dpdk/0197-net-hns3-fix-traffic-management.patch
speech_white c88e0aa74a Add bugfixes for hns3 PMD
Add bugfixes for hns3 PMD to sync upstream branch.

Signed-off-by: speech_white <humin29@huawei.com>
2021-07-28 10:35:46 +08:00

312 lines
10 KiB
Diff

From 78db1dbe9adf7ed0fedd6331dcd3a2c1ee0b85c4 Mon Sep 17 00:00:00 2001
From: Huisong Li <lihuisong@huawei.com>
Date: Mon, 21 Jun 2021 15:38:45 +0800
Subject: [PATCH 09/26] net/hns3: fix traffic management
In a multi-TC scenario, if the length of packets destined for different
TCs is different, for example, 64B and 1500B packets destined for TC0 and
TC1 respectively. There is a problem that the bandwidth of the TC to which
large packets are sent is preempted by the TC to which small packets are
sent on the Kunpeng 920 network engine. As a result, the TC bandwidth
accuracy is inaccurate.
To solve this problem, this patch made the following adjustments:
1/ During initialization, firmware reports the capability bit indicating
whether the TM function is supported.
2/ The command word for configuring TC and port rate limiting is added,
instead of reusing the existing command word. And firmware configured
to the correct module.
3/ When the PF driver is loaded, firmware completes the default
initialization of the TC and port.
Fixes: c09c7847d892 ("net/hns3: support traffic management")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
drivers/net/hns3/hns3_cmd.c | 5 ++-
drivers/net/hns3/hns3_cmd.h | 4 +++
drivers/net/hns3/hns3_dcb.c | 4 +--
drivers/net/hns3/hns3_dcb.h | 2 --
drivers/net/hns3/hns3_ethdev.h | 4 +++
drivers/net/hns3/hns3_tm.c | 69 +++++++++++++++++++++++++++++-------------
drivers/net/hns3/hns3_tm.h | 12 ++++++++
7 files changed, 74 insertions(+), 26 deletions(-)
diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c
index 5f4d74d..ab92240 100644
--- a/drivers/net/hns3/hns3_cmd.c
+++ b/drivers/net/hns3/hns3_cmd.c
@@ -431,7 +431,8 @@ hns3_get_caps_name(uint32_t caps_id)
{ HNS3_CAPS_STASH_B, "stash" },
{ HNS3_CAPS_UDP_TUNNEL_CSUM_B, "udp_tunnel_csum" },
{ HNS3_CAPS_RAS_IMP_B, "ras_imp" },
- { HNS3_CAPS_RXD_ADV_LAYOUT_B, "rxd_adv_layout" }
+ { HNS3_CAPS_RXD_ADV_LAYOUT_B, "rxd_adv_layout" },
+ { HNS3_CAPS_TM_B, "tm_capability" }
};
uint32_t i;
@@ -507,6 +508,8 @@ hns3_parse_capability(struct hns3_hw *hw,
HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, 1);
if (hns3_get_bit(caps, HNS3_CAPS_RAS_IMP_B))
hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_RAS_IMP_B, 1);
+ if (hns3_get_bit(caps, HNS3_CAPS_TM_B))
+ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TM_B, 1);
}
static uint32_t
diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index a249a7a..cd58303 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -162,6 +162,9 @@ enum hns3_opcode_type {
HNS3_OPC_TM_INTERNAL_CNT = 0x0851,
HNS3_OPC_TM_INTERNAL_STS_1 = 0x0852,
+ HNS3_OPC_TM_PORT_LIMIT_RATE = 0x0870,
+ HNS3_OPC_TM_TC_LIMIT_RATE = 0x0871,
+
/* Mailbox cmd */
HNS3_OPC_MBX_VF_TO_PF = 0x2001,
@@ -319,6 +322,7 @@ enum HNS3_CAPS_BITS {
HNS3_CAPS_UDP_TUNNEL_CSUM_B,
HNS3_CAPS_RAS_IMP_B,
HNS3_CAPS_RXD_ADV_LAYOUT_B = 15,
+ HNS3_CAPS_TM_B = 17,
};
enum HNS3_API_CAP_BITS {
diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c
index 8778452..61a2404 100644
--- a/drivers/net/hns3/hns3_dcb.c
+++ b/drivers/net/hns3/hns3_dcb.c
@@ -415,7 +415,7 @@ hns3_dcb_pg_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket,
return hns3_cmd_send(hw, &desc, 1);
}
-int
+static int
hns3_pg_shaper_rate_cfg(struct hns3_hw *hw, uint8_t pg_id, uint32_t rate)
{
struct hns3_shaper_parameter shaper_parameter;
@@ -551,7 +551,7 @@ hns3_dcb_pri_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket,
return hns3_cmd_send(hw, &desc, 1);
}
-int
+static int
hns3_pri_shaper_rate_cfg(struct hns3_hw *hw, uint8_t tc_no, uint32_t rate)
{
struct hns3_shaper_parameter shaper_parameter;
diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h
index 279f163..1abe649 100644
--- a/drivers/net/hns3/hns3_dcb.h
+++ b/drivers/net/hns3/hns3_dcb.h
@@ -209,8 +209,6 @@ int hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q,
int hns3_update_queue_map_configure(struct hns3_adapter *hns);
int hns3_port_shaper_update(struct hns3_hw *hw, uint32_t speed);
-int hns3_pg_shaper_rate_cfg(struct hns3_hw *hw, uint8_t pg_id, uint32_t rate);
-int hns3_pri_shaper_rate_cfg(struct hns3_hw *hw, uint8_t tc_no, uint32_t rate);
uint8_t hns3_txq_mapped_tc_get(struct hns3_hw *hw, uint16_t txq_no);
#endif /* _HNS3_DCB_H_ */
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index f3bc60e..31379fd 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -868,6 +868,7 @@ enum {
HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B,
HNS3_DEV_SUPPORT_RAS_IMP_B,
+ HNS3_DEV_SUPPORT_TM_B,
};
#define hns3_dev_dcb_supported(hw) \
@@ -904,6 +905,9 @@ enum {
#define hns3_dev_tx_push_supported(hw) \
hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_TX_PUSH_B)
+#define hns3_dev_tm_supported(hw) \
+ hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_TM_B)
+
#define HNS3_DEV_PRIVATE_TO_HW(adapter) \
(&((struct hns3_adapter *)adapter)->hw)
#define HNS3_DEV_PRIVATE_TO_PF(adapter) \
diff --git a/drivers/net/hns3/hns3_tm.c b/drivers/net/hns3/hns3_tm.c
index f7bfc25..81c61ad 100644
--- a/drivers/net/hns3/hns3_tm.c
+++ b/drivers/net/hns3/hns3_tm.c
@@ -28,8 +28,12 @@ void
hns3_tm_conf_init(struct rte_eth_dev *dev)
{
struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t max_tx_queues = hns3_tm_max_tx_queues_get(dev);
+ if (!hns3_dev_tm_supported(hw))
+ return;
+
pf->tm_conf.nb_leaf_nodes_max = max_tx_queues;
pf->tm_conf.nb_nodes_max = 1 + HNS3_MAX_TC_NUM + max_tx_queues;
pf->tm_conf.nb_shaper_profile_max = 1 + HNS3_MAX_TC_NUM;
@@ -50,9 +54,13 @@ void
hns3_tm_conf_uninit(struct rte_eth_dev *dev)
{
struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct hns3_tm_shaper_profile *shaper_profile;
struct hns3_tm_node *tm_node;
+ if (!hns3_dev_tm_supported(hw))
+ return;
+
if (pf->tm_conf.nb_queue_node > 0) {
while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) {
TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node);
@@ -912,40 +920,39 @@ static int
hns3_tm_config_port_rate(struct hns3_hw *hw,
struct hns3_tm_shaper_profile *shaper_profile)
{
+ struct hns3_port_limit_rate_cmd *cfg;
+ struct hns3_cmd_desc desc;
uint32_t firmware_rate;
uint64_t rate;
+ int ret;
if (shaper_profile) {
rate = shaper_profile->profile.peak.rate;
firmware_rate = hns3_tm_rate_convert_tm2firmware(rate);
} else {
- firmware_rate = hw->dcb_info.pg_info[0].bw_limit;
+ firmware_rate = hw->max_tm_rate;
}
- /*
- * The TM shaper topology after device inited:
- * pri0 shaper --->|
- * pri1 shaper --->|
- * ... |----> pg0 shaper ----> port shaper
- * ... |
- * priX shaper --->|
- *
- * Because port shaper rate maybe changed by firmware, to avoid
- * concurrent configure, driver use pg0 shaper to achieve the rate limit
- * of port.
- *
- * The finally port rate = MIN(pg0 shaper rate, port shaper rate)
- */
- return hns3_pg_shaper_rate_cfg(hw, 0, firmware_rate);
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_TM_PORT_LIMIT_RATE, false);
+ cfg = (struct hns3_port_limit_rate_cmd *)desc.data;
+ cfg->speed = rte_cpu_to_le_32(firmware_rate);
+
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret)
+ hns3_err(hw, "failed to config port rate, ret = %d", ret);
+
+ return ret;
}
static int
-hns3_tm_config_tc_rate(struct hns3_hw *hw,
- uint8_t tc_no,
+hns3_tm_config_tc_rate(struct hns3_hw *hw, uint8_t tc_no,
struct hns3_tm_shaper_profile *shaper_profile)
{
+ struct hns3_tc_limit_rate_cmd *cfg;
+ struct hns3_cmd_desc desc;
uint32_t firmware_rate;
uint64_t rate;
+ int ret;
if (shaper_profile) {
rate = shaper_profile->profile.peak.rate;
@@ -954,7 +961,17 @@ hns3_tm_config_tc_rate(struct hns3_hw *hw,
firmware_rate = hw->dcb_info.tc_info[tc_no].bw_limit;
}
- return hns3_pri_shaper_rate_cfg(hw, tc_no, firmware_rate);
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_TM_TC_LIMIT_RATE, false);
+ cfg = (struct hns3_tc_limit_rate_cmd *)desc.data;
+ cfg->speed = rte_cpu_to_le_32(firmware_rate);
+ cfg->tc_id = tc_no;
+
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret)
+ hns3_err(hw, "failed to config tc (%u) rate, ret = %d",
+ tc_no, ret);
+
+ return ret;
}
static bool
@@ -1227,12 +1244,16 @@ static const struct rte_tm_ops hns3_tm_ops = {
};
int
-hns3_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
- void *arg)
+hns3_tm_ops_get(struct rte_eth_dev *dev, void *arg)
{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
if (arg == NULL)
return -EINVAL;
+ if (!hns3_dev_tm_supported(hw))
+ return -EOPNOTSUPP;
+
*(const void **)arg = &hns3_tm_ops;
return 0;
@@ -1243,6 +1264,9 @@ hns3_tm_dev_start_proc(struct hns3_hw *hw)
{
struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw);
+ if (!hns3_dev_tm_supported(hw))
+ return;
+
if (pf->tm_conf.root && !pf->tm_conf.committed)
hns3_warn(hw,
"please call hierarchy_commit() before starting the port.");
@@ -1289,6 +1313,9 @@ hns3_tm_conf_update(struct hns3_hw *hw)
struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw);
struct rte_tm_error error;
+ if (!hns3_dev_tm_supported(hw))
+ return 0;
+
if (pf->tm_conf.root == NULL || !pf->tm_conf.committed)
return 0;
diff --git a/drivers/net/hns3/hns3_tm.h b/drivers/net/hns3/hns3_tm.h
index d8de3e4..2286d0e 100644
--- a/drivers/net/hns3/hns3_tm.h
+++ b/drivers/net/hns3/hns3_tm.h
@@ -9,6 +9,18 @@
#include <rte_tailq.h>
#include <rte_tm_driver.h>
+struct hns3_port_limit_rate_cmd {
+ uint32_t speed; /* Unit Mbps */
+ uint32_t rsvd[5];
+};
+
+struct hns3_tc_limit_rate_cmd {
+ uint32_t speed; /* Unit Mbps */
+ uint8_t tc_id;
+ uint8_t rsvd[3];
+ uint32_t rsvd1[4];
+};
+
enum hns3_tm_node_type {
HNS3_TM_NODE_TYPE_PORT,
HNS3_TM_NODE_TYPE_TC,
--
2.7.4