[PATCH 20.11] net/hns3: fix LRO offload to report

Huisong Li lihuisong at huawei.com
Wed Nov 15 11:05:39 CET 2023


[upstream commit a4b2c6815abd3e39daca2e2c93334b813e6a0be4]

Some network engines, like part of HIP09, may not support LRO
offload, but this offload capability is also reported to user.
So this patch determines whether driver reports this capability
based on the capabilities from firmware.

In addition, some network engines, like HIP08, always support LRO
offload and their firmware don't report this capability. So this
patch has to move getting revision ID codes to earlier stage and set
default capabilities for these network engines based on revision ID.

Fixes: ab2e2e344163 ("net/hns3: get device capability in primary process")
Fixes: f5ed7d99cf45 ("net/hns3: extract common function to obtain revision ID")

Signed-off-by: Huisong Li <lihuisong at huawei.com>
Signed-off-by: Jie Hai <haijie1 at huawei.com>
---
 drivers/net/hns3/hns3_cmd.c       | 18 +++++++++--
 drivers/net/hns3/hns3_cmd.h       |  1 +
 drivers/net/hns3/hns3_ethdev.c    | 50 +++++++++++++++++++------------
 drivers/net/hns3/hns3_ethdev.h    |  5 ++++
 drivers/net/hns3/hns3_ethdev_vf.c | 28 ++++++-----------
 drivers/net/hns3/hns3_rxtx.c      |  3 ++
 6 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c
index 2a67c264c6..eb9590eb17 100644
--- a/drivers/net/hns3/hns3_cmd.c
+++ b/drivers/net/hns3/hns3_cmd.c
@@ -436,6 +436,8 @@ static void hns3_parse_capability(struct hns3_hw *hw,
 		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B, 1);
 	if (hns3_get_bit(caps, HNS3_CAPS_STASH_B))
 		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_STASH_B, 1);
+	if (hns3_get_bit(caps, HNS3_CAPS_GRO_B))
+		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_GRO_B, 1);
 }
 
 static uint32_t
@@ -470,6 +472,19 @@ hns3_set_dcb_capability(struct hns3_hw *hw)
 		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1);
 }
 
+static void
+hns3_set_default_capability(struct hns3_hw *hw)
+{
+	hns3_set_dcb_capability(hw);
+
+	/*
+	 * The firmware of the network engines with HIP08 do not report some
+	 * capabilities, like GRO. Set default capabilities for it.
+	 */
+	if (hw->revision < PCI_REVISION_ID_HIP09_A)
+		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_GRO_B, 1);
+}
+
 static int
 hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw)
 {
@@ -488,8 +503,7 @@ hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw)
 
 	hw->fw_version = rte_le_to_cpu_32(resp->firmware);
 
-	hns3_set_dcb_capability(hw);
-
+	hns3_set_default_capability(hw);
 	hns3_parse_capability(hw, resp);
 
 	return 0;
diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index c5e7fc1064..9eea622972 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -290,6 +290,7 @@ enum HNS3_CAPS_BITS {
 	HNS3_CAPS_TQP_TXRX_INDEP_B,
 	HNS3_CAPS_HW_PAD_B,
 	HNS3_CAPS_STASH_B,
+	HNS3_CAPS_GRO_B = 20,
 };
 
 enum HNS3_API_CAP_BITS {
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 454f73ac77..cc18384446 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2581,8 +2581,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_RX_OFFLOAD_VLAN_STRIP |
 				 DEV_RX_OFFLOAD_VLAN_FILTER |
 				 DEV_RX_OFFLOAD_JUMBO_FRAME |
-				 DEV_RX_OFFLOAD_RSS_HASH |
-				 DEV_RX_OFFLOAD_TCP_LRO);
+				 DEV_RX_OFFLOAD_RSS_HASH);
 	info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
 				 DEV_TX_OFFLOAD_IPV4_CKSUM |
 				 DEV_TX_OFFLOAD_TCP_CKSUM |
@@ -2600,6 +2599,9 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
 				 RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
 
+	if (hns3_dev_gro_supported(hw))
+		info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
+
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
@@ -3032,6 +3034,28 @@ hns3_parse_speed(int speed_cmd, uint32_t *speed)
 	return 0;
 }
 
+int
+hns3_get_pci_revision_id(struct hns3_hw *hw, uint8_t *revision_id)
+{
+	struct rte_pci_device *pci_dev;
+	struct rte_eth_dev *eth_dev;
+	uint8_t revision;
+	int ret;
+
+	eth_dev = &rte_eth_devices[hw->data->port_id];
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN,
+				  HNS3_PCI_REVISION_ID);
+	if (ret != HNS3_PCI_REVISION_ID_LEN) {
+		hns3_err(hw, "failed to read pci revision id, ret = %d", ret);
+		return -EIO;
+	}
+
+	*revision_id = revision;
+
+	return 0;
+}
+
 static void
 hns3_set_default_dev_specifications(struct hns3_hw *hw)
 {
@@ -3109,30 +3133,14 @@ static int
 hns3_get_capability(struct hns3_hw *hw)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	struct rte_pci_device *pci_dev;
 	struct hns3_pf *pf = &hns->pf;
-	struct rte_eth_dev *eth_dev;
-	uint8_t revision;
 	int ret;
 
-	eth_dev = &rte_eth_devices[hw->data->port_id];
-	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
-
-	/* Get PCI revision id */
-	ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN,
-				  HNS3_PCI_REVISION_ID);
-	if (ret != HNS3_PCI_REVISION_ID_LEN) {
-		PMD_INIT_LOG(ERR, "failed to read pci revision id, ret = %d",
-			     ret);
-		return -EIO;
-	}
-	hw->revision = revision;
-
 	ret = hns3_query_mac_stats_reg_num(hw);
 	if (ret)
 		return ret;
 
-	if (revision < PCI_REVISION_ID_HIP09_A) {
+	if (hw->revision < PCI_REVISION_ID_HIP09_A) {
 		hns3_set_default_dev_specifications(hw);
 		hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE;
 		hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
@@ -4786,6 +4794,10 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 	/* Get hardware io base address from pcie BAR2 IO space */
 	hw->io_base = pci_dev->mem_resource[2].addr;
 
+	ret = hns3_get_pci_revision_id(hw, &hw->revision);
+	if (ret)
+		return ret;
+
 	/* Firmware command queue initialize */
 	ret = hns3_cmd_init_queue(hw);
 	if (ret) {
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 00571fa457..ce022f2096 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -778,6 +778,7 @@ struct hns3_adapter {
 #define HNS3_DEV_SUPPORT_TX_PUSH_B		0x5
 #define HNS3_DEV_SUPPORT_INDEP_TXRX_B		0x6
 #define HNS3_DEV_SUPPORT_STASH_B		0x7
+#define HNS3_DEV_SUPPORT_GRO_B			0x14
 
 #define hns3_dev_dcb_supported(hw) \
 	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B)
@@ -808,6 +809,9 @@ struct hns3_adapter {
 #define hns3_dev_stash_supported(hw) \
 	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_STASH_B)
 
+#define hns3_dev_gro_supported(hw) \
+	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_GRO_B)
+
 #define HNS3_DEV_PRIVATE_TO_HW(adapter) \
 	(&((struct hns3_adapter *)(adapter))->hw)
 #define HNS3_DEV_PRIVATE_TO_PF(adapter) \
@@ -939,6 +943,7 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
 bool hns3_is_reset_pending(struct hns3_adapter *hns);
 bool hns3vf_is_reset_pending(struct hns3_adapter *hns);
 void hns3_update_link_status(struct hns3_hw *hw);
+int hns3_get_pci_revision_id(struct hns3_hw *hw, uint8_t *revision_id);
 
 static inline bool
 is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 0b15b3bd2f..de9dbe5b26 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -982,8 +982,7 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_RX_OFFLOAD_VLAN_STRIP |
 				 DEV_RX_OFFLOAD_VLAN_FILTER |
 				 DEV_RX_OFFLOAD_JUMBO_FRAME |
-				 DEV_RX_OFFLOAD_RSS_HASH |
-				 DEV_RX_OFFLOAD_TCP_LRO);
+				 DEV_RX_OFFLOAD_RSS_HASH);
 	info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
 				 DEV_TX_OFFLOAD_IPV4_CKSUM |
 				 DEV_TX_OFFLOAD_TCP_CKSUM |
@@ -1001,6 +1000,9 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
 				 RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
 
+	if (hns3_dev_gro_supported(hw))
+		info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
+
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
@@ -1199,25 +1201,9 @@ hns3vf_query_dev_specifications(struct hns3_hw *hw)
 static int
 hns3vf_get_capability(struct hns3_hw *hw)
 {
-	struct rte_pci_device *pci_dev;
-	struct rte_eth_dev *eth_dev;
-	uint8_t revision;
 	int ret;
 
-	eth_dev = &rte_eth_devices[hw->data->port_id];
-	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
-
-	/* Get PCI revision id */
-	ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN,
-				  HNS3_PCI_REVISION_ID);
-	if (ret != HNS3_PCI_REVISION_ID_LEN) {
-		PMD_INIT_LOG(ERR, "failed to read pci revision id, ret = %d",
-			     ret);
-		return -EIO;
-	}
-	hw->revision = revision;
-
-	if (revision < PCI_REVISION_ID_HIP09_A) {
+	if (hw->revision < PCI_REVISION_ID_HIP09_A) {
 		hns3vf_set_default_dev_specifications(hw);
 		hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE;
 		hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
@@ -1775,6 +1761,10 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev)
 	/* Get hardware io base address from pcie BAR2 IO space */
 	hw->io_base = pci_dev->mem_resource[2].addr;
 
+	ret = hns3_get_pci_revision_id(hw, &hw->revision);
+	if (ret)
+		return ret;
+
 	/* Firmware command queue initialize */
 	ret = hns3_cmd_init_queue(hw);
 	if (ret) {
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 4f1354fb19..0136fdf0d2 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2794,6 +2794,9 @@ hns3_config_gro(struct hns3_hw *hw, bool en)
 	struct hns3_cmd_desc desc;
 	int ret;
 
+	if (!hns3_dev_gro_supported(hw))
+		return 0;
+
 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GRO_GENERIC_CONFIG, false);
 	req = (struct hns3_cfg_gro_status_cmd *)desc.data;
 
-- 
2.33.0



More information about the stable mailing list