Commit 66ef878c authored by Peiyang Wang's avatar Peiyang Wang Committed by Jiantao Xiao
Browse files

net: hns3: support tc limit rate

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


CVE: NA

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

Traffic class is supposed to support limit rate. Different tc will be
configured different rate. The followed tc command can be used.

tc qdisc add dev eth0 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 10gbps 1gbps
100mbps 10mbps

As showed the aboved command, the eth0 has 4 tcs and the limit rate are
80 Gbits/sec, 8 Gbits/sec, 800 Mbits/sec and 80 Mbits/sec respectively.

Signed-off-by: default avatarPeiyang Wang <wangpeiyang1@huawei.com>
parent 04595b55
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ enum hclge_opcode_type {
	HCLGE_OPC_TM_INTERNAL_STS	= 0x0850,
	HCLGE_OPC_TM_INTERNAL_CNT	= 0x0851,
	HCLGE_OPC_TM_INTERNAL_STS_1	= 0x0852,
	HCLGE_OPC_TM_TC_RATE_LIMIT_CFG	= 0x0871,
	HCLGE_OPC_TM_FLUSH		= 0x0872,

	/* Packet buffer allocate commands */
+9 −1
Original line number Diff line number Diff line
@@ -613,13 +613,21 @@ static void hclge_sync_mqprio_qopt(struct hnae3_tc_info *tc_info,
static int hclge_config_tc(struct hclge_dev *hdev,
			   struct hnae3_tc_info *tc_info)
{
	int ret;
	int i;

	hclge_tm_schd_info_update(hdev, tc_info->num_tc);
	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++)
		hdev->tm_info.prio_tc[i] = tc_info->prio_tc[i];

	return hclge_map_update(hdev);
	ret = hclge_map_update(hdev);
	if (ret)
		return ret;

	if (hnae3_dev_roh_supported(hdev))
		return hclge_tm_set_tc_rate_limit(hdev, tc_info);

	return 0;
}

/* Set up TC for hardware offloaded mqprio in channel mode */
+47 −0
Original line number Diff line number Diff line
@@ -1668,6 +1668,49 @@ void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
	hclge_tm_schd_info_init(hdev);
}

static int hclge_tc_rate_limit_cfg(struct hclge_dev *hdev, u32 speed, u8 tc)
{
	struct hclge_tc_rate_limit_cmd *tc_rate_limit_cmd;
	struct hclge_desc desc;
	int ret;

	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_TC_RATE_LIMIT_CFG,
				   false);

	tc_rate_limit_cmd = (struct hclge_tc_rate_limit_cmd *)desc.data;
	tc_rate_limit_cmd->speed = cpu_to_le32(speed);
	tc_rate_limit_cmd->tc_id = tc;

	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		dev_err(&hdev->pdev->dev,
			"failed to config tc(%u) rate limit, ret = %d\n",
			tc, ret);

	return ret;
}

int hclge_tm_set_tc_rate_limit(struct hclge_dev *hdev,
			       struct hnae3_tc_info *tc_info)
{
	u32 speed;
	int ret;
	int i;

	for (i = 0; i < tc_info->num_tc; i++) {
		/* mac speed unit is Mbps, tc max_rate is Bps */
		speed = hclge_tm_rate_2_port_rate(tc_info->max_rate[i]);
		if (!speed)
			speed = hdev->hw.mac.max_speed;

		ret = hclge_tc_rate_limit_cfg(hdev, speed, i);
		if (ret)
			return ret;
	}

	return 0;
}

u32 hclge_tm_rate_2_port_rate(u64 rate)
{
	do_div(rate, TM_RATE_PORT_RATE_SCALE);
@@ -1676,6 +1719,7 @@ u32 hclge_tm_rate_2_port_rate(u64 rate)

int hclge_tm_init_hw(struct hclge_dev *hdev, bool init)
{
	struct hnae3_tc_info *tc_info = &hdev->vport[0].nic.kinfo.tc_info;
	int ret;

	if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
@@ -1690,6 +1734,9 @@ int hclge_tm_init_hw(struct hclge_dev *hdev, bool init)
	if (ret)
		return ret;

	if (hnae3_dev_roh_supported(hdev))
		return hclge_tm_set_tc_rate_limit(hdev, tc_info);

	return 0;
}

+8 −0
Original line number Diff line number Diff line
@@ -214,6 +214,12 @@ struct hclge_tm_nodes_cmd {
	__le16 queue_num;
};

struct hclge_tc_rate_limit_cmd {
	__le32 speed;	/* Unit Mbps */
	u8 tc_id;
	u8 rsvd[19];
};

struct hclge_tm_shaper_para {
	u32 rate;
	u8 ir_b;
@@ -279,5 +285,7 @@ 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);
int hclge_tm_set_tc_rate_limit(struct hclge_dev *hdev,
			       struct hnae3_tc_info *tc_info);
u32 hclge_tm_rate_2_port_rate(u64 rate);
#endif