Commit 04595b55 authored by Peiyang Wang's avatar Peiyang Wang Committed by Jiantao Xiao
Browse files

net: hns3: support tc command with max rate parameter

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I7YRUW


CVE: NA

----------------------------------------------------------------------

Traffic class is supposed to support limit rate. Configure different rates
for different tc. The followed tc command can be used.

tc qdisc add dev ethx root mqprio num_tc 4 map 0 1 2 3 0 1 2 3 queues 8@0
8@8 8@16 8@24 hw 1 mode channel shaper bw_rlimit max_rate 10mbps 10mbps
10mbps 10mbps

Signed-off-by: default avatarPeiyang Wang <wangpeiyang1@huawei.com>
parent 0b7ebb1c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@
#define HNAE3_DEV_SUPPORT_ROCE_DCB_BITS (BIT(HNAE3_DEV_SUPPORT_DCB_B) | \
		BIT(HNAE3_DEV_SUPPORT_ROCE_B))

#define hnae3_dev_roh_supported(hdev) \
	hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_ROH_CLIENT_INITED_B)

#define hnae3_dev_roce_supported(hdev) \
	hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)

@@ -834,6 +837,7 @@ struct hnae3_tc_info {
	u8 num_tc; /* Total number of enabled TCs */
	bool mqprio_active;
	bool dcb_ets_active;
	u64 max_rate[HNAE3_MAX_TC];     /* Unit Bps */
};

#define HNAE3_MAX_DSCP			64
+37 −5
Original line number Diff line number Diff line
@@ -509,6 +509,36 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
	return 0;
}

static int hclge_mqprio_qopt_check_rate(struct hclge_dev *hdev, u64 min_rate,
					u64 max_rate)
{
	u32 max_speed = hclge_tm_rate_2_port_rate(max_rate);

	if (min_rate) {
		dev_err(&hdev->pdev->dev, "unsupported min_rate, min_rate = %lluB/s\n",
			min_rate);
		return -EOPNOTSUPP;
	}

	if (!max_rate)
		return 0;

	if (hnae3_dev_roh_supported(hdev)) {
		if (max_rate < TM_RATE_PORT_RATE_SCALE ||
		    max_speed > hdev->hw.mac.max_speed) {
			dev_err(&hdev->pdev->dev,
				"invalid max_rate[%lluB/s]: the range is [1Mbps, %uMbps]\n",
				max_rate, hdev->hw.mac.max_speed);
			return -EINVAL;
		}
		return 0;
	}

	dev_err(&hdev->pdev->dev, "unsupported max_rate, max_rate = %lluB/s\n",
		max_rate);
	return -EOPNOTSUPP;
}

static int hclge_mqprio_qopt_check(struct hclge_dev *hdev,
				   struct tc_mqprio_qopt_offload *mqprio_qopt)
{
@@ -546,11 +576,11 @@ static int hclge_mqprio_qopt_check(struct hclge_dev *hdev,
			return -EINVAL;
		}

		if (mqprio_qopt->min_rate[i] || mqprio_qopt->max_rate[i]) {
			dev_err(&hdev->pdev->dev,
				"qopt tx_rate is not supported\n");
			return -EOPNOTSUPP;
		}
		ret = hclge_mqprio_qopt_check_rate(hdev,
						   mqprio_qopt->min_rate[i],
						   mqprio_qopt->max_rate[i]);
		if (ret)
			return ret;

		queue_sum = mqprio_qopt->qopt.offset[i];
		queue_sum += mqprio_qopt->qopt.count[i];
@@ -576,6 +606,8 @@ static void hclge_sync_mqprio_qopt(struct hnae3_tc_info *tc_info,
	       sizeof_field(struct hnae3_tc_info, tqp_count));
	memcpy(tc_info->tqp_offset, mqprio_qopt->qopt.offset,
	       sizeof_field(struct hnae3_tc_info, tqp_offset));
	memcpy(tc_info->max_rate, mqprio_qopt->max_rate,
	       sizeof_field(struct hnae3_tc_info, max_rate));
}

static int hclge_config_tc(struct hclge_dev *hdev,
+2 −0
Original line number Diff line number Diff line
@@ -362,6 +362,8 @@ struct hclge_cfg {
	u16 umv_space;
};

#define TM_RATE_PORT_RATE_SCALE	125000

struct hclge_tm_info {
	u8 num_tc;
	u8 num_pg;      /* It must be 1 if vNET-Base schd */
+6 −0
Original line number Diff line number Diff line
@@ -1668,6 +1668,12 @@ void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
	hclge_tm_schd_info_init(hdev);
}

u32 hclge_tm_rate_2_port_rate(u64 rate)
{
	do_div(rate, TM_RATE_PORT_RATE_SCALE);
	return rate > U32_MAX ? U32_MAX : (u32)rate;
}

int hclge_tm_init_hw(struct hclge_dev *hdev, bool init)
{
	int ret;
+1 −0
Original line number Diff line number Diff line
@@ -279,4 +279,5 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev,
int hclge_up_to_tc_map(struct hclge_dev *hdev);
int hclge_dscp_to_tc_map(struct hclge_dev *hdev);
int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable);
u32 hclge_tm_rate_2_port_rate(u64 rate);
#endif