From: Peiyang Wang wangpeiyang1@huawei.com
driver inclusion category:feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9A3QT 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: Peiyang Wang wangpeiyang1@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 4 ++ .../hisilicon/hns3/hns3pf/hclge_dcb.c | 42 ++++++++++++++++--- .../hisilicon/hns3/hns3pf/hclge_main.h | 2 + .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 6 +++ .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 1 + 5 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 47c4f7a34836..d484d92ded6f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -71,6 +71,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)
@@ -853,6 +856,7 @@ struct hnae3_tc_info { bool mqprio_active; bool mqprio_destroy; bool dcb_ets_active; + u64 max_rate[HNAE3_MAX_TC]; /* Unit Bps */ };
#define HNAE3_MAX_DSCP 64 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index eabbacb1c714..1cfd7a32e6ab 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -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, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 14a95c9f7853..59662acd2b9b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -378,6 +378,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 */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index 6387120bee04..79a2472230fd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -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; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h index 49cc441f999d..896b3b9672eb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -279,5 +279,6 @@ 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); void hclge_reset_tc_config(struct hclge_dev *hdev); #endif