patches for DPDK stable branches
 help / color / mirror / Atom feed
* [dpdk-stable] [PATCH 00/24] backport for 19.11.4
@ 2020-08-17  9:25 Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 01/24] net/hns3: get link status change through mailbox Wei Hu (Xavier)
                   ` (26 more replies)
  0 siblings, 27 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

This series are backport for 19.11.4 about hns3 PMD driver, bonding
and testpmd.

Chengchang Tang (6):
  net/hns3: remove restriction on setting VF MTU
  net/hns3: support promiscuous and allmulticast mode for VF
  net/hns3: fix adding multicast MAC address
  net/hns3: decrease non-nearby memory access in Rx
  net/hns3: support setting VF PVID by PF driver
  net/hns3: cleanup duplicated code on processing TSO in Tx

Chengwen Feng (1):
  net/hns3: get Rx/Tx queue fbd in xstats

Hao Chen (1):
  net/hns3: optimize default RSS algorithm

Hongbo Zheng (3):
  net/hns3: get link status change through mailbox
  net/hns3: support TSO
  net/hns3: check TSO segment size during Tx

Lijun Ou (4):
  net/hns3: remove unnecessary branch
  net/hns3: support symmetric RSS
  net/hns3: report Tx descriptor segment limitations
  app/testpmd: remove hardcoded descriptors limit

Wei Hu (Xavier) (8):
  net/hns3: support setting VF MAC address by PF driver
  net/hns3: get Tx abnormal errors in xstats
  net/hns3: get PCI revision ID
  net/hns3: support LRO
  net/hns3: get device capability in primary process
  net/hns3: support copper media type
  net/hns3: fix reassembling multiple segment packets in Tx
  net/hns3: fix inserted VLAN tag position in Tx

Weifeng Li (1):
  net/bonding: change state machine to defaulted

 app/test-pmd/cmdline.c                        |  11 +-
 app/test-pmd/testpmd.c                        | 171 ++++++
 app/test-pmd/testpmd.h                        |   2 +
 doc/guides/nics/features/hns3.ini             |   2 +
 doc/guides/nics/features/hns3_vf.ini          |   4 +
 doc/guides/nics/hns3.rst                      |   2 +
 drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
 drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
 drivers/net/hns3/hns3_ethdev.c                | 269 ++++++--
 drivers/net/hns3/hns3_ethdev.h                |  34 +-
 drivers/net/hns3/hns3_ethdev_vf.c             | 578 +++++++++++++++---
 drivers/net/hns3/hns3_flow.c                  |  12 +-
 drivers/net/hns3/hns3_mbx.c                   |  93 +++
 drivers/net/hns3/hns3_mbx.h                   |  13 +
 drivers/net/hns3/hns3_rss.c                   |  35 +-
 drivers/net/hns3/hns3_rss.h                   |   6 +-
 drivers/net/hns3/hns3_rxtx.c                  | 525 ++++++++++++++--
 drivers/net/hns3/hns3_rxtx.h                  |  65 +-
 drivers/net/hns3/hns3_stats.c                 | 243 +++++---
 drivers/net/hns3/hns3_stats.h                 |   3 +-
 20 files changed, 1779 insertions(+), 313 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 01/24] net/hns3: get link status change through mailbox
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 02/24] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Hongbo Zheng <zhenghongbo3@huawei.com>

[ upstream commit 109e4dd1bd7a5f7e0400be974f2b9e18d10cb3a6 ]

Currently, firmware adds the function of sending message to PF driver
through mailbox when the link status is changed, hns3 PMD driver can
usually recognize link state change faster through the message.

And in some extreme cases, this way is not faster than existing method
regularly updating link status by issuing the command every second in PF
driver, because of the parallel processing of mailbox and command
messages in firmware. So we reserve updating link status using timers in
PF driver, and add querying link status by issuing command to the
firmware in '.link_update' ops implementation function named
hns3_dev_link_update to solve the out of date link status.

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 14 +++++++++++--
 drivers/net/hns3/hns3_ethdev.h |  1 +
 drivers/net/hns3/hns3_mbx.c    | 37 ++++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_mbx.h    |  8 ++++++++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 971f2f900..c31a9328a 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -75,6 +75,7 @@ static enum hns3_reset_level hns3_get_reset_level(struct hns3_adapter *hns,
 static int hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
+static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
@@ -216,6 +217,8 @@ hns3_interrupt_handler(void *param)
 		hns3_schedule_reset(hns);
 	} else if (event_cause == HNS3_VECTOR0_EVENT_RST)
 		hns3_schedule_reset(hns);
+	else if (event_cause == HNS3_VECTOR0_EVENT_MBX)
+		hns3_dev_handle_mbx_msg(hw);
 	else
 		hns3_err(hw, "Received unknown event");
 
@@ -2441,6 +2444,11 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev,
 	struct hns3_mac *mac = &hw->mac;
 	struct rte_eth_link new_link;
 
+	if (!hns3_is_reset_pending(hns)) {
+		hns3_update_speed_duplex(eth_dev);
+		hns3_update_link_status(hw);
+	}
+
 	memset(&new_link, 0, sizeof(new_link));
 	switch (mac->link_speed) {
 	case ETH_SPEED_NUM_10M:
@@ -4067,14 +4075,16 @@ hns3_get_mac_link_status(struct hns3_hw *hw)
 	return !!link_status;
 }
 
-static void
+void
 hns3_update_link_status(struct hns3_hw *hw)
 {
 	int state;
 
 	state = hns3_get_mac_link_status(hw);
-	if (state != hw->mac.link_status)
+	if (state != hw->mac.link_status) {
 		hw->mac.link_status = state;
+		hns3_warn(hw, "Link status change to %s!", state ? "up" : "down");
+	}
 }
 
 static void
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 155099e99..35e64aa5a 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -648,6 +648,7 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
 			 enum rte_filter_op filter_op, void *arg);
 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);
 
 static inline bool
 is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c
index 7b5ef9476..64996c9ae 100644
--- a/drivers/net/hns3/hns3_mbx.c
+++ b/drivers/net/hns3/hns3_mbx.c
@@ -292,6 +292,40 @@ hns3_update_resp_position(struct hns3_hw *hw, uint32_t resp_msg)
 	resp->tail = tail;
 }
 
+static void
+hns3_link_fail_parse(struct hns3_hw *hw, uint8_t link_fail_code)
+{
+	switch (link_fail_code) {
+	case HNS3_MBX_LF_NORMAL:
+		break;
+	case HNS3_MBX_LF_REF_CLOCK_LOST:
+		hns3_warn(hw, "Reference clock lost!");
+		break;
+	case HNS3_MBX_LF_XSFP_TX_DISABLE:
+		hns3_warn(hw, "SFP tx is disabled!");
+		break;
+	case HNS3_MBX_LF_XSFP_ABSENT:
+		hns3_warn(hw, "SFP is absent!");
+		break;
+	default:
+		hns3_warn(hw, "Unknown fail code:%u!", link_fail_code);
+		break;
+	}
+}
+
+static void
+hns3_handle_link_change_event(struct hns3_hw *hw,
+			      struct hns3_mbx_pf_to_vf_cmd *req)
+{
+#define LINK_STATUS_OFFSET     1
+#define LINK_FAIL_CODE_OFFSET  2
+
+	if (!req->msg[LINK_STATUS_OFFSET])
+		hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]);
+
+	hns3_update_link_status(hw);
+}
+
 void
 hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 {
@@ -347,6 +381,9 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 
 			hns3_mbx_handler(hw);
 			break;
+		case HNS3_MBX_PUSH_LINK_STATUS:
+			hns3_handle_link_change_event(hw, req);
+			break;
 		default:
 			hns3_err(hw,
 				 "VF received unsupported(%d) mbx msg from PF",
diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h
index 7bcfbbebc..b01eaacc3 100644
--- a/drivers/net/hns3/hns3_mbx.h
+++ b/drivers/net/hns3/hns3_mbx.h
@@ -42,6 +42,7 @@ enum HNS3_MBX_OPCODE {
 
 	HNS3_MBX_HANDLE_VF_TBL = 38,    /* (VF -> PF) store/clear hw cfg tbl */
 	HNS3_MBX_GET_RING_VECTOR_MAP,   /* (VF -> PF) get ring-to-vector map */
+	HNS3_MBX_PUSH_LINK_STATUS = 201, /* (IMP -> PF) get port link status */
 };
 
 /* below are per-VF mac-vlan subcodes */
@@ -65,6 +66,13 @@ enum hns3_mbx_tbl_cfg_subcode {
 	HNS3_MBX_VPORT_LIST_CLEAR = 0,
 };
 
+enum hns3_mbx_link_fail_subcode {
+	HNS3_MBX_LF_NORMAL = 0,
+	HNS3_MBX_LF_REF_CLOCK_LOST,
+	HNS3_MBX_LF_XSFP_TX_DISABLE,
+	HNS3_MBX_LF_XSFP_ABSENT,
+};
+
 #define HNS3_MBX_MAX_MSG_SIZE	16
 #define HNS3_MBX_MAX_RESP_DATA_SIZE	8
 #define HNS3_MBX_RING_MAP_BASIC_MSG_NUM	3
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 02/24] net/hns3: optimize default RSS algorithm
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 01/24] net/hns3: get link status change through mailbox Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 03/24] net/hns3: support setting VF MAC address by PF driver Wei Hu (Xavier)
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Hao Chen <chenhao164@huawei.com>

[ upstream commit 8834849a9518db9cc79f5585ce15c4630ff0c0c9 ]

This patch changed the default algorithm of RSS from simle_xor to
toeplitz because toeplitz is used more frequently by upper applications
such as ceph.

Signed-off-by: Hao Chen <chenhao164@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_rss.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index f19b79928..a6cab29c9 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -211,7 +211,11 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw,
 			req->ipv6_fragment_en |= HNS3_IP_OTHER_BIT_MASK;
 			break;
 		default:
-			/* Other unsupported flow types won't change tuples */
+			/*
+			 * rss_hf doesn't include unsupported flow types
+			 * because the API framework has checked it, and
+			 * this branch will never go unless rss_hf is zero.
+			 */
 			break;
 		}
 	}
@@ -251,8 +255,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 	struct hns3_hw *hw = &hns->hw;
 	struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets;
 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
-	uint8_t algo = rss_cfg->conf.func;
 	uint8_t key_len = rss_conf->rss_key_len;
+	uint8_t algo;
 	uint64_t rss_hf = rss_conf->rss_hf;
 	uint8_t *key = rss_conf->rss_key;
 	int ret;
@@ -288,6 +292,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 			ret = -EINVAL;
 			goto conf_err;
 		}
+		algo = rss_cfg->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR ?
+			HNS3_RSS_HASH_ALGO_SIMPLE : HNS3_RSS_HASH_ALGO_TOEPLITZ;
 		ret = hns3_set_rss_algo_key(hw, algo, key);
 		if (ret)
 			goto conf_err;
@@ -505,7 +511,9 @@ hns3_set_default_rss_args(struct hns3_hw *hw)
 	int i;
 
 	/* Default hash algorithm */
-	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+
+	/* Default RSS key */
 	memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE);
 
 	/* Initialize RSS indirection table */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 03/24] net/hns3: support setting VF MAC address by PF driver
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 01/24] net/hns3: get link status change through mailbox Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 02/24] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 04/24] net/hns3: remove unnecessary branch Wei Hu (Xavier)
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit eab21776717ec6cee13535c9efad724f2ae56aa6 ]

Currently, we only support VF device is bound to vfio_pci or igb_uio and
then driven by DPDK driver when PF is driven by kernel mode hns3 ethdev
driver, VF is not supported when PF is driven by hns3 DPDK driver.

This patch adds support setting VF MAC address by hns3 PF kernel ethdev
driver on the host by "ip link set ..." command.
1) If the hns3 PF kernel ethdev driver sets the MAC address for VF
   device before the initialization of the related VF device, hns3 VF
   PMD driver should get the MAC address from PF driver through mailbox
   and configure hardware using this MAC address in the initialization.
   The hns3 VF PMD driver get the MAC address form PF driver, if
   obtaining a non-zero MAC address from mailbox, VF driver will
   configure hardware using it, otherwise using a random MAC address in
   the initialization of VF device.
2) If the hns3 PF kernel ethdev driver sets the MAC address for VF
   device after the initialization of the related VF device, the PF
   driver will notify VF driver to reset VF device to make the new MAC
   address effective immediately. The hns3 VF PMD driver should check
   whether the MAC address has been changed by the PF kernel netdevice
   driver, if changed VF driver should configure hardware using the new
   MAC address in the recovering hardware configuration stage of the
   reset process.
3) When user has configured a mac address for VF device by "ip link set
   ..." command based on the PF device, the hns3 PF kernel ethdev driver
   does not allow VF driver to request reconfiguring a different default
   mac address and return -EPREM to VF driver through mailbox.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
---
 drivers/net/hns3/hns3_ethdev_vf.c | 108 ++++++++++++++++++++++++++++--
 1 file changed, 102 insertions(+), 6 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 5e5da8685..1e358d839 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -208,12 +208,27 @@ hns3vf_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
 				HNS3_MBX_MAC_VLAN_UC_MODIFY, addr_bytes,
-				HNS3_TWO_ETHER_ADDR_LEN, false, NULL, 0);
+				HNS3_TWO_ETHER_ADDR_LEN, true, NULL, 0);
 	if (ret) {
-		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-				      mac_addr);
-		hns3_err(hw, "Failed to set mac addr(%s) for vf: %d", mac_str,
-			 ret);
+		/*
+		 * The hns3 VF PMD driver depends on the hns3 PF kernel ethdev
+		 * driver. When user has configured a MAC address for VF device
+		 * by "ip link set ..." command based on the PF device, the hns3
+		 * PF kernel ethdev driver does not allow VF driver to request
+		 * reconfiguring a different default MAC address, and return
+		 * -EPREM to VF driver through mailbox.
+		 */
+		if (ret == -EPERM) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      old_addr);
+			hns3_warn(hw, "Has permanet mac addr(%s) for vf",
+				  mac_str);
+		} else {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      mac_addr);
+			hns3_err(hw, "Failed to set mac addr(%s) for vf: %d",
+				 mac_str, ret);
+		}
 	}
 
 	rte_ether_addr_copy(mac_addr,
@@ -881,6 +896,24 @@ hns3vf_get_tc_info(struct hns3_hw *hw)
 	return 0;
 }
 
+static int
+hns3vf_get_host_mac_addr(struct hns3_hw *hw)
+{
+	uint8_t host_mac[RTE_ETHER_ADDR_LEN];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_GET_MAC_ADDR, 0, NULL, 0,
+				true, host_mac, RTE_ETHER_ADDR_LEN);
+	if (ret) {
+		hns3_err(hw, "Failed to get mac addr from PF: %d", ret);
+		return ret;
+	}
+
+	memcpy(hw->mac.mac_addr, host_mac, RTE_ETHER_ADDR_LEN);
+
+	return 0;
+}
+
 static int
 hns3vf_get_configuration(struct hns3_hw *hw)
 {
@@ -899,6 +932,11 @@ hns3vf_get_configuration(struct hns3_hw *hw)
 	if (ret)
 		return ret;
 
+	/* Get user defined VF MAC addr from PF */
+	ret = hns3vf_get_host_mac_addr(hw);
+	if (ret)
+		return ret;
+
 	/* Get tc configuration from PF */
 	return hns3vf_get_tc_info(hw);
 }
@@ -1321,7 +1359,20 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev)
 		goto err_get_config;
 	}
 
-	rte_eth_random_addr(hw->mac.mac_addr); /* Generate a random mac addr */
+	/*
+	 * The hns3 PF ethdev driver in kernel support setting VF MAC address
+	 * on the host by "ip link set ..." command. To avoid some incorrect
+	 * scenes, for example, hns3 VF PMD driver fails to receive and send
+	 * packets after user configure the MAC address by using the
+	 * "ip link set ..." command, hns3 VF PMD driver keep the same MAC
+	 * address strategy as the hns3 kernel ethdev driver in the
+	 * initialization. If user configure a MAC address by the ip command
+	 * for VF device, then hns3 VF PMD driver will start with it, otherwise
+	 * start with a random MAC address in the initialization.
+	 */
+	ret = rte_is_zero_ether_addr((struct rte_ether_addr *)hw->mac.mac_addr);
+	if (ret)
+		rte_eth_random_addr(hw->mac.mac_addr);
 
 	ret = hns3vf_clear_vport_list(hw);
 	if (ret) {
@@ -1840,12 +1891,57 @@ hns3vf_start_service(struct hns3_adapter *hns)
 	return 0;
 }
 
+static int
+hns3vf_check_default_mac_change(struct hns3_hw *hw)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *hw_mac;
+	int ret;
+
+	/*
+	 * The hns3 PF ethdev driver in kernel support setting VF MAC address
+	 * on the host by "ip link set ..." command. If the hns3 PF kernel
+	 * ethdev driver sets the MAC address for VF device after the
+	 * initialization of the related VF device, the PF driver will notify
+	 * VF driver to reset VF device to make the new MAC address effective
+	 * immediately. The hns3 VF PMD driver should check whether the MAC
+	 * address has been changed by the PF kernel ethdev driver, if changed
+	 * VF driver should configure hardware using the new MAC address in the
+	 * recovering hardware configuration stage of the reset process.
+	 */
+	ret = hns3vf_get_host_mac_addr(hw);
+	if (ret)
+		return ret;
+
+	hw_mac = (struct rte_ether_addr *)hw->mac.mac_addr;
+	ret = rte_is_zero_ether_addr(hw_mac);
+	if (ret) {
+		rte_ether_addr_copy(&hw->data->mac_addrs[0], hw_mac);
+	} else {
+		ret = rte_is_same_ether_addr(&hw->data->mac_addrs[0], hw_mac);
+		if (!ret) {
+			rte_ether_addr_copy(hw_mac, &hw->data->mac_addrs[0]);
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      &hw->data->mac_addrs[0]);
+			hns3_warn(hw, "Default MAC address has been changed to:"
+				  " %s by the host PF kernel ethdev driver",
+				  mac_str);
+		}
+	}
+
+	return 0;
+}
+
 static int
 hns3vf_restore_conf(struct hns3_adapter *hns)
 {
 	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
+	ret = hns3vf_check_default_mac_change(hw);
+	if (ret)
+		return ret;
+
 	ret = hns3vf_configure_mac_addr(hns, false);
 	if (ret)
 		return ret;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 04/24] net/hns3: remove unnecessary branch
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (2 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 03/24] net/hns3: support setting VF MAC address by PF driver Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 05/24] net/hns3: support TSO Wei Hu (Xavier)
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit d13a7447a131a3a7078caf1d14e674e8add1d0a5 ]

Because the rte layer of DPDK framework has already processed the case
when the idx is zero before calling the '.mac_addr_remove' ops function,
the input parameter named idx can not be zero in the '.mac_addr_remove'
function. This patch removes unnecessary branch process to check whether
input parameter named idx is zero in the '.mac_addr_remove' ops
implementation function named hns3_remove_mac_addr.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index c31a9328a..128cd793d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -1531,8 +1531,6 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 		return;
 	}
 
-	if (idx == 0)
-		hw->mac.default_addr_setted = false;
 	rte_spinlock_unlock(&hw->lock);
 }
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 05/24] net/hns3: support TSO
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (3 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 04/24] net/hns3: remove unnecessary branch Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 06/24] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Hongbo Zheng <zhenghongbo3@huawei.com>

[ upstream commit 6dca716c9e1daa8ea770a4a198bd068e72a2e03c ]

This patch adds TCP segment offload support for hns3 PMD driver.

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 doc/guides/nics/features/hns3.ini    |   1 +
 doc/guides/nics/features/hns3_vf.ini |   1 +
 doc/guides/nics/hns3.rst             |   1 +
 drivers/net/hns3/hns3_ethdev.c       |   4 +
 drivers/net/hns3/hns3_ethdev.h       |   6 +-
 drivers/net/hns3/hns3_ethdev_vf.c    |   4 +
 drivers/net/hns3/hns3_rxtx.c         | 258 +++++++++++++++++++++++++--
 7 files changed, 259 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini
index cd5c08a9d..c3a8544bc 100644
--- a/doc/guides/nics/features/hns3.ini
+++ b/doc/guides/nics/features/hns3.ini
@@ -8,6 +8,7 @@ Link status          = Y
 Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
+TSO                  = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini
index fd00ac3e2..e4e77380f 100644
--- a/doc/guides/nics/features/hns3_vf.ini
+++ b/doc/guides/nics/features/hns3_vf.ini
@@ -8,6 +8,7 @@ Link status          = Y
 Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
+TSO                  = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 8d19f4851..05dbe4174 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -17,6 +17,7 @@ Features of the HNS3 PMD are:
 - Receive Side Scaling (RSS)
 - Packet type information
 - Checksum offload
+- TSO offload
 - Promiscuous mode
 - Multicast mode
 - Port hardware statistics
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 128cd793d..39edd7e51 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2387,6 +2387,10 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_TX_OFFLOAD_VLAN_INSERT |
 				 DEV_TX_OFFLOAD_QINQ_INSERT |
 				 DEV_TX_OFFLOAD_MULTI_SEGS |
+				 DEV_TX_OFFLOAD_TCP_TSO |
+				 DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+				 DEV_TX_OFFLOAD_GRE_TNL_TSO |
+				 DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
 				 info->tx_queue_offload_capa);
 
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 35e64aa5a..df06ba3b0 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -31,11 +31,15 @@
 #define HNS3_MC_MACADDR_NUM		128
 
 #define HNS3_MAX_BD_SIZE		65535
-#define HNS3_MAX_TX_BD_PER_PKT		8
+#define HNS3_MAX_NON_TSO_BD_PER_PKT	8
+#define HNS3_MAX_TSO_BD_PER_PKT		63
 #define HNS3_MAX_FRAME_LEN		9728
 #define HNS3_MIN_FRAME_LEN		64
 #define HNS3_VLAN_TAG_SIZE		4
 #define HNS3_DEFAULT_RX_BUF_LEN		2048
+#define HNS3_MAX_BD_PAYLEN		(1024 * 1024 - 1)
+#define HNS3_MAX_TSO_HDR_SIZE		512
+#define HNS3_MAX_TSO_HDR_BD_NUM		3
 
 #define HNS3_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + HNS3_VLAN_TAG_SIZE * 2)
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 1e358d839..e6fc2ea88 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -692,6 +692,10 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_TX_OFFLOAD_VLAN_INSERT |
 				 DEV_TX_OFFLOAD_QINQ_INSERT |
 				 DEV_TX_OFFLOAD_MULTI_SEGS |
+				 DEV_TX_OFFLOAD_TCP_TSO |
+				 DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+				 DEV_TX_OFFLOAD_GRE_TNL_TSO |
+				 DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
 				 info->tx_queue_offload_capa);
 
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index c1ffa136b..734a11fdc 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1858,6 +1858,78 @@ hns3_tx_free_useless_buffer(struct hns3_tx_queue *txq)
 	txq->tx_bd_ready   = tx_bd_ready;
 }
 
+static int
+hns3_tso_proc_tunnel(struct hns3_desc *desc, uint64_t ol_flags,
+		     struct rte_mbuf *rxm, uint8_t *l2_len)
+{
+	uint64_t tun_flags;
+	uint8_t ol4_len;
+	uint32_t otmp;
+
+	tun_flags = ol_flags & PKT_TX_TUNNEL_MASK;
+	if (tun_flags == 0)
+		return 0;
+
+	otmp = rte_le_to_cpu_32(desc->tx.ol_type_vlan_len_msec);
+	switch (tun_flags) {
+	case PKT_TX_TUNNEL_GENEVE:
+	case PKT_TX_TUNNEL_VXLAN:
+		*l2_len = rxm->l2_len - RTE_ETHER_VXLAN_HLEN;
+		break;
+	case PKT_TX_TUNNEL_GRE:
+		/*
+		 * OL4 header size, defined in 4 Bytes, it contains outer
+		 * L4(GRE) length and tunneling length.
+		 */
+		ol4_len = hns3_get_field(otmp, HNS3_TXD_L4LEN_M,
+					 HNS3_TXD_L4LEN_S);
+		*l2_len = rxm->l2_len - (ol4_len << HNS3_L4_LEN_UNIT);
+		break;
+	default:
+		/* For non UDP / GRE tunneling, drop the tunnel packet */
+		return -EINVAL;
+	}
+	hns3_set_field(otmp, HNS3_TXD_L2LEN_M, HNS3_TXD_L2LEN_S,
+		       rxm->outer_l2_len >> HNS3_L2_LEN_UNIT);
+	desc->tx.ol_type_vlan_len_msec = rte_cpu_to_le_32(otmp);
+
+	return 0;
+}
+
+static void
+hns3_set_tso(struct hns3_desc *desc,
+	     uint64_t ol_flags, struct rte_mbuf *rxm)
+{
+	uint32_t paylen, hdr_len;
+	uint32_t tmp;
+	uint8_t l2_len = rxm->l2_len;
+
+	if (!(ol_flags & PKT_TX_TCP_SEG))
+		return;
+
+	if (hns3_tso_proc_tunnel(desc, ol_flags, rxm, &l2_len))
+		return;
+
+	hdr_len = rxm->l2_len + rxm->l3_len + rxm->l4_len;
+	hdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?
+		    rxm->outer_l2_len + rxm->outer_l3_len : 0;
+	paylen = rxm->pkt_len - hdr_len;
+	if (paylen <= rxm->tso_segsz)
+		return;
+
+	tmp = rte_le_to_cpu_32(desc->tx.type_cs_vlan_tso_len);
+	hns3_set_bit(tmp, HNS3_TXD_TSO_B, 1);
+	hns3_set_bit(tmp, HNS3_TXD_L3CS_B, 1);
+	hns3_set_field(tmp, HNS3_TXD_L4T_M, HNS3_TXD_L4T_S, HNS3_L4T_TCP);
+	hns3_set_bit(tmp, HNS3_TXD_L4CS_B, 1);
+	hns3_set_field(tmp, HNS3_TXD_L4LEN_M, HNS3_TXD_L4LEN_S,
+		       sizeof(struct rte_tcp_hdr) >> HNS3_L4_LEN_UNIT);
+	hns3_set_field(tmp, HNS3_TXD_L2LEN_M, HNS3_TXD_L2LEN_S,
+		       l2_len >> HNS3_L2_LEN_UNIT);
+	desc->tx.type_cs_vlan_tso_len = rte_cpu_to_le_32(tmp);
+	desc->tx.mss = rte_cpu_to_le_16(rxm->tso_segsz);
+}
+
 static void
 fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,
 	  bool first, int offset)
@@ -1865,9 +1937,9 @@ fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,
 	struct hns3_desc *tx_ring = txq->tx_ring;
 	struct hns3_desc *desc = &tx_ring[tx_desc_id];
 	uint8_t frag_end = rxm->next == NULL ? 1 : 0;
+	uint64_t ol_flags = rxm->ol_flags;
 	uint16_t size = rxm->data_len;
 	uint16_t rrcfv = 0;
-	uint64_t ol_flags = rxm->ol_flags;
 	uint32_t hdr_len;
 	uint32_t paylen;
 	uint32_t tmp;
@@ -1882,6 +1954,7 @@ fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,
 			   rxm->outer_l2_len + rxm->outer_l3_len : 0;
 		paylen = rxm->pkt_len - hdr_len;
 		desc->tx.paylen = rte_cpu_to_le_32(paylen);
+		hns3_set_tso(desc, ol_flags, rxm);
 	}
 
 	hns3_set_bit(rrcfv, HNS3_TXD_FE_B, frag_end);
@@ -2195,6 +2268,136 @@ hns3_txd_enable_checksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,
 	desc->tx.type_cs_vlan_tso_len |= rte_cpu_to_le_32(value);
 }
 
+static bool
+hns3_pkt_need_linearized(struct rte_mbuf *tx_pkts, uint32_t bd_num)
+{
+	struct rte_mbuf *m_first = tx_pkts;
+	struct rte_mbuf *m_last = tx_pkts;
+	uint32_t tot_len = 0;
+	uint32_t hdr_len;
+	uint32_t i;
+
+	/*
+	 * Hardware requires that the sum of the data length of every 8
+	 * consecutive buffers is greater than MSS in hns3 network engine.
+	 * We simplify it by ensuring pkt_headlen + the first 8 consecutive
+	 * frags greater than gso header len + mss, and the remaining 7
+	 * consecutive frags greater than MSS except the last 7 frags.
+	 */
+	if (bd_num <= HNS3_MAX_NON_TSO_BD_PER_PKT)
+		return false;
+
+	for (i = 0; m_last && i < HNS3_MAX_NON_TSO_BD_PER_PKT - 1;
+	     i++, m_last = m_last->next)
+		tot_len += m_last->data_len;
+
+	if (!m_last)
+		return true;
+
+	/* ensure the first 8 frags is greater than mss + header */
+	hdr_len = tx_pkts->l2_len + tx_pkts->l3_len + tx_pkts->l4_len;
+	hdr_len += (tx_pkts->ol_flags & PKT_TX_TUNNEL_MASK) ?
+		   tx_pkts->outer_l2_len + tx_pkts->outer_l3_len : 0;
+	if (tot_len + m_last->data_len < tx_pkts->tso_segsz + hdr_len)
+		return true;
+
+	/*
+	 * ensure the sum of the data length of every 7 consecutive buffer
+	 * is greater than mss except the last one.
+	 */
+	for (i = 0; m_last && i < bd_num - HNS3_MAX_NON_TSO_BD_PER_PKT; i++) {
+		tot_len -= m_first->data_len;
+		tot_len += m_last->data_len;
+
+		if (tot_len < tx_pkts->tso_segsz)
+			return true;
+
+		m_first = m_first->next;
+		m_last = m_last->next;
+	}
+
+	return false;
+}
+
+static void
+hns3_outer_header_cksum_prepare(struct rte_mbuf *m)
+{
+	uint64_t ol_flags = m->ol_flags;
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_udp_hdr *udp_hdr;
+	uint32_t paylen, hdr_len;
+
+	if (!(ol_flags & (PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IPV6)))
+		return;
+
+	if (ol_flags & PKT_TX_IPV4) {
+		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
+						   m->outer_l2_len);
+
+		if (ol_flags & PKT_TX_IP_CKSUM)
+			ipv4_hdr->hdr_checksum = 0;
+	}
+
+	if ((ol_flags & PKT_TX_L4_MASK) == PKT_TX_UDP_CKSUM &&
+	    ol_flags & PKT_TX_TCP_SEG) {
+		hdr_len = m->l2_len + m->l3_len + m->l4_len;
+		hdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?
+				m->outer_l2_len + m->outer_l3_len : 0;
+		paylen = m->pkt_len - hdr_len;
+		if (paylen <= m->tso_segsz)
+			return;
+		udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
+						  m->outer_l2_len +
+						  m->outer_l3_len);
+		udp_hdr->dgram_cksum = 0;
+	}
+}
+
+static inline bool
+hns3_pkt_is_tso(struct rte_mbuf *m)
+{
+	return (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG);
+}
+
+static int
+hns3_check_tso_pkt_valid(struct rte_mbuf *m)
+{
+	uint32_t tmp_data_len_sum = 0;
+	uint16_t nb_buf = m->nb_segs;
+	uint32_t paylen, hdr_len;
+	struct rte_mbuf *m_seg;
+	int i;
+
+	if (nb_buf > HNS3_MAX_TSO_BD_PER_PKT)
+		return -EINVAL;
+
+	hdr_len = m->l2_len + m->l3_len + m->l4_len;
+	hdr_len += (m->ol_flags & PKT_TX_TUNNEL_MASK) ?
+			m->outer_l2_len + m->outer_l3_len : 0;
+	if (hdr_len > HNS3_MAX_TSO_HDR_SIZE)
+		return -EINVAL;
+
+	paylen = m->pkt_len - hdr_len;
+	if (paylen > HNS3_MAX_BD_PAYLEN)
+		return -EINVAL;
+
+	/*
+	 * The TSO header (include outer and inner L2, L3 and L4 header)
+	 * should be provided by three descriptors in maximum in hns3 network
+	 * engine.
+	 */
+	m_seg = m;
+	for (i = 0; m_seg != NULL && i < HNS3_MAX_TSO_HDR_BD_NUM && i < nb_buf;
+	     i++, m_seg = m_seg->next) {
+		tmp_data_len_sum += m_seg->data_len;
+	}
+
+	if (hdr_len > tmp_data_len_sum)
+		return -EINVAL;
+
+	return 0;
+}
+
 uint16_t
 hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
 	       uint16_t nb_pkts)
@@ -2206,6 +2409,13 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
 	for (i = 0; i < nb_pkts; i++) {
 		m = tx_pkts[i];
 
+		if (hns3_pkt_is_tso(m) &&
+		    (hns3_pkt_need_linearized(m, m->nb_segs) ||
+		     hns3_check_tso_pkt_valid(m))) {
+			rte_errno = EINVAL;
+			return i;
+		}
+
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
 		ret = rte_validate_tx_offload(m);
 		if (ret != 0) {
@@ -2218,6 +2428,8 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
 			rte_errno = -ret;
 			return i;
 		}
+
+		hns3_outer_header_cksum_prepare(m);
 	}
 
 	return i;
@@ -2241,13 +2453,39 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,
 	return 0;
 }
 
+static int
+hns3_check_non_tso_pkt(uint16_t nb_buf, struct rte_mbuf **m_seg,
+		      struct rte_mbuf *tx_pkt, struct hns3_tx_queue *txq)
+{
+	struct rte_mbuf *new_pkt;
+	int ret;
+
+	if (hns3_pkt_is_tso(*m_seg))
+		return 0;
+
+	/*
+	 * If packet length is greater than HNS3_MAX_FRAME_LEN
+	 * driver support, the packet will be ignored.
+	 */
+	if (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN))
+		return -EINVAL;
+
+	if (unlikely(nb_buf > HNS3_MAX_NON_TSO_BD_PER_PKT)) {
+		ret = hns3_reassemble_tx_pkts(txq, tx_pkt, &new_pkt);
+		if (ret)
+			return ret;
+		*m_seg = new_pkt;
+	}
+
+	return 0;
+}
+
 uint16_t
 hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct rte_net_hdr_lens hdr_lens = {0};
 	struct hns3_tx_queue *txq = tx_queue;
 	struct hns3_entry *tx_bak_pkt;
-	struct rte_mbuf *new_pkt;
 	struct rte_mbuf *tx_pkt;
 	struct rte_mbuf *m_seg;
 	uint32_t nb_hold = 0;
@@ -2279,13 +2517,6 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			goto end_of_tx;
 		}
 
-		/*
-		 * If packet length is greater than HNS3_MAX_FRAME_LEN
-		 * driver support, the packet will be ignored.
-		 */
-		if (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN))
-			break;
-
 		/*
 		 * If packet length is less than minimum packet size, driver
 		 * need to pad it.
@@ -2304,12 +2535,9 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		}
 
 		m_seg = tx_pkt;
-		if (unlikely(nb_buf > HNS3_MAX_TX_BD_PER_PKT)) {
-			if (hns3_reassemble_tx_pkts(txq, tx_pkt, &new_pkt))
-				goto end_of_tx;
-			m_seg = new_pkt;
-			nb_buf = m_seg->nb_segs;
-		}
+
+		if (hns3_check_non_tso_pkt(nb_buf, &m_seg, tx_pkt, txq))
+			goto end_of_tx;
 
 		if (hns3_parse_cksum(txq, tx_next_use, m_seg, &hdr_lens))
 			goto end_of_tx;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 06/24] net/hns3: remove restriction on setting VF MTU
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (4 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 05/24] net/hns3: support TSO Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 07/24] net/hns3: support promiscuous and allmulticast mode for VF Wei Hu (Xavier)
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit 4bf2c84bd88691bbb9cdc39a8bcf597537abfa80 ]

The hns3 PF/VF devices on the same port share the hardware MTU
configuration. Currently, we send mailbox to inform hns3 PF kernel
ethdev driver to finish hardware MTU configuration in hns3 VF PMD
driver, there is no need to stop the port for hns3 VF device, and
the MTU value issued by hns3 VF PMD driver must be less than or
equal to PF's MTU.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev_vf.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index e6fc2ea88..69cc2be78 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -621,12 +621,14 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	uint32_t frame_size = mtu + HNS3_ETH_OVERHEAD;
 	int ret;
 
-	if (dev->data->dev_started) {
-		hns3_err(hw, "Failed to set mtu, port %u must be stopped "
-			 "before configuration", dev->data->port_id);
-		return -EBUSY;
-	}
-
+	/*
+	 * The hns3 PF/VF devices on the same port share the hardware MTU
+	 * configuration. Currently, we send mailbox to inform hns3 PF kernel
+	 * ethdev driver to finish hardware MTU configuration in hns3 VF PMD
+	 * driver, there is no need to stop the port for hns3 VF device, and the
+	 * MTU value issued by hns3 VF PMD driver must be less than or equal to
+	 * PF's MTU.
+	 */
 	if (rte_atomic16_read(&hw->reset.resetting)) {
 		hns3_err(hw, "Failed to set mtu during resetting");
 		return -EIO;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 07/24] net/hns3: support promiscuous and allmulticast mode for VF
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (5 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 06/24] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 08/24] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit 40486d38496241711955fc752ff4a6db4c89da7f ]

Currently, we only support VF device is bound to vfio_pci or igb_uio and
then driven by DPDK driver when PF is driven by kernel mode hns3 ethdev
driver, VF is not supported when PF is driven by hns3 DPDK driver.

This patch adds promiscuous and allmulticast mode support for hns3 VF
PMD driver.
1) The promiscuous/allmulticast mode can be configured successfully only
   based on the trusted VF device. If based on the non trusted VF
   device, configuring promiscuous/allmulticast mode will fail. The hns3
   VF device can be configured as trusted device by hns3 PF kernel
   ethdev driver on the host by "ip link set <eth num> vf <vf id> turst
   on" command.
2) After the promiscuous mode is configured successfully, hns3 VF PMD
   driver can receive the ingress and outgoing traffic. In the words,
   all the ingress packets, all the packets sent from the PF and other
   VFs on the same physical port.
3) Note: Because of the hardware constraints, By default vlan filter is
   enabled and couldn't be turned off based on VF device, so vlan filter
   is still effective even in promiscuous mode. If upper applications
   don't call rte_eth_dev_vlan_filter API function to set vlan based on
   VF device, hns3 VF PMD driver will can't receive the packets with
   vlan tag in promiscuous mode.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 doc/guides/nics/features/hns3_vf.ini |   2 +
 drivers/net/hns3/hns3_ethdev_vf.c    | 117 +++++++++++++++++++++++++--
 drivers/net/hns3/hns3_mbx.c          |  23 ++++++
 drivers/net/hns3/hns3_mbx.h          |   2 +
 4 files changed, 139 insertions(+), 5 deletions(-)

diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini
index e4e77380f..80773ac90 100644
--- a/doc/guides/nics/features/hns3_vf.ini
+++ b/doc/guides/nics/features/hns3_vf.ini
@@ -9,6 +9,8 @@ Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
 TSO                  = Y
+Promiscuous mode     = Y
+Allmulticast mode    = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 69cc2be78..6d6d9cdf5 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -410,7 +410,8 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
 }
 
 static int
-hns3vf_set_promisc_mode(struct hns3_hw *hw, bool en_bc_pmc)
+hns3vf_set_promisc_mode(struct hns3_hw *hw, bool en_bc_pmc,
+			bool en_uc_pmc, bool en_mc_pmc)
 {
 	struct hns3_mbx_vf_to_pf_cmd *req;
 	struct hns3_cmd_desc desc;
@@ -418,17 +419,115 @@ hns3vf_set_promisc_mode(struct hns3_hw *hw, bool en_bc_pmc)
 
 	req = (struct hns3_mbx_vf_to_pf_cmd *)desc.data;
 
+	/*
+	 * The hns3 VF PMD driver depends on the hns3 PF kernel ethdev driver,
+	 * so there are some features for promiscuous/allmulticast mode in hns3
+	 * VF PMD driver as below:
+	 * 1. The promiscuous/allmulticast mode can be configured successfully
+	 *    only based on the trusted VF device. If based on the non trusted
+	 *    VF device, configuring promiscuous/allmulticast mode will fail.
+	 *    The hns3 VF device can be confiruged as trusted device by hns3 PF
+	 *    kernel ethdev driver on the host by the following command:
+	 *      "ip link set <eth num> vf <vf id> turst on"
+	 * 2. After the promiscuous mode is configured successfully, hns3 VF PMD
+	 *    driver can receive the ingress and outgoing traffic. In the words,
+	 *    all the ingress packets, all the packets sent from the PF and
+	 *    other VFs on the same physical port.
+	 * 3. Note: Because of the hardware constraints, By default vlan filter
+	 *    is enabled and couldn't be turned off based on VF device, so vlan
+	 *    filter is still effective even in promiscuous mode. If upper
+	 *    applications don't call rte_eth_dev_vlan_filter API function to
+	 *    set vlan based on VF device, hns3 VF PMD driver will can't receive
+	 *    the packets with vlan tag in promiscuoue mode.
+	 */
 	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MBX_VF_TO_PF, false);
 	req->msg[0] = HNS3_MBX_SET_PROMISC_MODE;
 	req->msg[1] = en_bc_pmc ? 1 : 0;
+	req->msg[2] = en_uc_pmc ? 1 : 0;
+	req->msg[3] = en_mc_pmc ? 1 : 0;
 
 	ret = hns3_cmd_send(hw, &desc, 1);
 	if (ret)
-		hns3_err(hw, "Set promisc mode fail, status is %d", ret);
+		hns3_err(hw, "Set promisc mode fail, ret = %d", ret);
+
+	return ret;
+}
+
+static int
+hns3vf_dev_promiscuous_enable(struct rte_eth_dev *dev)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	int ret;
+
+	ret = hns3vf_set_promisc_mode(hw, true, true, true);
+	if (ret)
+		hns3_err(hw, "Failed to enable promiscuous mode, ret = %d",
+			ret);
+	return ret;
+}
+
+static int
+hns3vf_dev_promiscuous_disable(struct rte_eth_dev *dev)
+{
+	bool allmulti = dev->data->all_multicast ? true : false;
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	int ret;
+
+	ret = hns3vf_set_promisc_mode(hw, true, false, allmulti);
+	if (ret)
+		hns3_err(hw, "Failed to disable promiscuous mode, ret = %d",
+			ret);
+	return ret;
+}
+
+static int
+hns3vf_dev_allmulticast_enable(struct rte_eth_dev *dev)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	int ret;
+
+	if (dev->data->promiscuous)
+		return 0;
+
+	ret = hns3vf_set_promisc_mode(hw, true, false, true);
+	if (ret)
+		hns3_err(hw, "Failed to enable allmulticast mode, ret = %d",
+			ret);
+	return ret;
+}
+
+static int
+hns3vf_dev_allmulticast_disable(struct rte_eth_dev *dev)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	int ret;
+
+	if (dev->data->promiscuous)
+		return 0;
 
+	ret = hns3vf_set_promisc_mode(hw, true, false, false);
+	if (ret)
+		hns3_err(hw, "Failed to disable allmulticast mode, ret = %d",
+			ret);
 	return ret;
 }
 
+static int
+hns3vf_restore_promisc(struct hns3_adapter *hns)
+{
+	struct hns3_hw *hw = &hns->hw;
+	bool allmulti = hw->data->all_multicast ? true : false;
+
+	if (hw->data->promiscuous)
+		return hns3vf_set_promisc_mode(hw, true, true, true);
+
+	return hns3vf_set_promisc_mode(hw, true, false, allmulti);
+}
+
 static int
 hns3vf_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id,
 			     bool mmap, enum hns3_ring_type queue_type,
@@ -1257,7 +1356,7 @@ hns3vf_init_hardware(struct hns3_adapter *hns)
 	uint16_t mtu = hw->data->mtu;
 	int ret;
 
-	ret = hns3vf_set_promisc_mode(hw, true);
+	ret = hns3vf_set_promisc_mode(hw, true, false, false);
 	if (ret)
 		return ret;
 
@@ -1299,7 +1398,7 @@ hns3vf_init_hardware(struct hns3_adapter *hns)
 	return 0;
 
 err_init_hardware:
-	(void)hns3vf_set_promisc_mode(hw, false);
+	(void)hns3vf_set_promisc_mode(hw, false, false, false);
 	return ret;
 }
 
@@ -1421,7 +1520,7 @@ hns3vf_uninit_vf(struct rte_eth_dev *eth_dev)
 
 	hns3_rss_uninit(hns);
 	(void)hns3vf_set_alive(hw, false);
-	(void)hns3vf_set_promisc_mode(hw, false);
+	(void)hns3vf_set_promisc_mode(hw, false, false, false);
 	hns3vf_disable_irq0(hw);
 	rte_intr_disable(&pci_dev->intr_handle);
 	hns3_intr_unregister(&pci_dev->intr_handle, hns3vf_interrupt_handler,
@@ -1956,6 +2055,10 @@ hns3vf_restore_conf(struct hns3_adapter *hns)
 	if (ret)
 		goto err_mc_mac;
 
+	ret = hns3vf_restore_promisc(hns);
+	if (ret)
+		goto err_vlan_table;
+
 	ret = hns3vf_restore_vlan_conf(hns);
 	if (ret)
 		goto err_vlan_table;
@@ -2106,6 +2209,10 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {
 	.dev_stop           = hns3vf_dev_stop,
 	.dev_close          = hns3vf_dev_close,
 	.mtu_set            = hns3vf_dev_mtu_set,
+	.promiscuous_enable = hns3vf_dev_promiscuous_enable,
+	.promiscuous_disable = hns3vf_dev_promiscuous_disable,
+	.allmulticast_enable = hns3vf_dev_allmulticast_enable,
+	.allmulticast_disable = hns3vf_dev_allmulticast_disable,
 	.stats_get          = hns3_stats_get,
 	.stats_reset        = hns3_stats_reset,
 	.xstats_get         = hns3_dev_xstats_get,
diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c
index 64996c9ae..34c8c688f 100644
--- a/drivers/net/hns3/hns3_mbx.c
+++ b/drivers/net/hns3/hns3_mbx.c
@@ -326,6 +326,21 @@ hns3_handle_link_change_event(struct hns3_hw *hw,
 	hns3_update_link_status(hw);
 }
 
+static void
+hns3_handle_promisc_info(struct hns3_hw *hw, uint16_t promisc_en)
+{
+	if (!promisc_en) {
+		/*
+		 * When promisc/allmulti mode is closed by the hns3 PF kernel
+		 * ethdev driver for untrusted, modify VF's related status.
+		 */
+		hns3_warn(hw, "Promisc mode will be closed by host for being "
+			      "untrusted.");
+		hw->data->promiscuous = 0;
+		hw->data->all_multicast = 0;
+	}
+}
+
 void
 hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 {
@@ -384,6 +399,14 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 		case HNS3_MBX_PUSH_LINK_STATUS:
 			hns3_handle_link_change_event(hw, req);
 			break;
+		case HNS3_MBX_PUSH_PROMISC_INFO:
+			/*
+			 * When the trust status of VF device changed by the
+			 * hns3 PF kernel driver, VF driver will receive this
+			 * mailbox message from PF driver.
+			 */
+			hns3_handle_promisc_info(hw, req->msg[1]);
+			break;
 		default:
 			hns3_err(hw,
 				 "VF received unsupported(%d) mbx msg from PF",
diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h
index b01eaacc3..d6d70f686 100644
--- a/drivers/net/hns3/hns3_mbx.h
+++ b/drivers/net/hns3/hns3_mbx.h
@@ -40,6 +40,8 @@ enum HNS3_MBX_OPCODE {
 	HNS3_MBX_SET_MTU,               /* (VF -> PF) set mtu */
 	HNS3_MBX_GET_QID_IN_PF,         /* (VF -> PF) get queue id in pf */
 
+	HNS3_MBX_PUSH_PROMISC_INFO = 36, /* (PF -> VF) push vf promisc info */
+
 	HNS3_MBX_HANDLE_VF_TBL = 38,    /* (VF -> PF) store/clear hw cfg tbl */
 	HNS3_MBX_GET_RING_VECTOR_MAP,   /* (VF -> PF) get ring-to-vector map */
 	HNS3_MBX_PUSH_LINK_STATUS = 201, /* (IMP -> PF) get port link status */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 08/24] net/hns3: fix adding multicast MAC address
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (6 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 07/24] net/hns3: support promiscuous and allmulticast mode for VF Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 09/24] net/hns3: get Rx/Tx queue fbd in xstats Wei Hu (Xavier)
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit fb94f359481ff6d53f6b7850d3ad393addfb6afb ]

Currently, when upper application calls the rte_eth_dev_mac_addr_add API
function to add a MC mac address based on hns3 PF/VF device, it will
fail.

In hns3 network engine adding UC and MC mac address with different
commands with firmware. We need to determine whether the input address
is a UC or a MC address to call different commands in the
'.mac_addr_add' and '.mac_addr_remove' ops implementation functions in
hns3 PF and VF driver as below:
  hns3_add_mac_addr
  hns3vf_add_uc_mac_addr
  hns3_remove_mac_addr
  hns3vf_remove_mac_addr

By the way, it is recommended calling the rte_eth_dev_set_mc_addr_list API
function to set the MC mac address, because using the
rte_eth_dev_mac_addr_add API function to set MC mac address may affect the
specifications of UC mac addresses.

Fixes: 7d7f9f80bbfb ("net/hns3: support MAC address related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 133 ++++++++++++++---
 drivers/net/hns3/hns3_ethdev_vf.c | 231 +++++++++++++++++++++++-------
 2 files changed, 295 insertions(+), 69 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 39edd7e51..0bad55030 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -77,6 +77,11 @@ static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
 static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
+static int hns3_add_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+static int hns3_remove_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
 {
@@ -1459,6 +1464,53 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	return ret;
 }
 
+static int
+hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3_add_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_remove_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to remove mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		  uint32_t idx, __attribute__ ((unused)) uint32_t pool)
@@ -1468,12 +1520,27 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_add_uc_addr_common(hw, mac_addr);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_add_uc_addr_common(hw, mac_addr);
+
 	if (ret) {
 		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
+			 ret);
 		return ret;
 	}
 
@@ -1495,7 +1562,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Remove unicast mac addr err! addr(%s) invalid",
+		hns3_err(hw, "remove unicast mac addr err! addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1522,16 +1589,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_remove_uc_addr_common(hw, mac_addr);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_remove_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_remove_uc_addr_common(hw, mac_addr);
+	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
-		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s): %d", mac_str, ret);
-		return;
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,
+			 ret);
 	}
-
-	rte_spinlock_unlock(&hw->lock);
 }
 
 static int
@@ -1632,19 +1701,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
 
 	for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		if (del)
-			ret = hns3_remove_uc_addr_common(hw, addr);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3_remove_mc_addr(hw, addr) :
+			      hns3_add_mc_addr(hw, addr);
 		else
-			ret = hns3_add_uc_addr_common(hw, addr);
+			ret = del ? hns3_remove_uc_addr_common(hw, addr) :
+			      hns3_add_uc_addr_common(hw, addr);
+
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
-			hns3_dbg(hw,
-				 "Failed to %s mac addr(%s). ret:%d i:%d",
-				 del ? "remove" : "restore", mac_str, ret, i);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
 	return err;
@@ -1691,7 +1763,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_multicast_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr, addr(%s) invalid",
+		hns3_err(hw, "failed to add mc mac addr, addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1720,7 +1792,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 			hns3_err(hw, "mc mac vlan table is full");
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mc mac addr(%s): %d", mac_str, ret);
 	}
 
 	return ret;
@@ -1785,7 +1857,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
@@ -1798,7 +1870,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
@@ -1809,12 +1881,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 				rte_ether_format_addr(mac_str,
 						      RTE_ETHER_ADDR_FMT_SIZE,
 						      addr);
-				hns3_err(hw, "Failed to set mc mac addr, "
+				hns3_err(hw, "failed to set mc mac addr, "
 					 "addrs invalid. two same addrs(%s).",
 					 mac_str);
 				return -EINVAL;
 			}
 		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
 
 	return 0;
@@ -3601,6 +3691,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code)
 			     "add mac ethertype failed for undefined, code=%d.",
 			     resp_code);
 		return_status = -EIO;
+		break;
 	}
 
 	return return_status;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 6d6d9cdf5..d503d5011 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -59,6 +59,10 @@ static enum hns3_reset_level hns3vf_get_reset_level(struct hns3_hw *hw,
 static int hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3vf_dev_configure_vlan(struct rte_eth_dev *dev);
 
+static int hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
+				  struct rte_ether_addr *mac_addr);
+static int hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
+				     struct rte_ether_addr *mac_addr);
 /* set PCI bus mastering */
 static void
 hns3vf_set_bus_master(const struct rte_pci_device *device, bool op)
@@ -134,6 +138,76 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op)
 	return -1;
 }
 
+static int
+hns3vf_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
+				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_REMOVE,
+				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN,
+				false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3vf_add_mc_mac_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		    __attribute__ ((unused)) uint32_t idx,
@@ -144,14 +218,26 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
-				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3vf_add_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s) for vf: %d", mac_str,
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
 			 ret);
 	}
 
@@ -168,15 +254,17 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_REMOVE,
-				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, false,
-				NULL, 0);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_remove_mc_mac_addr(hw, mac_addr);
+	else
+		ret = hns3vf_remove_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s) for vf: %d",
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d",
 			 mac_str, ret);
 	}
 }
@@ -243,39 +331,39 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del)
 {
 	struct hns3_hw *hw = &hns->hw;
 	struct rte_ether_addr *addr;
-	enum hns3_mbx_mac_vlan_subcode opcode;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int ret = 0;
+	int err = 0;
+	int ret;
 	int i;
 
-	if (del)
-		opcode = HNS3_MBX_MAC_VLAN_UC_REMOVE;
-	else
-		opcode = HNS3_MBX_MAC_VLAN_UC_ADD;
 	for (i = 0; i < HNS3_VF_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr);
-		hns3_dbg(hw, "rm mac addr: %s", mac_str);
-		ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST, opcode,
-					addr->addr_bytes, RTE_ETHER_ADDR_LEN,
-					false, NULL, 0);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3vf_remove_mc_mac_addr(hw, addr) :
+			      hns3vf_add_mc_mac_addr(hw, addr);
+		else
+			ret = del ? hns3vf_remove_uc_mac_addr(hw, addr) :
+			      hns3vf_add_uc_mac_addr(hw, addr);
+
 		if (ret) {
-			hns3_err(hw, "Failed to remove mac addr for vf: %d",
-				 ret);
-			break;
+			err = ret;
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
-	return ret;
+	return err;
 }
 
 static int
-hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
 		       struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -294,11 +382,10 @@ hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
 			  struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -317,45 +404,92 @@ hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
-			    struct rte_ether_addr *mc_addr_set,
-			    uint32_t nb_mc_addr)
+hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw,
+			     struct rte_ether_addr *mc_addr_set,
+			     uint32_t nb_mc_addr)
 {
-	struct hns3_adapter *hns = dev->data->dev_private;
-	struct hns3_hw *hw = &hns->hw;
-	struct rte_ether_addr *addr;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int cur_addr_num;
-	int set_addr_num;
-	int num;
-	int ret;
-	int i;
+	struct rte_ether_addr *addr;
+	uint32_t i;
+	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
 	}
 
-	set_addr_num = (int)nb_mc_addr;
-	for (i = 0; i < set_addr_num; i++) {
+	/* Check if input mac addresses are valid */
+	for (i = 0; i < nb_mc_addr; i++) {
 		addr = &mc_addr_set[i];
 		if (!rte_is_multicast_ether_addr(addr)) {
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
+
+		/* Check if there are duplicate addresses */
+		for (j = i + 1; j < nb_mc_addr; j++) {
+			if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. two same addrs(%s).",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_VF_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
+
+	return 0;
+}
+
+static int
+hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mc_addr_set,
+			    uint32_t nb_mc_addr)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_ether_addr *addr;
+	int cur_addr_num;
+	int set_addr_num;
+	int num;
+	int ret;
+	int i;
+
+	ret = hns3vf_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
+	if (ret)
+		return ret;
+
 	rte_spinlock_lock(&hw->lock);
 	cur_addr_num = hw->mc_addrs_num;
 	for (i = 0; i < cur_addr_num; i++) {
 		num = cur_addr_num - i - 1;
 		addr = &hw->mc_addrs[num];
-		ret = hns3vf_remove_mc_mac_addr(hns, addr);
+		ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -364,9 +498,10 @@ hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
 		hw->mc_addrs_num--;
 	}
 
+	set_addr_num = (int)nb_mc_addr;
 	for (i = 0; i < set_addr_num; i++) {
 		addr = &mc_addr_set[i];
-		ret = hns3vf_add_mc_mac_addr(hns, addr);
+		ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -395,9 +530,9 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
 		if (!rte_is_multicast_ether_addr(addr))
 			continue;
 		if (del)
-			ret = hns3vf_remove_mc_mac_addr(hns, addr);
+			ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		else
-			ret = hns3vf_add_mc_mac_addr(hns, addr);
+			ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 09/24] net/hns3: get Rx/Tx queue fbd in xstats
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (7 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 08/24] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 10/24] net/hns3: get Tx abnormal errors " Wei Hu (Xavier)
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengwen Feng <fengchengwen@huawei.com>

[ upstream commit 4016d76b7c54db9b292e5a90db53029980e91f74 ]

This patch adds getting Rx/Tx queue fbd information in extended device
statistics. The upper level application can get them by calling the
rte_eth_xstats_get API function.

The fbd registers of every Rx/Tx queue are very useful to identify the
Rx/Tx bottleneck.
1. The Rx queue fbd register is the number of the unprocessed buffer
   descriptors which are waiting for driver to process;
2. The Tx queue fbd register is the number of the unprocessed buffer
   descriptors which are waiting for network engine hardware to process.

As a result, we get the following output information in testpmd
application by using the command "show port xstats" as below:
rx_q0RX_QUEUE_FBD: 19
rx_q1RX_QUEUE_FBD: 18
tx_q0TX_QUEUE_FBD: 0
tx_q1TX_QUEUE_FBD: 0

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_stats.c | 174 +++++++++++++++++-----------------
 drivers/net/hns3/hns3_stats.h |   3 +-
 2 files changed, 90 insertions(+), 87 deletions(-)

diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c
index 10cc7570c..e03ffbbd6 100644
--- a/drivers/net/hns3/hns3_stats.c
+++ b/drivers/net/hns3/hns3_stats.c
@@ -13,6 +13,7 @@
 #include "hns3_ethdev.h"
 #include "hns3_rxtx.h"
 #include "hns3_logs.h"
+#include "hns3_regs.h"
 
 /* MAC statistics */
 static const struct hns3_xstats_name_offset hns3_mac_strings[] = {
@@ -233,6 +234,16 @@ static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = {
 		HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(ol4_csum_erros)}
 };
 
+/* The statistic of rx queue */
+static const struct hns3_xstats_name_offset hns3_rx_queue_strings[] = {
+	{"RX_QUEUE_FBD", HNS3_RING_RX_FBDNUM_REG}
+};
+
+/* The statistic of tx queue */
+static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
+	{"TX_QUEUE_FBD", HNS3_RING_TX_FBDNUM_REG}
+};
+
 #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \
 	sizeof(hns3_mac_strings[0]))
 
@@ -245,6 +256,12 @@ static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = {
 #define HNS3_NUM_RX_BD_ERROR_XSTATS (sizeof(hns3_rx_bd_error_strings) / \
 	sizeof(hns3_rx_bd_error_strings[0]))
 
+#define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \
+	sizeof(hns3_rx_queue_strings[0]))
+
+#define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \
+	sizeof(hns3_tx_queue_strings[0]))
+
 #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \
 			    HNS3_NUM_RESET_XSTATS)
 
@@ -547,13 +564,16 @@ static int
 hns3_xstats_calc_num(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
+	int bderr_stats = dev->data->nb_rx_queues * HNS3_NUM_RX_BD_ERROR_XSTATS;
+	int rx_queue_stats = dev->data->nb_rx_queues * HNS3_NUM_RX_QUEUE_STATS;
+	int tx_queue_stats = dev->data->nb_tx_queues * HNS3_NUM_TX_QUEUE_STATS;
 
 	if (hns->is_vf)
-		return dev->data->nb_rx_queues * HNS3_NUM_RX_BD_ERROR_XSTATS +
-		       HNS3_NUM_RESET_XSTATS;
+		return bderr_stats + rx_queue_stats + tx_queue_stats +
+			HNS3_NUM_RESET_XSTATS;
 	else
-		return dev->data->nb_rx_queues * HNS3_NUM_RX_BD_ERROR_XSTATS +
-		       HNS3_FIX_NUM_STATS;
+		return bderr_stats + rx_queue_stats + tx_queue_stats +
+			HNS3_FIX_NUM_STATS;
 }
 
 /*
@@ -579,6 +599,7 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	struct hns3_mac_stats *mac_stats = &hw->mac_stats;
 	struct hns3_reset_stats *reset_stats = &hw->reset.stats;
 	struct hns3_rx_queue *rxq;
+	uint32_t reg_offset;
 	uint16_t i, j;
 	char *addr;
 	int count;
@@ -627,7 +648,7 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	}
 
 	/* Get the Rx BD errors stats */
-	for (j = 0; j != dev->data->nb_rx_queues; ++j) {
+	for (j = 0; j < dev->data->nb_rx_queues; j++) {
 		for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
 			rxq = dev->data->rx_queues[j];
 			addr = (char *)rxq + hns3_rx_bd_error_strings[i].offset;
@@ -637,6 +658,30 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 		}
 	}
 
+	/* Get rx queue stats */
+	for (j = 0; j < dev->data->nb_rx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
+			reg_offset = HNS3_TQP_REG_OFFSET +
+					HNS3_TQP_REG_SIZE * j;
+			xstats[count].value = hns3_read_dev(hw,
+				reg_offset + hns3_rx_queue_strings[i].offset);
+			xstats[count].id = count;
+			count++;
+		}
+	}
+
+	/* Get tx queue stats */
+	for (j = 0; j < dev->data->nb_tx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
+			reg_offset = HNS3_TQP_REG_OFFSET +
+					HNS3_TQP_REG_SIZE * j;
+			xstats[count].value = hns3_read_dev(hw,
+				reg_offset + hns3_tx_queue_strings[i].offset);
+			xstats[count].id = count;
+			count++;
+		}
+	}
+
 	return count;
 }
 
@@ -665,7 +710,7 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
  *     is the number of entries filled in the stats table.
  */
 int
-hns3_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
+hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
 			  struct rte_eth_xstat_name *xstats_names,
 			  __rte_unused unsigned int size)
 {
@@ -711,6 +756,24 @@ hns3_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
 		}
 	}
 
+	for (j = 0; j < dev->data->nb_rx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
+			snprintf(xstats_names[count].name,
+				 sizeof(xstats_names[count].name),
+				 "rx_q%u%s", j, hns3_rx_queue_strings[i].name);
+			count++;
+		}
+	}
+
+	for (j = 0; j < dev->data->nb_tx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
+			snprintf(xstats_names[count].name,
+				 sizeof(xstats_names[count].name),
+				 "tx_q%u%s", j, hns3_tx_queue_strings[i].name);
+			count++;
+		}
+	}
+
 	return count;
 }
 
@@ -741,18 +804,13 @@ int
 hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 			  uint64_t *values, uint32_t size)
 {
+	const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
 	struct hns3_adapter *hns = dev->data->dev_private;
-	struct hns3_pf *pf = &hns->pf;
+	struct rte_eth_xstat *values_copy;
 	struct hns3_hw *hw = &hns->hw;
-	struct hns3_mac_stats *mac_stats = &hw->mac_stats;
-	struct hns3_reset_stats *reset_stats = &hw->reset.stats;
-	struct hns3_rx_queue *rxq;
-	const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
-	uint64_t *values_copy;
+	uint32_t count_value;
 	uint64_t len;
-	uint32_t count = 0;
-	uint16_t i, j;
-	char *addr;
+	uint32_t i;
 	int ret;
 
 	if (ids == NULL || size < cnt_stats)
@@ -765,7 +823,7 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 		return ret;
 	}
 
-	len = cnt_stats * HNS3_VALUES_BYTES;
+	len = cnt_stats * sizeof(struct rte_eth_xstat);
 	values_copy = rte_zmalloc("hns3_xstats_values", len, 0);
 	if (values_copy == NULL) {
 		hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
@@ -773,36 +831,10 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 		return -ENOMEM;
 	}
 
-	if (!hns->is_vf) {
-		/* Get MAC name from hw->hw_xstats.mac_stats */
-		for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
-			addr = (char *)mac_stats + hns3_mac_strings[i].offset;
-			values_copy[count] = *(uint64_t *)addr;
-			count++;
-		}
-
-		for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) {
-			addr = (char *)&pf->abn_int_stats +
-			       hns3_error_int_stats_strings[i].offset;
-			values_copy[count] = *(uint64_t *)addr;
-			count++;
-		}
-	}
-
-	for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
-		addr = (char *)reset_stats +
-		       hns3_reset_stats_strings[i].offset;
-		values_copy[count] = *(uint64_t *)addr;
-		count++;
-	}
-
-	for (j = 0; j != dev->data->nb_rx_queues; ++j) {
-		for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
-			rxq = dev->data->rx_queues[j];
-			addr = (char *)rxq + hns3_rx_bd_error_strings[i].offset;
-			values_copy[count] = *(uint64_t *)addr;
-			count++;
-		}
+	count_value = hns3_dev_xstats_get(dev, values_copy, cnt_stats);
+	if (count_value != cnt_stats) {
+		rte_free(values_copy);
+		return -EINVAL;
 	}
 
 	for (i = 0; i < size; i++) {
@@ -812,7 +844,8 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 			rte_free(values_copy);
 			return -EINVAL;
 		}
-		memcpy(&values[i], &values_copy[ids[i]], sizeof(values[i]));
+		memcpy(&values[i], &values_copy[ids[i]].value,
+			sizeof(values[i]));
 	}
 
 	rte_free(values_copy);
@@ -845,67 +878,38 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
 				struct rte_eth_xstat_name *xstats_names,
 				const uint64_t *ids, uint32_t size)
 {
+	const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
 	struct hns3_adapter *hns = dev->data->dev_private;
-	struct rte_eth_xstat_name *xstats_names_copy;
+	struct rte_eth_xstat_name *names_copy;
 	struct hns3_hw *hw = &hns->hw;
-	const uint32_t cnt_stats = hns3_xstats_calc_num(dev);
-	uint16_t count_name = 0;
-	uint16_t i, j;
 	uint64_t len;
+	uint32_t i;
 
 	if (ids == NULL || xstats_names == NULL)
 		return cnt_stats;
 
 	len = cnt_stats * sizeof(struct rte_eth_xstat_name);
-	xstats_names_copy = rte_zmalloc("hns3_xstats_names", len, 0);
-	if (xstats_names_copy == NULL) {
+	names_copy = rte_zmalloc("hns3_xstats_names", len, 0);
+	if (names_copy == NULL) {
 		hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed "
 			     "to store statistics names", len);
 		return -ENOMEM;
 	}
 
-	if (!hns->is_vf) {
-		for (i = 0; i < HNS3_NUM_MAC_STATS; i++) {
-			snprintf(xstats_names_copy[count_name].name,
-				 sizeof(xstats_names_copy[count_name].name),
-				 "%s", hns3_mac_strings[i].name);
-			count_name++;
-		}
-		for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) {
-			snprintf(xstats_names_copy[count_name].name,
-				 sizeof(xstats_names_copy[count_name].name),
-				 "%s", hns3_error_int_stats_strings[i].name);
-			count_name++;
-		}
-	}
-	for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
-		snprintf(xstats_names_copy[count_name].name,
-			 sizeof(xstats_names_copy[count_name].name),
-			 "%s", hns3_reset_stats_strings[i].name);
-		count_name++;
-	}
-	for (j = 0; j != dev->data->nb_rx_queues; ++j) {
-		for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) {
-			snprintf(xstats_names_copy[count_name].name,
-				 sizeof(xstats_names_copy[count_name].name),
-				 "rx_q%u%s", j,
-				 hns3_rx_bd_error_strings[i].name);
-			count_name++;
-		}
-	}
+	(void)hns3_dev_xstats_get_names(dev, names_copy, cnt_stats);
 
 	for (i = 0; i < size; i++) {
 		if (ids[i] >= cnt_stats) {
 			hns3_err(hw, "ids[%d] (%" PRIx64 ") is invalid, "
 				     "should < %u", i, ids[i], cnt_stats);
-			rte_free(xstats_names_copy);
+			rte_free(names_copy);
 			return -EINVAL;
 		}
 		snprintf(xstats_names[i].name, sizeof(xstats_names[i].name),
-			 "%s", xstats_names_copy[ids[i]].name);
+			 "%s", names_copy[ids[i]].name);
 	}
 
-	rte_free(xstats_names_copy);
+	rte_free(names_copy);
 	return size;
 }
 
diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h
index 365bae083..0993c5f57 100644
--- a/drivers/net/hns3/hns3_stats.h
+++ b/drivers/net/hns3/hns3_stats.h
@@ -9,7 +9,6 @@
 #define HNS3_MAC_CMD_NUM		21
 #define HNS3_RD_FIRST_STATS_NUM		2
 #define HNS3_RD_OTHER_STATS_NUM		4
-#define HNS3_VALUES_BYTES		8
 
 /* TQP stats */
 struct hns3_tqp_stats {
@@ -137,7 +136,7 @@ int hns3_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
 int hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 			unsigned int n);
 int hns3_dev_xstats_reset(struct rte_eth_dev *dev);
-int hns3_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
+int hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
 			      struct rte_eth_xstat_name *xstats_names,
 			      __rte_unused unsigned int size);
 int hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 10/24] net/hns3: get Tx abnormal errors in xstats
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (8 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 09/24] net/hns3: get Rx/Tx queue fbd in xstats Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 11/24] net/hns3: get PCI revision ID Wei Hu (Xavier)
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit c4b7d6761d01d80cd975f47bf5c850721b891b61 ]

When upper level application calls the rte_eth_tx_burst API function to
send multiple packets at a time with burst mode based on hns3 network
engine, there are some abnormal conditions that cause the driver to fail
to operate the hardware to send packets correctly.

This patch adds some statistic counts for the abnormal errors of Tx data
path to the extend device statistics. The upper level application can
get them by calling the rte_eth_xstats_get API function.

Note: When using burst mode to call the rte_eth_tx_burst API function to
send multiple packets at a time. When the first abnormal error is
detected, add one to the relevant error statistics item, and then exit
the loop of sending multiple packets of the function. That is to say,
even if there are multiple packets in which abnormal errors may be
detected in the burst, the relevant error statistics in the driver will
only be increased by one.

The detail description of the Tx abnormal errors statistic items as
below:
 - TX_OVER_LENGTH_PKT_CNT Total number of greater than
   HNS3_MAX_FRAME_LEN the driver supported.

 - TX_EXCEED_LIMITED_BD_PKT_CNT
     Total number of exceeding the hardware limited bd which process a
     packet needed bd numbers.

 - TX_EXCEED_LIMITED_BD_PKT_REASSEMBLE_FAIL_CNT
     Total number of exceeding the hardware limited bd fail which
     process a packet needed bd numbers and reassemble fail.

 - TX_UNSUPPORTED_TUNNEL_PKT_CNT
     Total number of unsupported tunnel packet. The unsupported tunnel
     type: vxlan_gpe, gtp, ipip and MPLSINUDP, MPLSINUDP is a packet
     with MPLS-in-UDP RFC 7510 header.

 - TX_QUEUE_FULL_CNT
     Total count which the available bd numbers in current bd queue is
     less than the bd numbers with the pkt process needed.

 - TX_SHORT_PKT_PAD_FAIL_CNT
     Total count which the packet length is less than minimum packet
     size HNS3_MIN_PKT_SIZE and fail to be appended with 0.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Hao Chen <chenhao164@huawei.com>
---
 drivers/net/hns3/hns3_rxtx.c  |  24 +++++--
 drivers/net/hns3/hns3_rxtx.h  |  48 ++++++++++++++
 drivers/net/hns3/hns3_stats.c | 115 +++++++++++++++++++++++++++-------
 3 files changed, 159 insertions(+), 28 deletions(-)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 734a11fdc..972dc7101 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1810,6 +1810,12 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
 	txq->configured = true;
 	txq->io_base = (void *)((char *)hw->io_base + HNS3_TQP_REG_OFFSET +
 				idx * HNS3_TQP_REG_SIZE);
+	txq->over_length_pkt_cnt = 0;
+	txq->exceed_limit_bd_pkt_cnt = 0;
+	txq->exceed_limit_bd_reassem_fail = 0;
+	txq->unsupported_tunnel_pkt_cnt = 0;
+	txq->queue_full_cnt = 0;
+	txq->pkt_padding_fail_cnt = 0;
 	rte_spinlock_lock(&hw->lock);
 	dev->data->tx_queues[idx] = txq;
 	rte_spinlock_unlock(&hw->lock);
@@ -2443,8 +2449,10 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id,
 	if (m->ol_flags & PKT_TX_TUNNEL_MASK) {
 		(void)rte_net_get_ptype(m, hdr_lens, RTE_PTYPE_ALL_MASK);
 		if (hns3_parse_tunneling_params(txq, tx_desc_id, m->ol_flags,
-						hdr_lens))
+						hdr_lens)) {
+			txq->unsupported_tunnel_pkt_cnt++;
 			return -EINVAL;
+		}
 	}
 	/* Enable checksum offloading */
 	if (m->ol_flags & HNS3_TX_CKSUM_OFFLOAD_MASK)
@@ -2467,13 +2475,18 @@ hns3_check_non_tso_pkt(uint16_t nb_buf, struct rte_mbuf **m_seg,
 	 * If packet length is greater than HNS3_MAX_FRAME_LEN
 	 * driver support, the packet will be ignored.
 	 */
-	if (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN))
+	if (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN)) {
+		txq->over_length_pkt_cnt++;
 		return -EINVAL;
+	}
 
 	if (unlikely(nb_buf > HNS3_MAX_NON_TSO_BD_PER_PKT)) {
+		txq->exceed_limit_bd_pkt_cnt++;
 		ret = hns3_reassemble_tx_pkts(txq, tx_pkt, &new_pkt);
-		if (ret)
+		if (ret) {
+			txq->exceed_limit_bd_reassem_fail++;
 			return ret;
+		}
 		*m_seg = new_pkt;
 	}
 
@@ -2511,6 +2524,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		nb_buf = tx_pkt->nb_segs;
 
 		if (nb_buf > txq->tx_bd_ready) {
+			txq->queue_full_cnt++;
 			if (nb_tx == 0)
 				return 0;
 
@@ -2528,8 +2542,10 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			add_len = HNS3_MIN_PKT_SIZE -
 					 rte_pktmbuf_pkt_len(tx_pkt);
 			appended = rte_pktmbuf_append(tx_pkt, add_len);
-			if (appended == NULL)
+			if (appended == NULL) {
+				txq->pkt_padding_fail_cnt++;
 				break;
+			}
 
 			memset(appended, 0, add_len);
 		}
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index 1fd1afd1d..ee4514290 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -278,6 +278,54 @@ struct hns3_tx_queue {
 
 	bool tx_deferred_start; /* don't start this queue in dev start */
 	bool configured;        /* indicate if tx queue has been configured */
+
+	/*
+	 * The following items are used for the abnormal errors statistics in
+	 * the Tx datapath. When upper level application calls the
+	 * rte_eth_tx_burst API function to send multiple packets at a time with
+	 * burst mode based on hns3 network engine, there are some abnormal
+	 * conditions that cause the driver to fail to operate the hardware to
+	 * send packets correctly.
+	 * Note: When using burst mode to call the rte_eth_tx_burst API function
+	 * to send multiple packets at a time. When the first abnormal error is
+	 * detected, add one to the relevant error statistics item, and then
+	 * exit the loop of sending multiple packets of the function. That is to
+	 * say, even if there are multiple packets in which abnormal errors may
+	 * be detected in the burst, the relevant error statistics in the driver
+	 * will only be increased by one.
+	 * The detail description of the Tx abnormal errors statistic items as
+	 * below:
+	 *  - over_length_pkt_cnt
+	 *     Total number of greater than HNS3_MAX_FRAME_LEN the driver
+	 *     supported.
+	 *
+	 * - exceed_limit_bd_pkt_cnt
+	 *     Total number of exceeding the hardware limited bd which process
+	 *     a packet needed bd numbers.
+	 *
+	 * - exceed_limit_bd_reassem_fail
+	 *     Total number of exceeding the hardware limited bd fail which
+	 *     process a packet needed bd numbers and reassemble fail.
+	 *
+	 * - unsupported_tunnel_pkt_cnt
+	 *     Total number of unsupported tunnel packet. The unsupported tunnel
+	 *     type: vxlan_gpe, gtp, ipip and MPLSINUDP, MPLSINUDP is a packet
+	 *     with MPLS-in-UDP RFC 7510 header.
+	 *
+	 * - queue_full_cnt
+	 *     Total count which the available bd numbers in current bd queue is
+	 *     less than the bd numbers with the pkt process needed.
+	 *
+	 * - pkt_padding_fail_cnt
+	 *     Total count which the packet length is less than minimum packet
+	 *     size HNS3_MIN_PKT_SIZE and fail to be appended with 0.
+	 */
+	uint64_t over_length_pkt_cnt;
+	uint64_t exceed_limit_bd_pkt_cnt;
+	uint64_t exceed_limit_bd_reassem_fail;
+	uint64_t unsupported_tunnel_pkt_cnt;
+	uint64_t queue_full_cnt;
+	uint64_t pkt_padding_fail_cnt;
 };
 
 struct hns3_queue_info {
diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c
index e03ffbbd6..d2467a484 100644
--- a/drivers/net/hns3/hns3_stats.c
+++ b/drivers/net/hns3/hns3_stats.c
@@ -234,6 +234,22 @@ static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = {
 		HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(ol4_csum_erros)}
 };
 
+/* The statistic of the Tx errors */
+static const struct hns3_xstats_name_offset hns3_tx_errors_strings[] = {
+	{"TX_OVER_LENGTH_PKT_CNT",
+		HNS3_TX_ERROR_STATS_FIELD_OFFSET(over_length_pkt_cnt)},
+	{"TX_EXCEED_LIMITED_BD_PKT_CNT",
+		HNS3_TX_ERROR_STATS_FIELD_OFFSET(exceed_limit_bd_pkt_cnt)},
+	{"TX_EXCEED_LIMITED_BD_PKT_REASSEMBLE_FAIL_CNT",
+		HNS3_TX_ERROR_STATS_FIELD_OFFSET(exceed_limit_bd_reassem_fail)},
+	{"TX_UNSUPPORTED_TUNNEL_PKT_CNT",
+		HNS3_TX_ERROR_STATS_FIELD_OFFSET(unsupported_tunnel_pkt_cnt)},
+	{"TX_QUEUE_FULL_CNT",
+		HNS3_TX_ERROR_STATS_FIELD_OFFSET(queue_full_cnt)},
+	{"TX_SHORT_PKT_PAD_FAIL_CNT",
+		HNS3_TX_ERROR_STATS_FIELD_OFFSET(pkt_padding_fail_cnt)}
+};
+
 /* The statistic of rx queue */
 static const struct hns3_xstats_name_offset hns3_rx_queue_strings[] = {
 	{"RX_QUEUE_FBD", HNS3_RING_RX_FBDNUM_REG}
@@ -256,6 +272,9 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
 #define HNS3_NUM_RX_BD_ERROR_XSTATS (sizeof(hns3_rx_bd_error_strings) / \
 	sizeof(hns3_rx_bd_error_strings[0]))
 
+#define HNS3_NUM_TX_ERRORS_XSTATS (sizeof(hns3_tx_errors_strings) / \
+	sizeof(hns3_tx_errors_strings[0]))
+
 #define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \
 	sizeof(hns3_rx_queue_strings[0]))
 
@@ -491,6 +510,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev)
 	struct hns3_tqp_stats *stats = &hw->tqp_stats;
 	struct hns3_cmd_desc desc_reset;
 	struct hns3_rx_queue *rxq;
+	struct hns3_tx_queue *txq;
 	uint16_t i;
 	int ret;
 
@@ -522,7 +542,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev)
 		}
 	}
 
-	/* Clear Rx BD and Tx error stats */
+	/* Clear the Rx BD errors stats */
 	for (i = 0; i != eth_dev->data->nb_rx_queues; ++i) {
 		rxq = eth_dev->data->rx_queues[i];
 		if (rxq) {
@@ -535,6 +555,19 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev)
 		}
 	}
 
+	/* Clear the Tx errors stats */
+	for (i = 0; i != eth_dev->data->nb_tx_queues; ++i) {
+		txq = eth_dev->data->tx_queues[i];
+		if (txq) {
+			txq->over_length_pkt_cnt = 0;
+			txq->exceed_limit_bd_pkt_cnt = 0;
+			txq->exceed_limit_bd_reassem_fail = 0;
+			txq->unsupported_tunnel_pkt_cnt = 0;
+			txq->queue_full_cnt = 0;
+			txq->pkt_padding_fail_cnt = 0;
+		}
+	}
+
 	memset(stats, 0, sizeof(struct hns3_tqp_stats));
 
 	return 0;
@@ -565,15 +598,51 @@ hns3_xstats_calc_num(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
 	int bderr_stats = dev->data->nb_rx_queues * HNS3_NUM_RX_BD_ERROR_XSTATS;
+	int tx_err_stats = dev->data->nb_tx_queues * HNS3_NUM_TX_ERRORS_XSTATS;
 	int rx_queue_stats = dev->data->nb_rx_queues * HNS3_NUM_RX_QUEUE_STATS;
 	int tx_queue_stats = dev->data->nb_tx_queues * HNS3_NUM_TX_QUEUE_STATS;
 
 	if (hns->is_vf)
-		return bderr_stats + rx_queue_stats + tx_queue_stats +
-			HNS3_NUM_RESET_XSTATS;
+		return bderr_stats + tx_err_stats + rx_queue_stats +
+		       tx_queue_stats + HNS3_NUM_RESET_XSTATS;
 	else
-		return bderr_stats + rx_queue_stats + tx_queue_stats +
-			HNS3_FIX_NUM_STATS;
+		return bderr_stats + tx_err_stats + rx_queue_stats +
+		       tx_queue_stats + HNS3_FIX_NUM_STATS;
+}
+
+static void
+hns3_get_queue_stats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+		     int *count)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	uint32_t reg_offset;
+	uint16_t i, j;
+
+	/* Get rx queue stats */
+	for (j = 0; j < dev->data->nb_rx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
+			reg_offset = HNS3_TQP_REG_OFFSET +
+					HNS3_TQP_REG_SIZE * j;
+			xstats[*count].value = hns3_read_dev(hw,
+				reg_offset + hns3_rx_queue_strings[i].offset);
+			xstats[*count].id = *count;
+			(*count)++;
+		}
+	}
+
+	/* Get tx queue stats */
+	for (j = 0; j < dev->data->nb_tx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
+			reg_offset = HNS3_TQP_REG_OFFSET +
+					HNS3_TQP_REG_SIZE * j;
+			xstats[*count].value = hns3_read_dev(hw,
+				reg_offset + hns3_tx_queue_strings[i].offset);
+			xstats[*count].id = *count;
+			(*count)++;
+		}
+	}
+
 }
 
 /*
@@ -599,7 +668,7 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	struct hns3_mac_stats *mac_stats = &hw->mac_stats;
 	struct hns3_reset_stats *reset_stats = &hw->reset.stats;
 	struct hns3_rx_queue *rxq;
-	uint32_t reg_offset;
+	struct hns3_tx_queue *txq;
 	uint16_t i, j;
 	char *addr;
 	int count;
@@ -658,30 +727,18 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 		}
 	}
 
-	/* Get rx queue stats */
-	for (j = 0; j < dev->data->nb_rx_queues; j++) {
-		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
-			reg_offset = HNS3_TQP_REG_OFFSET +
-					HNS3_TQP_REG_SIZE * j;
-			xstats[count].value = hns3_read_dev(hw,
-				reg_offset + hns3_rx_queue_strings[i].offset);
-			xstats[count].id = count;
-			count++;
-		}
-	}
-
-	/* Get tx queue stats */
+	/* Get the Tx errors stats */
 	for (j = 0; j < dev->data->nb_tx_queues; j++) {
-		for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) {
-			reg_offset = HNS3_TQP_REG_OFFSET +
-					HNS3_TQP_REG_SIZE * j;
-			xstats[count].value = hns3_read_dev(hw,
-				reg_offset + hns3_tx_queue_strings[i].offset);
+		for (i = 0; i < HNS3_NUM_TX_ERRORS_XSTATS; i++) {
+			txq = dev->data->tx_queues[j];
+			addr = (char *)txq + hns3_tx_errors_strings[i].offset;
+			xstats[count].value = *(uint64_t *)addr;
 			xstats[count].id = count;
 			count++;
 		}
 	}
 
+	hns3_get_queue_stats(dev, xstats, &count);
 	return count;
 }
 
@@ -756,6 +813,16 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
 		}
 	}
 
+	for (j = 0; j < dev->data->nb_tx_queues; j++) {
+		for (i = 0; i < HNS3_NUM_TX_ERRORS_XSTATS; i++) {
+			snprintf(xstats_names[count].name,
+				 sizeof(xstats_names[count].name),
+				 "tx_q%u%s", j,
+				 hns3_tx_errors_strings[i].name);
+			count++;
+		}
+	}
+
 	for (j = 0; j < dev->data->nb_rx_queues; j++) {
 		for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) {
 			snprintf(xstats_names[count].name,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 11/24] net/hns3: get PCI revision ID
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (9 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 10/24] net/hns3: get Tx abnormal errors " Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 12/24] net/hns3: check TSO segment size during Tx Wei Hu (Xavier)
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit 837740cfa37a4641b6e3fc2d92c6572fe3c9911f ]

The hns3 network engine is built-in multiple SoCs, such as kunpeng 920,
kunpeng 930, etc. The PCI revision id is 0x21 in kunpeng 920, and the PCI
revision id is 0x30 in kunpeng 930.

This patch gets PCI revision to identify different version of hardware
network engine.

Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 12 ++++++++++++
 drivers/net/hns3/hns3_ethdev.h    |  5 +++++
 drivers/net/hns3/hns3_ethdev_vf.c | 13 +++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 0bad55030..fcd47ef9a 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -5392,9 +5392,21 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint16_t device_id = pci_dev->id.device_id;
+	uint8_t revision;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
+
+	/* 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;
+
 	eth_dev->process_private = (struct hns3_process_private *)
 	    rte_zmalloc_socket("hns3_filter_list",
 			       sizeof(struct hns3_process_private),
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index df06ba3b0..ba06ed103 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -26,6 +26,10 @@
 #define HNS3_DEV_ID_100G_VF			0xA22E
 #define HNS3_DEV_ID_100G_RDMA_PFC_VF		0xA22F
 
+/* PCI Config offsets */
+#define HNS3_PCI_REVISION_ID			0x08
+#define HNS3_PCI_REVISION_ID_LEN		1
+
 #define HNS3_UC_MACADDR_NUM		128
 #define HNS3_VF_UC_MACADDR_NUM		48
 #define HNS3_MC_MACADDR_NUM		128
@@ -351,6 +355,7 @@ struct hns3_reset_data {
 struct hns3_hw {
 	struct rte_eth_dev_data *data;
 	void *io_base;
+	uint8_t revision;           /* PCI revision, low byte of class word */
 	struct hns3_cmq cmq;
 	struct hns3_mbx_resp_status mbx_resp; /* mailbox response */
 	struct hns3_mbx_arq_ring arq;         /* mailbox async rx queue */
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index d503d5011..99e09ec45 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -2392,12 +2392,25 @@ static const struct hns3_reset_ops hns3vf_reset_ops = {
 static int
 hns3vf_dev_init(struct rte_eth_dev *eth_dev)
 {
+	struct rte_device *dev = eth_dev->device;
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev);
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	uint8_t revision;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
+	/* 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;
+
 	eth_dev->process_private = (struct hns3_process_private *)
 	    rte_zmalloc_socket("hns3_filter_list",
 			       sizeof(struct hns3_process_private),
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 12/24] net/hns3: check TSO segment size during Tx
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (10 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 11/24] net/hns3: get PCI revision ID Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 13/24] net/hns3: support symmetric RSS Wei Hu (Xavier)
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Hongbo Zheng <zhenghongbo3@huawei.com>

[ upstream commit b68259f775b749ae860dfa4e170dd01774bf30d7 ]

Base on hns3 network engine, when the rte_eth_tx_burst API is called
by Upper Level Process, if PKT_TX_TCP_SEG flag is set and tso_segsz
is 0 in the input parameter structure rte_mbuf, hns3 PMD driver will
process this packet as an non-TSO packet, otherwise hardware will enter
an abnormal state.

Fixes: 6dca716c9e1d ("net/hns3: support TSO")
Cc: stable@dpdk.org

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_rxtx.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 972dc7101..db07fc459 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1902,6 +1902,12 @@ hns3_tso_proc_tunnel(struct hns3_desc *desc, uint64_t ol_flags,
 	return 0;
 }
 
+static inline bool
+hns3_pkt_is_tso(struct rte_mbuf *m)
+{
+	return (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG);
+}
+
 static void
 hns3_set_tso(struct hns3_desc *desc,
 	     uint64_t ol_flags, struct rte_mbuf *rxm)
@@ -1910,7 +1916,7 @@ hns3_set_tso(struct hns3_desc *desc,
 	uint32_t tmp;
 	uint8_t l2_len = rxm->l2_len;
 
-	if (!(ol_flags & PKT_TX_TCP_SEG))
+	if (!hns3_pkt_is_tso(rxm))
 		return;
 
 	if (hns3_tso_proc_tunnel(desc, ol_flags, rxm, &l2_len))
@@ -2359,12 +2365,6 @@ hns3_outer_header_cksum_prepare(struct rte_mbuf *m)
 	}
 }
 
-static inline bool
-hns3_pkt_is_tso(struct rte_mbuf *m)
-{
-	return (m->tso_segsz != 0 && m->ol_flags & PKT_TX_TCP_SEG);
-}
-
 static int
 hns3_check_tso_pkt_valid(struct rte_mbuf *m)
 {
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 13/24] net/hns3: support symmetric RSS
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (11 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 12/24] net/hns3: check TSO segment size during Tx Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 14/24] net/hns3: support LRO Wei Hu (Xavier)
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit 78b37190e0df294ae38ced3e9b5880b825c00daf ]

This patch adds support of symmetric algorithm of RSS.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_flow.c | 12 +++++++-----
 drivers/net/hns3/hns3_rss.c  | 27 +++++++++++++++++----------
 drivers/net/hns3/hns3_rss.h  |  6 +++---
 3 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c
index 0301d6b16..214ac63ab 100644
--- a/drivers/net/hns3/hns3_flow.c
+++ b/drivers/net/hns3/hns3_flow.c
@@ -1287,6 +1287,7 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev,
 	case RTE_ETH_HASH_FUNCTION_DEFAULT:
 	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
 	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
+	case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
 		break;
 	default:
 		return rte_flow_error_set(error, ENOTSUP,
@@ -1365,6 +1366,9 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func,
 	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
 		*hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
 		break;
+	case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
+		*hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
+		break;
 	default:
 		hns3_err(hw, "Invalid RSS algorithm configuration(%u)",
 			 algo_func);
@@ -1378,9 +1382,6 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func,
 static int
 hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
 {
-	uint8_t hash_algo =
-		(hw->rss_info.conf.func == RTE_ETH_HASH_FUNCTION_TOEPLITZ ?
-		 HNS3_RSS_HASH_ALGO_TOEPLITZ : HNS3_RSS_HASH_ALGO_SIMPLE);
 	struct hns3_rss_tuple_cfg *tuple;
 	int ret;
 
@@ -1388,11 +1389,12 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config)
 	hns3_parse_rss_key(hw, rss_config);
 
 	/* Parse hash algorithm */
-	ret = hns3_parse_rss_algorithm(hw, &rss_config->func, &hash_algo);
+	ret = hns3_parse_rss_algorithm(hw, &rss_config->func,
+				       &hw->rss_info.hash_algo);
 	if (ret)
 		return ret;
 
-	ret = hns3_set_rss_algo_key(hw, hash_algo, rss_config->key);
+	ret = hns3_set_rss_algo_key(hw, rss_config->key);
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index a6cab29c9..247bd7d3f 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -28,7 +28,7 @@ static const uint8_t hns3_hash_key[] = {
  * Used to set algorithm, key_offset and hash key of rss.
  */
 int
-hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, const uint8_t *key)
+hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key)
 {
 #define HNS3_KEY_OFFSET_MAX	3
 #define HNS3_SET_HASH_KEY_BYTE_FOUR	2
@@ -51,7 +51,8 @@ hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, const uint8_t *key)
 		hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG,
 					  false);
 
-		req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK);
+		req->hash_config |=
+			(hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK);
 		req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B);
 
 		if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR)
@@ -256,7 +257,6 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 	struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets;
 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
 	uint8_t key_len = rss_conf->rss_key_len;
-	uint8_t algo;
 	uint64_t rss_hf = rss_conf->rss_hf;
 	uint8_t *key = rss_conf->rss_key;
 	int ret;
@@ -292,9 +292,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 			ret = -EINVAL;
 			goto conf_err;
 		}
-		algo = rss_cfg->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR ?
-			HNS3_RSS_HASH_ALGO_SIMPLE : HNS3_RSS_HASH_ALGO_TOEPLITZ;
-		ret = hns3_set_rss_algo_key(hw, algo, key);
+		ret = hns3_set_rss_algo_key(hw, key);
 		if (ret)
 			goto conf_err;
 	}
@@ -529,20 +527,29 @@ hns3_config_rss(struct hns3_adapter *hns)
 {
 	struct hns3_hw *hw = &hns->hw;
 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
-	uint8_t hash_algo =
-		(hw->rss_info.conf.func == RTE_ETH_HASH_FUNCTION_TOEPLITZ ?
-		 HNS3_RSS_HASH_ALGO_TOEPLITZ : HNS3_RSS_HASH_ALGO_SIMPLE);
 	uint8_t *hash_key = rss_cfg->key;
 	int ret, ret1;
 
 	enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode;
 
+	switch (hw->rss_info.conf.func) {
+	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
+		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE;
+		break;
+	case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ:
+		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP;
+		break;
+	default:
+		hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ;
+		break;
+	}
+
 	/* When RSS is off, redirect the packet queue 0 */
 	if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) == 0)
 		hns3_rss_uninit(hns);
 
 	/* Configure RSS hash algorithm and hash key offset */
-	ret = hns3_set_rss_algo_key(hw, hash_algo, hash_key);
+	ret = hns3_set_rss_algo_key(hw, hash_key);
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h
index 8f065af0a..24638dfa6 100644
--- a/drivers/net/hns3/hns3_rss.h
+++ b/drivers/net/hns3/hns3_rss.h
@@ -27,7 +27,7 @@
 
 #define HNS3_RSS_HASH_ALGO_TOEPLITZ	0
 #define HNS3_RSS_HASH_ALGO_SIMPLE	1
-#define HNS3_RSS_HASH_ALGO_SYMMETRIC	2
+#define HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP	2
 #define HNS3_RSS_HASH_ALGO_MASK		0xf
 
 #define HNS3_RSS_INPUT_TUPLE_OTHER	GENMASK(3, 0)
@@ -50,6 +50,7 @@ struct hns3_rss_tuple_cfg {
 struct hns3_rss_conf {
 	/* RSS parameters :algorithm, flow_types,  key, queue */
 	struct rte_flow_action_rss conf;
+	uint8_t hash_algo; /* hash function type definited by hardware */
 	uint8_t key[HNS3_RSS_KEY_SIZE];  /* Hash key */
 	struct hns3_rss_tuple_cfg rss_tuple_sets;
 	uint8_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; /* Shadow table */
@@ -119,8 +120,7 @@ void hns3_rss_uninit(struct hns3_adapter *hns);
 int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw,
 				 struct hns3_rss_tuple_cfg *tuple,
 				 uint64_t rss_hf);
-int hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo,
-			  const uint8_t *key);
+int hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key);
 int hns3_restore_rss_filter(struct rte_eth_dev *dev);
 
 #endif /* _HNS3_RSS_H_ */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 14/24] net/hns3: support LRO
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (12 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 13/24] net/hns3: support symmetric RSS Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 15/24] net/hns3: decrease non-nearby memory access in Rx Wei Hu (Xavier)
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit 1f295c40da3de1722ed6f6f0bc0853966b6ff4ae ]

This patch adds support of LRO offload for hns3 PMD driver.

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 doc/guides/nics/features/hns3.ini    |  1 +
 doc/guides/nics/features/hns3_vf.ini |  1 +
 doc/guides/nics/hns3.rst             |  1 +
 drivers/net/hns3/hns3_ethdev.c       | 35 ++++++++++------------
 drivers/net/hns3/hns3_ethdev.h       |  2 +-
 drivers/net/hns3/hns3_ethdev_vf.c    | 16 +++++++++-
 drivers/net/hns3/hns3_rxtx.c         | 45 ++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_rxtx.h         |  4 ++-
 8 files changed, 82 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini
index c3a8544bc..66abda7cb 100644
--- a/doc/guides/nics/features/hns3.ini
+++ b/doc/guides/nics/features/hns3.ini
@@ -9,6 +9,7 @@ Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
 TSO                  = Y
+LRO                  = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini
index 80773ac90..71d246afc 100644
--- a/doc/guides/nics/features/hns3_vf.ini
+++ b/doc/guides/nics/features/hns3_vf.ini
@@ -9,6 +9,7 @@ Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
 TSO                  = Y
+LRO                  = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 05dbe4174..ae3c5f63f 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -18,6 +18,7 @@ Features of the HNS3 PMD are:
 - Packet type information
 - Checksum offload
 - TSO offload
+- LRO offload
 - Promiscuous mode
 - Multicast mode
 - Port hardware statistics
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index fcd47ef9a..fc5db2aaf 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -1096,25 +1096,6 @@ hns3_config_tso(struct hns3_hw *hw, unsigned int tso_mss_min,
 	return hns3_cmd_send(hw, &desc, 1);
 }
 
-int
-hns3_config_gro(struct hns3_hw *hw, bool en)
-{
-	struct hns3_cfg_gro_status_cmd *req;
-	struct hns3_cmd_desc desc;
-	int ret;
-
-	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GRO_GENERIC_CONFIG, false);
-	req = (struct hns3_cfg_gro_status_cmd *)desc.data;
-
-	req->gro_en = rte_cpu_to_le_16(en ? 1 : 0);
-
-	ret = hns3_cmd_send(hw, &desc, 1);
-	if (ret)
-		hns3_err(hw, "GRO hardware config cmd failed, ret = %d", ret);
-
-	return ret;
-}
-
 static int
 hns3_set_umv_space(struct hns3_hw *hw, uint16_t space_size,
 		   uint16_t *allocated_size, bool is_alloc)
@@ -2281,6 +2262,7 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
 	struct rte_eth_rss_conf rss_conf;
 	uint16_t mtu;
+	bool gro_en;
 	int ret;
 
 	/*
@@ -2347,6 +2329,12 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	if (ret)
 		goto cfg_err;
 
+	/* config hardware GRO */
+	gro_en = conf->rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false;
+	ret = hns3_config_gro(hw, gro_en);
+	if (ret)
+		goto cfg_err;
+
 	hw->adapter_state = HNS3_NIC_CONFIGURED;
 
 	return 0;
@@ -2456,6 +2444,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 	info->min_rx_bufsize = HNS3_MIN_BD_BUF_SIZE;
 	info->max_mac_addrs = HNS3_UC_MACADDR_NUM;
 	info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD;
+	info->max_lro_pkt_size = HNS3_MAX_LRO_SIZE;
 	info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM |
 				 DEV_RX_OFFLOAD_TCP_CKSUM |
 				 DEV_RX_OFFLOAD_UDP_CKSUM |
@@ -2467,7 +2456,8 @@ 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_RSS_HASH |
+				 DEV_RX_OFFLOAD_TCP_LRO);
 	info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 	info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
 				 DEV_TX_OFFLOAD_IPV4_CKSUM |
@@ -4414,6 +4404,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
 
 	hns3_enable_hw_error_intr(hns, false);
 	hns3_rss_uninit(hns);
+	(void)hns3_config_gro(hw, false);
 	hns3_promisc_uninit(hw);
 	hns3_fdir_filter_uninit(hns);
 	hns3_uninit_umv_space(hw);
@@ -5249,6 +5240,10 @@ hns3_restore_conf(struct hns3_adapter *hns)
 	if (ret)
 		goto err_promisc;
 
+	ret = hns3_restore_gro_conf(hw);
+	if (ret)
+		goto err_promisc;
+
 	if (hns->hw.adapter_state == HNS3_NIC_STARTED) {
 		ret = hns3_do_start(hns, false);
 		if (ret)
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index ba06ed103..c98e810fb 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -44,6 +44,7 @@
 #define HNS3_MAX_BD_PAYLEN		(1024 * 1024 - 1)
 #define HNS3_MAX_TSO_HDR_SIZE		512
 #define HNS3_MAX_TSO_HDR_BD_NUM		3
+#define HNS3_MAX_LRO_SIZE		64512
 
 #define HNS3_ETH_OVERHEAD \
 	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + HNS3_VLAN_TAG_SIZE * 2)
@@ -651,7 +652,6 @@ hns3_test_and_clear_bit(unsigned int nr, volatile uint64_t *addr)
 }
 
 int hns3_buffer_alloc(struct hns3_hw *hw);
-int hns3_config_gro(struct hns3_hw *hw, bool en);
 int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
 			 enum rte_filter_type filter_type,
 			 enum rte_filter_op filter_op, void *arg);
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 99e09ec45..0fff7a42b 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -765,6 +765,7 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
 	struct rte_eth_rss_conf rss_conf;
 	uint16_t mtu;
+	bool gro_en;
 	int ret;
 
 	/*
@@ -825,6 +826,12 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
 	if (ret)
 		goto cfg_err;
 
+	/* config hardware GRO */
+	gro_en = conf->rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false;
+	ret = hns3_config_gro(hw, gro_en);
+	if (ret)
+		goto cfg_err;
+
 	hw->adapter_state = HNS3_NIC_CONFIGURED;
 	return 0;
 
@@ -906,6 +913,7 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 	info->min_rx_bufsize = HNS3_MIN_BD_BUF_SIZE;
 	info->max_mac_addrs = HNS3_VF_UC_MACADDR_NUM;
 	info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD;
+	info->max_lro_pkt_size = HNS3_MAX_LRO_SIZE;
 
 	info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM |
 				 DEV_RX_OFFLOAD_UDP_CKSUM |
@@ -918,7 +926,8 @@ 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_RSS_HASH |
+				 DEV_RX_OFFLOAD_TCP_LRO);
 	info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 	info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
 				 DEV_TX_OFFLOAD_IPV4_CKSUM |
@@ -1654,6 +1663,7 @@ hns3vf_uninit_vf(struct rte_eth_dev *eth_dev)
 	PMD_INIT_FUNC_TRACE();
 
 	hns3_rss_uninit(hns);
+	(void)hns3_config_gro(hw, false);
 	(void)hns3vf_set_alive(hw, false);
 	(void)hns3vf_set_promisc_mode(hw, false, false, false);
 	hns3vf_disable_irq0(hw);
@@ -2202,6 +2212,10 @@ hns3vf_restore_conf(struct hns3_adapter *hns)
 	if (ret)
 		goto err_vlan_table;
 
+	ret = hns3_restore_gro_conf(hw);
+	if (ret)
+		goto err_vlan_table;
+
 	if (hw->adapter_state == HNS3_NIC_STARTED) {
 		ret = hns3vf_do_start(hns, false);
 		if (ret)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index db07fc459..c332b8703 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1571,6 +1571,7 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	uint32_t bd_base_info;
 	uint32_t cksum_err;
 	uint32_t l234_info;
+	uint32_t gro_size;
 	uint32_t ol_info;
 	uint64_t dma_addr;
 	uint16_t data_len;
@@ -1717,6 +1718,13 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		}
 		rxm->next = NULL;
 
+		gro_size = hns3_get_field(bd_base_info, HNS3_RXD_GRO_SIZE_M,
+					  HNS3_RXD_GRO_SIZE_S);
+		if (gro_size != 0) {
+			first_seg->ol_flags |= PKT_RX_LRO;
+			first_seg->tso_segsz = gro_size;
+		}
+
 		ret = hns3_handle_bdinfo(rxq, first_seg, bd_base_info,
 					 l234_info, &cksum_err);
 		if (unlikely(ret))
@@ -1902,6 +1910,43 @@ hns3_tso_proc_tunnel(struct hns3_desc *desc, uint64_t ol_flags,
 	return 0;
 }
 
+int
+hns3_config_gro(struct hns3_hw *hw, bool en)
+{
+	struct hns3_cfg_gro_status_cmd *req;
+	struct hns3_cmd_desc desc;
+	int ret;
+
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GRO_GENERIC_CONFIG, false);
+	req = (struct hns3_cfg_gro_status_cmd *)desc.data;
+
+	req->gro_en = rte_cpu_to_le_16(en ? 1 : 0);
+
+	ret = hns3_cmd_send(hw, &desc, 1);
+	if (ret)
+		hns3_err(hw, "%s hardware GRO failed, ret = %d",
+			 en ? "enable" : "disable", ret);
+
+	return ret;
+}
+
+int
+hns3_restore_gro_conf(struct hns3_hw *hw)
+{
+	uint64_t offloads;
+	bool gro_en;
+	int ret;
+
+	offloads = hw->data->dev_conf.rxmode.offloads;
+	gro_en = offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false;
+	ret = hns3_config_gro(hw, gro_en);
+	if (ret)
+		hns3_err(hw, "restore hardware GRO to %s failed, ret = %d",
+			 gro_en ? "enabled" : "disabled", ret);
+
+	return ret;
+}
+
 static inline bool
 hns3_pkt_is_tso(struct rte_mbuf *m)
 {
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index ee4514290..1e80d2558 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -81,7 +81,7 @@
 #define HNS3_RXD_TSIND_M			(0x7 << HNS3_RXD_TSIND_S)
 #define HNS3_RXD_LKBK_B				15
 #define HNS3_RXD_GRO_SIZE_S			16
-#define HNS3_RXD_GRO_SIZE_M			(0x3ff << HNS3_RXD_GRO_SIZE_S)
+#define HNS3_RXD_GRO_SIZE_M			(0x3fff << HNS3_RXD_GRO_SIZE_S)
 
 #define HNS3_TXD_L3T_S				0
 #define HNS3_TXD_L3T_M				(0x3 << HNS3_TXD_L3T_S)
@@ -384,5 +384,7 @@ void hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id,
 			    uint16_t rl_value);
 int hns3_set_fake_rx_or_tx_queues(struct rte_eth_dev *dev, uint16_t nb_rx_q,
 				  uint16_t nb_tx_q);
+int hns3_config_gro(struct hns3_hw *hw, bool en);
+int hns3_restore_gro_conf(struct hns3_hw *hw);
 
 #endif /* _HNS3_RXTX_H_ */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 15/24] net/hns3: decrease non-nearby memory access in Rx
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (13 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 14/24] net/hns3: support LRO Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 16/24] net/hns3: support setting VF PVID by PF driver Wei Hu (Xavier)
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit 8c7449779c4526d27205043560a21f0e2c2f622b ]

Currently, hns3 PMD driver needs know the PVID configuration state and
do different processing in the 'rx_pkt_burst' ops implementation
function.

This patch adds a member to struct hns3_rx_queue/hns3_tx_queue of the
driver to indicate the PVID configuration status, so it isn't need
to access other data structure in the 'rx_pkt_burst' ops implementation,
to avoid performance loss because of reducing cache miss.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 21 ++++++++++++++++++-
 drivers/net/hns3/hns3_rxtx.c   | 37 ++++++++++++++++++++++++++++------
 drivers/net/hns3/hns3_rxtx.h   | 13 ++++++++++++
 3 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index fc5db2aaf..c81f3a539 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -905,6 +905,8 @@ hns3_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	bool pvid_en_state_change;
+	uint16_t pvid_state;
 	int ret;
 
 	if (pvid > RTE_ETHER_MAX_VLAN_ID) {
@@ -913,10 +915,27 @@ hns3_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on)
 		return -EINVAL;
 	}
 
+	/*
+	 * If PVID configuration state change, should refresh the PVID
+	 * configuration state in struct hns3_tx_queue/hns3_rx_queue.
+	 */
+	pvid_state = hw->port_base_vlan_cfg.state;
+	if ((on && pvid_state == HNS3_PORT_BASE_VLAN_ENABLE) ||
+	    (!on && pvid_state == HNS3_PORT_BASE_VLAN_DISABLE))
+		pvid_en_state_change = false;
+	else
+		pvid_en_state_change = true;
+
 	rte_spinlock_lock(&hw->lock);
 	ret = hns3_vlan_pvid_configure(hns, pvid, on);
 	rte_spinlock_unlock(&hw->lock);
-	return ret;
+	if (ret)
+		return ret;
+
+	if (pvid_en_state_change)
+		hns3_update_all_queues_pvid_state(hw);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index c332b8703..e2cc2f5f7 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -315,6 +315,31 @@ hns3_init_tx_queue_hw(struct hns3_tx_queue *txq)
 		       HNS3_CFG_DESC_NUM(txq->nb_tx_desc));
 }
 
+void
+hns3_update_all_queues_pvid_state(struct hns3_hw *hw)
+{
+	uint16_t nb_rx_q = hw->data->nb_rx_queues;
+	uint16_t nb_tx_q = hw->data->nb_tx_queues;
+	struct hns3_rx_queue *rxq;
+	struct hns3_tx_queue *txq;
+	int pvid_state;
+	int i;
+
+	pvid_state = hw->port_base_vlan_cfg.state;
+	for (i = 0; i < hw->cfg_max_queues; i++) {
+		if (i < nb_rx_q) {
+			rxq = hw->data->rx_queues[i];
+			if (rxq != NULL)
+				rxq->pvid_state = pvid_state;
+		}
+		if (i < nb_tx_q) {
+			txq = hw->data->tx_queues[i];
+			if (txq != NULL)
+				txq->pvid_state = pvid_state;
+		}
+	}
+}
+
 void
 hns3_enable_all_queues(struct hns3_hw *hw, bool en)
 {
@@ -1275,6 +1300,7 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
 	rxq->pkt_first_seg = NULL;
 	rxq->pkt_last_seg = NULL;
 	rxq->port_id = dev->data->port_id;
+	rxq->pvid_state = hw->port_base_vlan_cfg.state;
 	rxq->configured = true;
 	rxq->io_base = (void *)((char *)hw->io_base + HNS3_TQP_REG_OFFSET +
 				idx * HNS3_TQP_REG_SIZE);
@@ -1503,7 +1529,7 @@ hns3_rx_set_cksum_flag(struct rte_mbuf *rxm, uint64_t packet_type,
 }
 
 static inline void
-hns3_rxd_to_vlan_tci(struct rte_eth_dev *dev, struct rte_mbuf *mb,
+hns3_rxd_to_vlan_tci(struct hns3_rx_queue *rxq, struct rte_mbuf *mb,
 		     uint32_t l234_info, const struct hns3_desc *rxd)
 {
 #define HNS3_STRP_STATUS_NUM		0x4
@@ -1511,8 +1537,6 @@ hns3_rxd_to_vlan_tci(struct rte_eth_dev *dev, struct rte_mbuf *mb,
 #define HNS3_NO_STRP_VLAN_VLD		0x0
 #define HNS3_INNER_STRP_VLAN_VLD	0x1
 #define HNS3_OUTER_STRP_VLAN_VLD	0x2
-	struct hns3_adapter *hns = dev->data->dev_private;
-	struct hns3_hw *hw = &hns->hw;
 	uint32_t strip_status;
 	uint32_t report_mode;
 
@@ -1538,7 +1562,7 @@ hns3_rxd_to_vlan_tci(struct rte_eth_dev *dev, struct rte_mbuf *mb,
 	};
 	strip_status = hns3_get_field(l234_info, HNS3_RXD_STRP_TAGP_M,
 				      HNS3_RXD_STRP_TAGP_S);
-	report_mode = report_type[hw->port_base_vlan_cfg.state][strip_status];
+	report_mode = report_type[rxq->pvid_state][strip_status];
 	switch (report_mode) {
 	case HNS3_NO_STRP_VLAN_VLD:
 		mb->vlan_tci = 0;
@@ -1584,7 +1608,6 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	nb_rx = 0;
 	nb_rx_bd = 0;
 	rxq = rx_queue;
-	dev = &rte_eth_devices[rxq->port_id];
 
 	rx_id = rxq->next_to_clean;
 	rx_ring = rxq->rx_ring;
@@ -1661,6 +1684,7 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 		nmb = rte_mbuf_raw_alloc(rxq->mb_pool);
 		if (unlikely(nmb == NULL)) {
+			dev = &rte_eth_devices[rxq->port_id];
 			dev->data->rx_mbuf_alloc_failed++;
 			break;
 		}
@@ -1737,7 +1761,7 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 			hns3_rx_set_cksum_flag(first_seg,
 					       first_seg->packet_type,
 					       cksum_err);
-		hns3_rxd_to_vlan_tci(dev, first_seg, l234_info, &rxd);
+		hns3_rxd_to_vlan_tci(rxq, first_seg, l234_info, &rxd);
 
 		rx_pkts[nb_rx++] = first_seg;
 		first_seg = NULL;
@@ -1815,6 +1839,7 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
 	txq->next_to_clean = 0;
 	txq->tx_bd_ready = txq->nb_tx_desc - 1;
 	txq->port_id = dev->data->port_id;
+	txq->pvid_state = hw->port_base_vlan_cfg.state;
 	txq->configured = true;
 	txq->io_base = (void *)((char *)hw->io_base + HNS3_TQP_REG_OFFSET +
 				idx * HNS3_TQP_REG_SIZE);
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index 1e80d2558..ccd508b74 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -250,6 +250,12 @@ struct hns3_rx_queue {
 	uint16_t rx_buf_len;
 	uint16_t rx_free_thresh;
 
+	/*
+	 * port based vlan configuration state.
+	 * value range: HNS3_PORT_BASE_VLAN_DISABLE / HNS3_PORT_BASE_VLAN_ENABLE
+	 */
+	uint16_t pvid_state;
+
 	bool rx_deferred_start; /* don't start this queue in dev start */
 	bool configured;        /* indicate if rx queue has been configured */
 
@@ -276,6 +282,12 @@ struct hns3_tx_queue {
 	uint16_t next_to_use;
 	uint16_t tx_bd_ready;
 
+	/*
+	 * port based vlan configuration state.
+	 * value range: HNS3_PORT_BASE_VLAN_DISABLE / HNS3_PORT_BASE_VLAN_ENABLE
+	 */
+	uint16_t pvid_state;
+
 	bool tx_deferred_start; /* don't start this queue in dev start */
 	bool configured;        /* indicate if tx queue has been configured */
 
@@ -386,5 +398,6 @@ int hns3_set_fake_rx_or_tx_queues(struct rte_eth_dev *dev, uint16_t nb_rx_q,
 				  uint16_t nb_tx_q);
 int hns3_config_gro(struct hns3_hw *hw, bool en);
 int hns3_restore_gro_conf(struct hns3_hw *hw);
+void hns3_update_all_queues_pvid_state(struct hns3_hw *hw);
 
 #endif /* _HNS3_RXTX_H_ */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 16/24] net/hns3: support setting VF PVID by PF driver
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (14 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 15/24] net/hns3: decrease non-nearby memory access in Rx Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 17/24] net/hns3: get device capability in primary process Wei Hu (Xavier)
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit b4e4d7ac9f094587edbf10d61693b7cc1528e92f ]

This patch adds support setting VF PVID by hns3 PF kernel ethdev driver
on the host by "ip link set <eth num> vf <vf id> vlan <vlan tag>"
command.

Because of the hardware constraints, the striped VLAN tag will always in
Rx descriptors which should has been dropped when PVID is enabled and
the PVID will overwrite the outer VLAN tag in Tx descriptor. So, hns3
PMD driver need to change the processing of VLAN tags in the process of
Tx and Rx according to whether PVID is enabled.
1) If the hns3 PF kernel ethdev driver sets the PVID for VF device
   before the initialization of the related VF device, hns3 VF PMD
   driver should get the PVID state from PF driver through mailbox and
   update the related state in txq and rxq maintained by hns3 VF driver
   to change the process of Tx and Rx.
2) If the hns3 PF kernel ethdev driver sets the PVID for VF device after
   initialization of the related VF device, the PF driver will notify VF
   driver to update the PVID state. The VF driver will update the PVID
   configuration state immediately to ensure that the VLAN process in Tx
   and Rx is correct. But in the window period of this state transition,
   packets loss or packets with wrong VLAN may occur.
3) Due to hardware limitations, we only support two-layer VLAN hardware
   offload in Tx direction based on hns3 network engine, so when PVID is
   enabled, QinQ insert is no longer supported. And when PVID is
   enabled, in the following two cases:
     i) packets with more than two VLAN tags.
     ii) packets with one VLAN tag while the hardware VLAN insert is
         enabled.
   The packets will be regarded as abnormal packets and discarded by
   hardware in Tx direction. For debugging purposes, a validation check
   for these types of packets is added to the '.tx_pkt_prepare' ops
   implementation function named hns3_prep_pkts to inform users that
   these packets will be discarded.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    |  5 ++-
 drivers/net/hns3/hns3_ethdev.h    |  9 +++++
 drivers/net/hns3/hns3_ethdev_vf.c | 56 +++++++++++++++++++++++++++++--
 drivers/net/hns3/hns3_mbx.c       | 33 ++++++++++++++++++
 drivers/net/hns3/hns3_mbx.h       |  3 ++
 drivers/net/hns3/hns3_rxtx.c      | 47 ++++++++++++++++++++++++++
 6 files changed, 147 insertions(+), 6 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index c81f3a539..d3caca436 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2483,14 +2483,13 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_TX_OFFLOAD_TCP_CKSUM |
 				 DEV_TX_OFFLOAD_UDP_CKSUM |
 				 DEV_TX_OFFLOAD_SCTP_CKSUM |
-				 DEV_TX_OFFLOAD_VLAN_INSERT |
-				 DEV_TX_OFFLOAD_QINQ_INSERT |
 				 DEV_TX_OFFLOAD_MULTI_SEGS |
 				 DEV_TX_OFFLOAD_TCP_TSO |
 				 DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
 				 DEV_TX_OFFLOAD_GRE_TNL_TSO |
 				 DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
-				 info->tx_queue_offload_capa);
+				 info->tx_queue_offload_capa |
+				 hns3_txvlan_cap_get(hw));
 
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
 		.nb_max = HNS3_MAX_RING_DESC,
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index c98e810fb..acc11ef22 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -670,4 +670,13 @@ is_reset_pending(struct hns3_adapter *hns)
 	return ret;
 }
 
+static inline uint64_t
+hns3_txvlan_cap_get(struct hns3_hw *hw)
+{
+	if (hw->port_base_vlan_cfg.state)
+		return DEV_TX_OFFLOAD_VLAN_INSERT;
+	else
+		return DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT;
+}
+
 #endif /* _HNS3_ETHDEV_H_ */
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 0fff7a42b..93fd3a7d0 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -934,14 +934,13 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 				 DEV_TX_OFFLOAD_TCP_CKSUM |
 				 DEV_TX_OFFLOAD_UDP_CKSUM |
 				 DEV_TX_OFFLOAD_SCTP_CKSUM |
-				 DEV_TX_OFFLOAD_VLAN_INSERT |
-				 DEV_TX_OFFLOAD_QINQ_INSERT |
 				 DEV_TX_OFFLOAD_MULTI_SEGS |
 				 DEV_TX_OFFLOAD_TCP_TSO |
 				 DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
 				 DEV_TX_OFFLOAD_GRE_TNL_TSO |
 				 DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
-				 info->tx_queue_offload_capa);
+				 info->tx_queue_offload_capa |
+				 hns3_txvlan_cap_get(hw));
 
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
 		.nb_max = HNS3_MAX_RING_DESC,
@@ -1084,6 +1083,49 @@ hns3vf_check_tqp_info(struct hns3_hw *hw)
 
 	return 0;
 }
+static int
+hns3vf_get_port_base_vlan_filter_state(struct hns3_hw *hw)
+{
+	uint8_t resp_msg;
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_VLAN,
+				HNS3_MBX_GET_PORT_BASE_VLAN_STATE, NULL, 0,
+				true, &resp_msg, sizeof(resp_msg));
+	if (ret) {
+		if (ret == -ETIME) {
+			/*
+			 * Getting current port based VLAN state from PF driver
+			 * will not affect VF driver's basic function. Because
+			 * the VF driver relies on hns3 PF kernel ether driver,
+			 * to avoid introducing compatibility issues with older
+			 * version of PF driver, no failure will be returned
+			 * when the return value is ETIME. This return value has
+			 * the following scenarios:
+			 * 1) Firmware didn't return the results in time
+			 * 2) the result return by firmware is timeout
+			 * 3) the older version of kernel side PF driver does
+			 *    not support this mailbox message.
+			 * For scenarios 1 and 2, it is most likely that a
+			 * hardware error has occurred, or a hardware reset has
+			 * occurred. In this case, these errors will be caught
+			 * by other functions.
+			 */
+			PMD_INIT_LOG(WARNING,
+				"failed to get PVID state for timeout, maybe "
+				"kernel side PF driver doesn't support this "
+				"mailbox message, or firmware didn't respond.");
+			resp_msg = HNS3_PORT_BASE_VLAN_DISABLE;
+		} else {
+			PMD_INIT_LOG(ERR, "failed to get port based VLAN state,"
+				" ret = %d", ret);
+			return ret;
+		}
+	}
+	hw->port_base_vlan_cfg.state = resp_msg ?
+		HNS3_PORT_BASE_VLAN_ENABLE : HNS3_PORT_BASE_VLAN_DISABLE;
+	return 0;
+}
 
 static int
 hns3vf_get_queue_info(struct hns3_hw *hw)
@@ -1186,6 +1228,10 @@ hns3vf_get_configuration(struct hns3_hw *hw)
 	if (ret)
 		return ret;
 
+	ret = hns3vf_get_port_base_vlan_filter_state(hw);
+	if (ret)
+		return ret;
+
 	/* Get tc configuration from PF */
 	return hns3vf_get_tc_info(hw);
 }
@@ -2208,6 +2254,10 @@ hns3vf_restore_conf(struct hns3_adapter *hns)
 	if (ret)
 		goto err_vlan_table;
 
+	ret = hns3vf_get_port_base_vlan_filter_state(hw);
+	if (ret)
+		goto err_vlan_table;
+
 	ret = hns3vf_restore_rx_interrupt(hw);
 	if (ret)
 		goto err_vlan_table;
diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c
index 34c8c688f..2510582c0 100644
--- a/drivers/net/hns3/hns3_mbx.c
+++ b/drivers/net/hns3/hns3_mbx.c
@@ -23,6 +23,7 @@
 #include "hns3_regs.h"
 #include "hns3_logs.h"
 #include "hns3_intr.h"
+#include "hns3_rxtx.h"
 
 #define HNS3_CMD_CODE_OFFSET		2
 
@@ -326,6 +327,30 @@ hns3_handle_link_change_event(struct hns3_hw *hw,
 	hns3_update_link_status(hw);
 }
 
+static void
+hns3_update_port_base_vlan_info(struct hns3_hw *hw,
+				struct hns3_mbx_pf_to_vf_cmd *req)
+{
+#define PVID_STATE_OFFSET	1
+	uint16_t new_pvid_state = req->msg[PVID_STATE_OFFSET] ?
+		HNS3_PORT_BASE_VLAN_ENABLE : HNS3_PORT_BASE_VLAN_DISABLE;
+	/*
+	 * Currently, hardware doesn't support more than two layers VLAN offload
+	 * based on hns3 network engine, which would cause packets loss or wrong
+	 * packets for these types of packets. If the hns3 PF kernel ethdev
+	 * driver sets the PVID for VF device after initialization of the
+	 * related VF device, the PF driver will notify VF driver to update the
+	 * PVID configuration state. The VF driver will update the PVID
+	 * configuration state immediately to ensure that the VLAN process in Tx
+	 * and Rx is correct. But in the window period of this state transition,
+	 * packets loss or packets with wrong VLAN may occur.
+	 */
+	if (hw->port_base_vlan_cfg.state != new_pvid_state) {
+		hw->port_base_vlan_cfg.state = new_pvid_state;
+		hns3_update_all_queues_pvid_state(hw);
+	}
+}
+
 static void
 hns3_handle_promisc_info(struct hns3_hw *hw, uint16_t promisc_en)
 {
@@ -399,6 +424,14 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 		case HNS3_MBX_PUSH_LINK_STATUS:
 			hns3_handle_link_change_event(hw, req);
 			break;
+		case HNS3_MBX_PUSH_VLAN_INFO:
+			/*
+			 * When the PVID configuration status of VF device is
+			 * changed by the hns3 PF kernel driver, VF driver will
+			 * receive this mailbox message from PF driver.
+			 */
+			hns3_update_port_base_vlan_info(hw, req);
+			break;
 		case HNS3_MBX_PUSH_PROMISC_INFO:
 			/*
 			 * When the trust status of VF device changed by the
diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h
index d6d70f686..7f7ade13f 100644
--- a/drivers/net/hns3/hns3_mbx.h
+++ b/drivers/net/hns3/hns3_mbx.h
@@ -40,6 +40,8 @@ enum HNS3_MBX_OPCODE {
 	HNS3_MBX_SET_MTU,               /* (VF -> PF) set mtu */
 	HNS3_MBX_GET_QID_IN_PF,         /* (VF -> PF) get queue id in pf */
 
+	HNS3_MBX_PUSH_VLAN_INFO = 34,   /* (PF -> VF) push port base vlan */
+
 	HNS3_MBX_PUSH_PROMISC_INFO = 36, /* (PF -> VF) push vf promisc info */
 
 	HNS3_MBX_HANDLE_VF_TBL = 38,    /* (VF -> PF) store/clear hw cfg tbl */
@@ -62,6 +64,7 @@ enum hns3_mbx_vlan_cfg_subcode {
 	HNS3_MBX_VLAN_FILTER = 0,               /* set vlan filter */
 	HNS3_MBX_VLAN_TX_OFF_CFG,               /* set tx side vlan offload */
 	HNS3_MBX_VLAN_RX_OFF_CFG,               /* set rx side vlan offload */
+	HNS3_MBX_GET_PORT_BASE_VLAN_STATE = 4,  /* get port based vlan state */
 };
 
 enum hns3_mbx_tbl_cfg_subcode {
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index e2cc2f5f7..931d89a1a 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2474,6 +2474,48 @@ hns3_check_tso_pkt_valid(struct rte_mbuf *m)
 	return 0;
 }
 
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+static inline int
+hns3_vld_vlan_chk(struct hns3_tx_queue *txq, struct rte_mbuf *m)
+{
+	struct rte_ether_hdr *eh;
+	struct rte_vlan_hdr *vh;
+
+	if (!txq->pvid_state)
+		return 0;
+
+	/*
+	 * Due to hardware limitations, we only support two-layer VLAN hardware
+	 * offload in Tx direction based on hns3 network engine, so when PVID is
+	 * enabled, QinQ insert is no longer supported.
+	 * And when PVID is enabled, in the following two cases:
+	 *  i) packets with more than two VLAN tags.
+	 *  ii) packets with one VLAN tag while the hardware VLAN insert is
+	 *      enabled.
+	 * The packets will be regarded as abnormal packets and discarded by
+	 * hardware in Tx direction. For debugging purposes, a validation check
+	 * for these types of packets is added to the '.tx_pkt_prepare' ops
+	 * implementation function named hns3_prep_pkts to inform users that
+	 * these packets will be discarded.
+	 */
+	if (m->ol_flags & PKT_TX_QINQ_PKT)
+		return -EINVAL;
+
+	eh = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
+	if (eh->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN)) {
+		if (m->ol_flags & PKT_TX_VLAN_PKT)
+			return -EINVAL;
+
+		/* Ensure the incoming packet is not a QinQ packet */
+		vh = (struct rte_vlan_hdr *)(eh + 1);
+		if (vh->eth_proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
 uint16_t
 hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
 	       uint16_t nb_pkts)
@@ -2498,6 +2540,11 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
 			rte_errno = -ret;
 			return i;
 		}
+
+		if (hns3_vld_vlan_chk(tx_queue, m)) {
+			rte_errno = EINVAL;
+			return i;
+		}
 #endif
 		ret = rte_net_intel_cksum_prepare(m);
 		if (ret != 0) {
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 17/24] net/hns3: get device capability in primary process
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (15 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 16/24] net/hns3: support setting VF PVID by PF driver Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 18/24] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit ab2e2e34416371817a21a41fc3def231675d4487 ]

This patch optimizes the code to get device capability in primary
process, and moves the code of getting PCI revision id in order to avoid
evaluating the private hw->revision of shared PMD-specific private data
in slave process.

Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 57 ++++++++++++++++++++-----------
 drivers/net/hns3/hns3_ethdev.h    |  4 +--
 drivers/net/hns3/hns3_ethdev_vf.c | 43 ++++++++++++++++-------
 3 files changed, 69 insertions(+), 35 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index d3caca436..dbeb8930d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2795,6 +2795,36 @@ hns3_parse_speed(int speed_cmd, uint32_t *speed)
 	return 0;
 }
 
+static int
+hns3_get_capability(struct hns3_hw *hw)
+{
+	struct rte_pci_device *pci_dev;
+	struct rte_eth_dev *eth_dev;
+	uint16_t device_id;
+	uint8_t revision;
+	int ret;
+
+	eth_dev = &rte_eth_devices[hw->data->port_id];
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	device_id = pci_dev->id.device_id;
+
+	if (device_id == HNS3_DEV_ID_25GE_RDMA ||
+	    device_id == HNS3_DEV_ID_50GE_RDMA ||
+	    device_id == HNS3_DEV_ID_100G_RDMA_MACSEC)
+		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1);
+
+	/* 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: %d", ret);
+		return -EIO;
+	}
+	hw->revision = revision;
+
+	return 0;
+}
+
 static int
 hns3_get_board_configuration(struct hns3_hw *hw)
 {
@@ -2869,6 +2899,13 @@ hns3_get_configuration(struct hns3_hw *hw)
 		return ret;
 	}
 
+	/* Get device capability */
+	ret = hns3_get_capability(hw);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "failed to get device capability: %d.", ret);
+		return ret;
+	}
+
 	/* Get pf resource */
 	ret = hns3_query_pf_resource(hw);
 	if (ret) {
@@ -5400,26 +5437,12 @@ static const struct hns3_reset_ops hns3_reset_ops = {
 static int
 hns3_dev_init(struct rte_eth_dev *eth_dev)
 {
-	struct rte_device *dev = eth_dev->device;
-	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev);
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint16_t device_id = pci_dev->id.device_id;
-	uint8_t revision;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
-	/* 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;
-
 	eth_dev->process_private = (struct hns3_process_private *)
 	    rte_zmalloc_socket("hns3_filter_list",
 			       sizeof(struct hns3_process_private),
@@ -5454,12 +5477,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
 	}
 
 	hw->adapter_state = HNS3_NIC_UNINITIALIZED;
-
-	if (device_id == HNS3_DEV_ID_25GE_RDMA ||
-	    device_id == HNS3_DEV_ID_50GE_RDMA ||
-	    device_id == HNS3_DEV_ID_100G_RDMA_MACSEC)
-		hns3_set_bit(hw->flag, HNS3_DEV_SUPPORT_DCB_B, 1);
-
 	hns->is_vf = false;
 	hw->data = eth_dev->data;
 
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index acc11ef22..bec6d71ab 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -399,7 +399,7 @@ struct hns3_hw {
 	uint16_t alloc_rss_size;    /* RX queue number per TC */
 	uint16_t tx_qnum_per_tc;    /* TX queue number per TC */
 
-	uint32_t flag;
+	uint32_t capability;
 
 	struct hns3_port_base_vlan_config port_base_vlan_cfg;
 	/*
@@ -530,7 +530,7 @@ struct hns3_adapter {
 #define HNS3_DEV_SUPPORT_DCB_B			0x0
 
 #define hns3_dev_dcb_supported(hw) \
-	hns3_get_bit((hw)->flag, HNS3_DEV_SUPPORT_DCB_B)
+	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B)
 
 #define HNS3_DEV_PRIVATE_TO_HW(adapter) \
 	(&((struct hns3_adapter *)adapter)->hw)
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 93fd3a7d0..c2a49346d 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -1066,6 +1066,29 @@ hns3vf_interrupt_handler(void *param)
 	hns3vf_enable_irq0(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: %d", ret);
+		return -EIO;
+	}
+	hw->revision = revision;
+
+	return 0;
+}
+
 static int
 hns3vf_check_tqp_info(struct hns3_hw *hw)
 {
@@ -1213,6 +1236,13 @@ hns3vf_get_configuration(struct hns3_hw *hw)
 	hw->mac.media_type = HNS3_MEDIA_TYPE_NONE;
 	hw->rss_dis_flag = false;
 
+	/* Get device capability */
+	ret = hns3vf_get_capability(hw);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "failed to get device capability: %d.", ret);
+		return ret;
+	}
+
 	/* Get queue configuration from PF */
 	ret = hns3vf_get_queue_info(hw);
 	if (ret)
@@ -2456,25 +2486,12 @@ static const struct hns3_reset_ops hns3vf_reset_ops = {
 static int
 hns3vf_dev_init(struct rte_eth_dev *eth_dev)
 {
-	struct rte_device *dev = eth_dev->device;
-	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev);
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint8_t revision;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
-	/* 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;
-
 	eth_dev->process_private = (struct hns3_process_private *)
 	    rte_zmalloc_socket("hns3_filter_list",
 			       sizeof(struct hns3_process_private),
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 18/24] net/hns3: report Tx descriptor segment limitations
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (16 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 17/24] net/hns3: get device capability in primary process Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 19/24] net/hns3: cleanup duplicated code on processing TSO in Tx Wei Hu (Xavier)
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit eb8b3a0d829bc109dfb13de9c8cdeacda5449e69 ]

According to the user manual of Kunpeng920 SoC, the max allowed number
of segments per whole packet is 63 and the max number of segments per
packet is 8 in datapath.

This patch reports the Two segment parameters of Tx descriptor
limitations to DPDK framework.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 2 ++
 drivers/net/hns3/hns3_ethdev_vf.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index dbeb8930d..f156da843 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2501,6 +2501,8 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
 		.nb_align = HNS3_ALIGN_RING_DESC,
+		.nb_seg_max = HNS3_MAX_TSO_BD_PER_PKT,
+		.nb_mtu_seg_max = HNS3_MAX_NON_TSO_BD_PER_PKT,
 	};
 
 	info->vmdq_queue_num = 0;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index c2a49346d..f34d32e39 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -952,6 +952,8 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
 		.nb_align = HNS3_ALIGN_RING_DESC,
+		.nb_seg_max = HNS3_MAX_TSO_BD_PER_PKT,
+		.nb_mtu_seg_max = HNS3_MAX_NON_TSO_BD_PER_PKT,
 	};
 
 	info->vmdq_queue_num = 0;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 19/24] net/hns3: cleanup duplicated code on processing TSO in Tx
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (17 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 18/24] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 20/24] net/hns3: support copper media type Wei Hu (Xavier)
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit a001f09d11fac91b760c038cf69af7b041bc983c ]

This patch fixes up paylen calculation twice when processing TSO request
in the '.tx_pkt_burst' ops implementation function to avoid performance
loss.

Fixes: 6dca716c9e1d ("net/hns3: support TSO")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
---
 drivers/net/hns3/hns3_rxtx.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 931d89a1a..d4a2b7226 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1979,12 +1979,11 @@ hns3_pkt_is_tso(struct rte_mbuf *m)
 }
 
 static void
-hns3_set_tso(struct hns3_desc *desc,
-	     uint64_t ol_flags, struct rte_mbuf *rxm)
+hns3_set_tso(struct hns3_desc *desc, uint64_t ol_flags,
+		uint32_t paylen, struct rte_mbuf *rxm)
 {
-	uint32_t paylen, hdr_len;
-	uint32_t tmp;
 	uint8_t l2_len = rxm->l2_len;
+	uint32_t tmp;
 
 	if (!hns3_pkt_is_tso(rxm))
 		return;
@@ -1992,10 +1991,6 @@ hns3_set_tso(struct hns3_desc *desc,
 	if (hns3_tso_proc_tunnel(desc, ol_flags, rxm, &l2_len))
 		return;
 
-	hdr_len = rxm->l2_len + rxm->l3_len + rxm->l4_len;
-	hdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?
-		    rxm->outer_l2_len + rxm->outer_l3_len : 0;
-	paylen = rxm->pkt_len - hdr_len;
 	if (paylen <= rxm->tso_segsz)
 		return;
 
@@ -2036,7 +2031,7 @@ fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,
 			   rxm->outer_l2_len + rxm->outer_l3_len : 0;
 		paylen = rxm->pkt_len - hdr_len;
 		desc->tx.paylen = rte_cpu_to_le_32(paylen);
-		hns3_set_tso(desc, ol_flags, rxm);
+		hns3_set_tso(desc, ol_flags, paylen, rxm);
 	}
 
 	hns3_set_bit(rrcfv, HNS3_TXD_FE_B, frag_end);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 20/24] net/hns3: support copper media type
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (18 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 19/24] net/hns3: cleanup duplicated code on processing TSO in Tx Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 21/24] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit 95e50325864c12682eb9872f69ec682be1a688a8 ]

The hns3 network engine is built-in multiple SoCs, such as kunpeng 920,
kunpeng 930, etc. The PCI revision id is 0x21 in kunpeng 920, and the
PCI revision id is 0x30 in kunpeng 930.

Copper media type is supported for hns3 PF device in kunpeng 930 and
later SoCs. The configuration operation for PHY is implemented by
firmware.

Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 6 +++++-
 drivers/net/hns3/hns3_ethdev.h | 7 +++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index f156da843..5d50fcf21 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2824,6 +2824,9 @@ hns3_get_capability(struct hns3_hw *hw)
 	}
 	hw->revision = revision;
 
+	if (revision >= PCI_REVISION_ID_HIP09_A)
+		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 1);
+
 	return 0;
 }
 
@@ -2841,7 +2844,8 @@ hns3_get_board_configuration(struct hns3_hw *hw)
 		return ret;
 	}
 
-	if (cfg.media_type == HNS3_MEDIA_TYPE_COPPER) {
+	if (cfg.media_type == HNS3_MEDIA_TYPE_COPPER &&
+	    !hns3_dev_copper_supported(hw)) {
 		PMD_INIT_LOG(ERR, "media type is copper, not supported.");
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index bec6d71ab..0cdf3d6ac 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -30,6 +30,9 @@
 #define HNS3_PCI_REVISION_ID			0x08
 #define HNS3_PCI_REVISION_ID_LEN		1
 
+#define PCI_REVISION_ID_HIP08_B			0x21
+#define PCI_REVISION_ID_HIP09_A			0x30
+
 #define HNS3_UC_MACADDR_NUM		128
 #define HNS3_VF_UC_MACADDR_NUM		48
 #define HNS3_MC_MACADDR_NUM		128
@@ -528,10 +531,14 @@ struct hns3_adapter {
 };
 
 #define HNS3_DEV_SUPPORT_DCB_B			0x0
+#define HNS3_DEV_SUPPORT_COPPER_B		0x1
 
 #define hns3_dev_dcb_supported(hw) \
 	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B)
 
+#define hns3_dev_copper_supported(hw) \
+	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_COPPER_B)
+
 #define HNS3_DEV_PRIVATE_TO_HW(adapter) \
 	(&((struct hns3_adapter *)adapter)->hw)
 #define HNS3_DEV_PRIVATE_TO_ADAPTER(adapter) \
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 21/24] net/hns3: fix reassembling multiple segment packets in Tx
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (19 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 20/24] net/hns3: support copper media type Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 22/24] net/hns3: fix inserted VLAN tag position " Wei Hu (Xavier)
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit 6c44219f9907a064049d160d366d98bb840724a6 ]

Because of the hardware constraints, hns3 network engine doesn't support
sending packets with more than eight fragments. And hns3 pmd driver
tries to reassemble these kind of packets to meet hardware requirements.
Currently, there are two problems:
1) when the input buffer_len * 8 < pkt_len, the packets are impossible
   to be reassembled into 8 Buffer Descriptors. In this case, the
   packets will be passed to hardware, which eventually causes a
   hardware reset.
2) The meta data in origin packets which are required to fill into the
   descriptor haven't been copied into the reassembled pkts.

This patch adds a check for 1) to ensure such packets will be dropped by
driver and copies useful meta data from the origin packets to the
reassembled packets.

Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_rxtx.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index d4a2b7226..07640dbe5 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2090,6 +2090,20 @@ hns3_tx_alloc_mbufs(struct hns3_tx_queue *txq, struct rte_mempool *mb_pool,
 	return 0;
 }
 
+static inline void
+hns3_pktmbuf_copy_hdr(struct rte_mbuf *new_pkt, struct rte_mbuf *old_pkt)
+{
+	new_pkt->ol_flags = old_pkt->ol_flags;
+	new_pkt->pkt_len = rte_pktmbuf_pkt_len(old_pkt);
+	new_pkt->outer_l2_len = old_pkt->outer_l2_len;
+	new_pkt->outer_l3_len = old_pkt->outer_l3_len;
+	new_pkt->l2_len = old_pkt->l2_len;
+	new_pkt->l3_len = old_pkt->l3_len;
+	new_pkt->l4_len = old_pkt->l4_len;
+	new_pkt->vlan_tci_outer = old_pkt->vlan_tci_outer;
+	new_pkt->vlan_tci = old_pkt->vlan_tci;
+}
+
 static int
 hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 			struct rte_mbuf **new_pkt)
@@ -2113,9 +2127,11 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 
 	mb_pool = tx_pkt->pool;
 	buf_size = tx_pkt->buf_len - RTE_PKTMBUF_HEADROOM;
-	nb_new_buf = (tx_pkt->pkt_len - 1) / buf_size + 1;
+	nb_new_buf = (rte_pktmbuf_pkt_len(tx_pkt) - 1) / buf_size + 1;
+	if (nb_new_buf > HNS3_MAX_NON_TSO_BD_PER_PKT)
+		return -EINVAL;
 
-	last_buf_len = tx_pkt->pkt_len % buf_size;
+	last_buf_len = rte_pktmbuf_pkt_len(tx_pkt) % buf_size;
 	if (last_buf_len == 0)
 		last_buf_len = buf_size;
 
@@ -2127,7 +2143,7 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 	/* Copy the original packet content to the new mbufs */
 	temp = tx_pkt;
 	s = rte_pktmbuf_mtod(temp, char *);
-	len_s = temp->data_len;
+	len_s = rte_pktmbuf_data_len(temp);
 	temp_new = new_mbuf;
 	for (i = 0; i < nb_new_buf; i++) {
 		d = rte_pktmbuf_mtod(temp_new, char *);
@@ -2150,13 +2166,14 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 				if (temp == NULL)
 					break;
 				s = rte_pktmbuf_mtod(temp, char *);
-				len_s = temp->data_len;
+				len_s = rte_pktmbuf_data_len(temp);
 			}
 		}
 
 		temp_new->data_len = buf_len;
 		temp_new = temp_new->next;
 	}
+	hns3_pktmbuf_copy_hdr(new_mbuf, tx_pkt);
 
 	/* free original mbufs */
 	rte_pktmbuf_free(tx_pkt);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 22/24] net/hns3: fix inserted VLAN tag position in Tx
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (20 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 21/24] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 23/24] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit fc9b57ff576c4088138a8e0e53650b806927e683 ]

Based on hns3 network engine, in order to configure hardware VLAN insert
offload in Tx direction, PMD driver reads the VLAN tags from the
vlan_tci_outer and vlan_tci of the structure rte_mbuf, fills them into
the Tx Buffer Descriptor and sets the related offload flag for every
packet.

Currently, there are two VLAN related problems in the 'tx_pkt_burst' ops
implementation function:
1) When setting the related offload flag, PMD driver inserts the VLAN
   tag into the position that close to L3 header. So, when upper
   application sends a packet with a VLAN tag in the data buffer, the
   VLAN offloaded by hardware will be added to the wrong position. It is
   supposed to add the VLAN tag from the rte_mbuf to the position close
   to the MAC header in the packet when using VLAN insertion.

   And when PF PVID is enabled by calling the API function named
   rte_eth_dev_set_vlan_pvid or VF PVID is enabled by hns3 PF kernel
   ether driver, the VLAN tag from the structure rte_mbuf to enable the
   VLAN insertion should be filled into the position that close to L3
   header to avoid to be overwritten by the PVID which will always be
   inserted in the position that close to the MAC address.

2) When sending multiple segment packets, VLAN information is required
   to be filled into the first Tx Buffer descriptor. However, currently
   hns3 PMD driver incorrectly placed it in the last Tx Buffer
   Descriptor. This results in VLAN insert offload failure when sending
   multiple segment packets.

This patch fixed them by filling the VLAN information into the position
of the Tx Buffer Descriptor.

Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_rxtx.c | 102 ++++++++++++++++++++++-------------
 1 file changed, 65 insertions(+), 37 deletions(-)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 07640dbe5..b0253d5f6 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2007,51 +2007,58 @@ hns3_set_tso(struct hns3_desc *desc, uint64_t ol_flags,
 	desc->tx.mss = rte_cpu_to_le_16(rxm->tso_segsz);
 }
 
+static inline void
+hns3_fill_per_desc(struct hns3_desc *desc, struct rte_mbuf *rxm)
+{
+	desc->addr = rte_mbuf_data_iova(rxm);
+	desc->tx.send_size = rte_cpu_to_le_16(rte_pktmbuf_data_len(rxm));
+	desc->tx.tp_fe_sc_vld_ra_ri = rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B));
+}
+
 static void
-fill_desc(struct hns3_tx_queue *txq, uint16_t tx_desc_id, struct rte_mbuf *rxm,
-	  bool first, int offset)
+hns3_fill_first_desc(struct hns3_tx_queue *txq, struct hns3_desc *desc,
+		     struct rte_mbuf *rxm)
 {
-	struct hns3_desc *tx_ring = txq->tx_ring;
-	struct hns3_desc *desc = &tx_ring[tx_desc_id];
-	uint8_t frag_end = rxm->next == NULL ? 1 : 0;
 	uint64_t ol_flags = rxm->ol_flags;
-	uint16_t size = rxm->data_len;
-	uint16_t rrcfv = 0;
 	uint32_t hdr_len;
 	uint32_t paylen;
-	uint32_t tmp;
 
-	desc->addr = rte_mbuf_data_iova(rxm) + offset;
-	desc->tx.send_size = rte_cpu_to_le_16(size);
-	hns3_set_bit(rrcfv, HNS3_TXD_VLD_B, 1);
-
-	if (first) {
-		hdr_len = rxm->l2_len + rxm->l3_len + rxm->l4_len;
-		hdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?
+	hdr_len = rxm->l2_len + rxm->l3_len + rxm->l4_len;
+	hdr_len += (ol_flags & PKT_TX_TUNNEL_MASK) ?
 			   rxm->outer_l2_len + rxm->outer_l3_len : 0;
-		paylen = rxm->pkt_len - hdr_len;
-		desc->tx.paylen = rte_cpu_to_le_32(paylen);
-		hns3_set_tso(desc, ol_flags, paylen, rxm);
-	}
-
-	hns3_set_bit(rrcfv, HNS3_TXD_FE_B, frag_end);
-	desc->tx.tp_fe_sc_vld_ra_ri = rte_cpu_to_le_16(rrcfv);
-
-	if (frag_end) {
-		if (ol_flags & (PKT_TX_VLAN_PKT | PKT_TX_QINQ_PKT)) {
-			tmp = rte_le_to_cpu_32(desc->tx.type_cs_vlan_tso_len);
-			hns3_set_bit(tmp, HNS3_TXD_VLAN_B, 1);
-			desc->tx.type_cs_vlan_tso_len = rte_cpu_to_le_32(tmp);
-			desc->tx.vlan_tag = rte_cpu_to_le_16(rxm->vlan_tci);
-		}
+	paylen = rxm->pkt_len - hdr_len;
+	desc->tx.paylen = rte_cpu_to_le_32(paylen);
+	hns3_set_tso(desc, ol_flags, paylen, rxm);
 
-		if (ol_flags & PKT_TX_QINQ_PKT) {
-			tmp = rte_le_to_cpu_32(desc->tx.ol_type_vlan_len_msec);
-			hns3_set_bit(tmp, HNS3_TXD_OVLAN_B, 1);
-			desc->tx.ol_type_vlan_len_msec = rte_cpu_to_le_32(tmp);
+	/*
+	 * Currently, hardware doesn't support more than two layers VLAN offload
+	 * in Tx direction based on hns3 network engine. So when the number of
+	 * VLANs in the packets represented by rxm plus the number of VLAN
+	 * offload by hardware such as PVID etc, exceeds two, the packets will
+	 * be discarded or the original VLAN of the packets will be overwitted
+	 * by hardware. When the PF PVID is enabled by calling the API function
+	 * named rte_eth_dev_set_vlan_pvid or the VF PVID is enabled by the hns3
+	 * PF kernel ether driver, the outer VLAN tag will always be the PVID.
+	 * To avoid the VLAN of Tx descriptor is overwritten by PVID, it should
+	 * be added to the position close to the IP header when PVID is enabled.
+	 */
+	if (!txq->pvid_state && ol_flags & (PKT_TX_VLAN_PKT |
+				PKT_TX_QINQ_PKT)) {
+		desc->tx.ol_type_vlan_len_msec |=
+				rte_cpu_to_le_32(BIT(HNS3_TXD_OVLAN_B));
+		if (ol_flags & PKT_TX_QINQ_PKT)
 			desc->tx.outer_vlan_tag =
-				rte_cpu_to_le_16(rxm->vlan_tci_outer);
-		}
+					rte_cpu_to_le_16(rxm->vlan_tci_outer);
+		else
+			desc->tx.outer_vlan_tag =
+					rte_cpu_to_le_16(rxm->vlan_tci);
+	}
+
+	if (ol_flags & PKT_TX_QINQ_PKT ||
+	    ((ol_flags & PKT_TX_VLAN_PKT) && txq->pvid_state)) {
+		desc->tx.type_cs_vlan_tso_len |=
+					rte_cpu_to_le_32(BIT(HNS3_TXD_VLAN_B));
+		desc->tx.vlan_tag = rte_cpu_to_le_16(rxm->vlan_tci);
 	}
 }
 
@@ -2628,8 +2635,10 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	struct rte_net_hdr_lens hdr_lens = {0};
 	struct hns3_tx_queue *txq = tx_queue;
 	struct hns3_entry *tx_bak_pkt;
+	struct hns3_desc *tx_ring;
 	struct rte_mbuf *tx_pkt;
 	struct rte_mbuf *m_seg;
+	struct hns3_desc *desc;
 	uint32_t nb_hold = 0;
 	uint16_t tx_next_use;
 	uint16_t tx_pkt_num;
@@ -2644,6 +2653,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	tx_next_use   = txq->next_to_use;
 	tx_bd_max     = txq->nb_tx_desc;
 	tx_pkt_num = nb_pkts;
+	tx_ring = txq->tx_ring;
 
 	/* send packets */
 	tx_bak_pkt = &txq->sw_ring[tx_next_use];
@@ -2688,8 +2698,22 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			goto end_of_tx;
 
 		i = 0;
+		desc = &tx_ring[tx_next_use];
+
+		/*
+		 * If the packet is divided into multiple Tx Buffer Descriptors,
+		 * only need to fill vlan, paylen and tso into the first Tx
+		 * Buffer Descriptor.
+		 */
+		hns3_fill_first_desc(txq, desc, m_seg);
+
 		do {
-			fill_desc(txq, tx_next_use, m_seg, (i == 0), 0);
+			desc = &tx_ring[tx_next_use];
+			/*
+			 * Fill valid bits, DMA address and data length for each
+			 * Tx Buffer Descriptor.
+			 */
+			hns3_fill_per_desc(desc, m_seg);
 			tx_bak_pkt->mbuf = m_seg;
 			m_seg = m_seg->next;
 			tx_next_use++;
@@ -2702,6 +2726,10 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			i++;
 		} while (m_seg != NULL);
 
+		/* Add end flag for the last Tx Buffer Descriptor */
+		desc->tx.tp_fe_sc_vld_ra_ri |=
+				 rte_cpu_to_le_16(BIT(HNS3_TXD_FE_B));
+
 		nb_hold += i;
 		txq->next_to_use = tx_next_use;
 		txq->tx_bd_ready -= i;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 23/24] app/testpmd: remove hardcoded descriptors limit
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (21 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 22/24] net/hns3: fix inserted VLAN tag position " Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 24/24] net/bonding: change state machine to defaulted Wei Hu (Xavier)
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit 99e040d3adc9ee2284e315219f2a6baee680f4e3 ]

When users configure rxds and txds by used port config cmd based
on testpmd application, it will not be able to configure rxd and
txd according to the max capability range supported by the actual
NIC hardware. Due testpmd defects, it can only configure a fixed
range to 0 to 2048.
The final result is that an incorrect printing prompt appears and
cannot be applied using rxd && txd according to the actual
capabilities supported by the device.
In order to solve the above problems, we modify the testpmd. First
by calling the rte_eth_dev_info_get api to obtain the max and min
rx/tx capability supported by the hns3, and then use this range
to compare with the actual value by users configured and make
reasonable limitation.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c |  11 +--
 app/test-pmd/testpmd.c | 171 +++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d508d1e26..2d18b6caf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1913,18 +1913,13 @@ cmd_config_rx_tx_parsed(void *parsed_result,
 		nb_txq = res->value;
 	}
 	else if (!strcmp(res->name, "rxd")) {
-		if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
-			printf("rxd %d invalid - must be > 0 && <= %d\n",
-					res->value, RTE_TEST_RX_DESC_MAX);
+		if (check_nb_rxd(res->value) != 0)
 			return;
-		}
 		nb_rxd = res->value;
 	} else if (!strcmp(res->name, "txd")) {
-		if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
-			printf("txd %d invalid - must be > 0 && <= %d\n",
-					res->value, RTE_TEST_TX_DESC_MAX);
+		if (check_nb_txd(res->value) != 0)
 			return;
-		}
+
 		nb_txd = res->value;
 	} else {
 		printf("Unknown parameter\n");
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 0ef7ecfe8..8d3b7b2a3 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1071,6 +1071,177 @@ check_nb_txq(queueid_t txq)
 	return 0;
 }
 
+/*
+ * Get the allowed maximum number of RXDs of every rx queue.
+ * *pid return the port id which has minimal value of
+ * max_rxd in all queues of all ports.
+ */
+static uint16_t
+get_allowed_max_nb_rxd(portid_t *pid)
+{
+	uint16_t allowed_max_rxd = UINT16_MAX;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.rx_desc_lim.nb_max < allowed_max_rxd) {
+			allowed_max_rxd = dev_info.rx_desc_lim.nb_max;
+			*pid = pi;
+		}
+	}
+	return allowed_max_rxd;
+}
+
+/*
+ * Get the allowed minimal number of RXDs of every rx queue.
+ * *pid return the port id which has minimal value of
+ * min_rxd in all queues of all ports.
+ */
+static uint16_t
+get_allowed_min_nb_rxd(portid_t *pid)
+{
+	uint16_t allowed_min_rxd = 0;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.rx_desc_lim.nb_min > allowed_min_rxd) {
+			allowed_min_rxd = dev_info.rx_desc_lim.nb_min;
+			*pid = pi;
+		}
+	}
+
+	return allowed_min_rxd;
+}
+
+/*
+ * Check input rxd is valid or not.
+ * If input rxd is not greater than any of maximum number
+ * of RXDs of every Rx queues and is not less than any of
+ * minimal number of RXDs of every Rx queues, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_rxd(queueid_t rxd)
+{
+	uint16_t allowed_max_rxd;
+	uint16_t allowed_min_rxd;
+	portid_t pid = 0;
+
+	allowed_max_rxd = get_allowed_max_nb_rxd(&pid);
+	if (rxd > allowed_max_rxd) {
+		printf("Fail: input rxd (%u) can't be greater "
+		       "than max_rxds (%u) of port %u\n",
+		       rxd,
+		       allowed_max_rxd,
+		       pid);
+		return -1;
+	}
+
+	allowed_min_rxd = get_allowed_min_nb_rxd(&pid);
+	if (rxd < allowed_min_rxd) {
+		printf("Fail: input rxd (%u) can't be less "
+		       "than min_rxds (%u) of port %u\n",
+		       rxd,
+		       allowed_min_rxd,
+		       pid);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Get the allowed maximum number of TXDs of every rx queues.
+ * *pid return the port id which has minimal value of
+ * max_txd in every tx queue.
+ */
+static uint16_t
+get_allowed_max_nb_txd(portid_t *pid)
+{
+	uint16_t allowed_max_txd = UINT16_MAX;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.tx_desc_lim.nb_max < allowed_max_txd) {
+			allowed_max_txd = dev_info.tx_desc_lim.nb_max;
+			*pid = pi;
+		}
+	}
+	return allowed_max_txd;
+}
+
+/*
+ * Get the allowed maximum number of TXDs of every tx queues.
+ * *pid return the port id which has minimal value of
+ * min_txd in every tx queue.
+ */
+static uint16_t
+get_allowed_min_nb_txd(portid_t *pid)
+{
+	uint16_t allowed_min_txd = 0;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.tx_desc_lim.nb_min > allowed_min_txd) {
+			allowed_min_txd = dev_info.tx_desc_lim.nb_min;
+			*pid = pi;
+		}
+	}
+
+	return allowed_min_txd;
+}
+
+/*
+ * Check input txd is valid or not.
+ * If input txd is not greater than any of maximum number
+ * of TXDs of every Rx queues, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_txd(queueid_t txd)
+{
+	uint16_t allowed_max_txd;
+	uint16_t allowed_min_txd;
+	portid_t pid = 0;
+
+	allowed_max_txd = get_allowed_max_nb_txd(&pid);
+	if (txd > allowed_max_txd) {
+		printf("Fail: input txd (%u) can't be greater "
+		       "than max_txds (%u) of port %u\n",
+		       txd,
+		       allowed_max_txd,
+		       pid);
+		return -1;
+	}
+
+	allowed_min_txd = get_allowed_min_nb_txd(&pid);
+	if (txd < allowed_min_txd) {
+		printf("Fail: input txd (%u) can't be less "
+		       "than min_txds (%u) of port %u\n",
+		       txd,
+		       allowed_min_txd,
+		       pid);
+		return -1;
+	}
+	return 0;
+}
+
+
 /*
  * Get the allowed maximum number of hairpin queues.
  * *pid return the port id which has minimal value of
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 0694e1ef8..2b1e9a24f 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -859,6 +859,8 @@ queueid_t get_allowed_max_nb_rxq(portid_t *pid);
 int check_nb_rxq(queueid_t rxq);
 queueid_t get_allowed_max_nb_txq(portid_t *pid);
 int check_nb_txq(queueid_t txq);
+int check_nb_rxd(queueid_t rxd);
+int check_nb_txd(queueid_t txd);
 queueid_t get_allowed_max_nb_hairpinq(portid_t *pid);
 int check_nb_hairpinq(queueid_t hairpinq);
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH 24/24] net/bonding: change state machine to defaulted
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (22 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 23/24] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
@ 2020-08-17  9:25 ` Wei Hu (Xavier)
  2020-08-17  9:51 ` [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Luca Boccassi
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17  9:25 UTC (permalink / raw)
  To: stable; +Cc: xavier.huwei

From: Weifeng Li <liweifeng96@126.com>

[ upstream commit 0bf68c660e932e76087dc8c87f8b1dacba89c2be ]

A dpdk bonding 802.3ad network as follows:
+----------+                        +-----------+
|dpdk lacp |bond1.1 <------> bond2.1|switch lacp|
|          |bond1.2 <------> bond2.2|           |
+----------+                        +-----------+
If a fiber optic go wrong about single pass during normal running like
this:
bond1.2 -----> bond2.2 ok
bond1.2 <--x-- bond2.2 error: bond1.2 receive no LACPDU Some packets
			      from switch to dpdk will choose bond2.2
			      and lost.

DPDK lacp state machine will transits to the expired state if no LACPDU
is received before the current_while_timer expires. But if no LACPDU is
received before the current_while_timer expires again, DPDK lacp state
machine has no change. Bond2.2 can not change to inactive depend on the
received LACPDU.
According to IEEE 802.3ad, if no lacpdu is received before the
current_while_timer expires again, the state machine should transits
from expired to defaulted. Bond2.2 will change to inactive depend on the
LACPDU with defaulted state.

This patch adds a state machine change from expired to defaulted when no
lacpdu is received before the current_while_timer expires again
according to IEEE 802.3ad:
If no LACPDU is received before the current_while timer expires again,
the state machine transits to the DEFAULTED state. The record Default
function overwrites the current operational parameters for the Partner
with administratively configured values. This allows configuration of
aggregations and individual links when no protocol partner is present,
while still permitting an active partner to override default settings.
The update_Default_Selected function sets the Selected variable FALSE
if the Link Aggregation Group has changed. Since all operational
parameters are now set to locally administered values there can be no
disagreement as to the Link Aggregation Group, so the Matched variable
is set TRUE.

The relevant description is in the chapter 43.4.12 of the link below:
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=850426

Signed-off-by: Weifeng Li <liweifeng96@126.com>
Acked-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/bonding/eth_bond_8023ad_private.h |  3 +++
 drivers/net/bonding/rte_eth_bond_8023ad.c     | 21 +++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/eth_bond_8023ad_private.h b/drivers/net/bonding/eth_bond_8023ad_private.h
index 6e44ffdb1..9b5738afe 100644
--- a/drivers/net/bonding/eth_bond_8023ad_private.h
+++ b/drivers/net/bonding/eth_bond_8023ad_private.h
@@ -50,6 +50,7 @@
 #define SM_FLAGS_MOVED                      0x0100
 #define SM_FLAGS_PARTNER_SHORT_TIMEOUT      0x0200
 #define SM_FLAGS_NTT                        0x0400
+#define SM_FLAGS_EXPIRED                    0x0800
 
 #define BOND_LINK_FULL_DUPLEX_KEY           0x01
 #define BOND_LINK_SPEED_KEY_10M             0x02
@@ -103,6 +104,8 @@ struct port {
 
 	/** The operational Partner's port parameters */
 	struct port_params partner;
+	/** Partner administrative parameter values */
+	struct port_params partner_admin;
 
 	/* Additional port parameters not listed in documentation */
 	/** State machine flags */
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b24a44686..67ca0730f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -356,16 +356,28 @@ rx_machine(struct bond_dev_private *internals, uint16_t slave_id,
 
 		timer_set(&port->current_while_timer, timeout);
 		ACTOR_STATE_CLR(port, EXPIRED);
+		SM_FLAG_CLR(port, EXPIRED);
 		return; /* No state change */
 	}
 
 	/* If CURRENT state timer is not running (stopped or expired)
 	 * transit to EXPIRED state from DISABLED or CURRENT */
 	if (!timer_is_running(&port->current_while_timer)) {
-		ACTOR_STATE_SET(port, EXPIRED);
-		PARTNER_STATE_CLR(port, SYNCHRONIZATION);
-		PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
-		timer_set(&port->current_while_timer, internals->mode4.short_timeout);
+		if (SM_FLAG(port, EXPIRED)) {
+			port->selected = UNSELECTED;
+			memcpy(&port->partner, &port->partner_admin,
+				sizeof(struct port_params));
+			record_default(port);
+			ACTOR_STATE_CLR(port, EXPIRED);
+			timer_cancel(&port->current_while_timer);
+		} else {
+			SM_FLAG_SET(port, EXPIRED);
+			ACTOR_STATE_SET(port, EXPIRED);
+			PARTNER_STATE_CLR(port, SYNCHRONIZATION);
+			PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
+			timer_set(&port->current_while_timer,
+				internals->mode4.short_timeout);
+		}
 	}
 }
 
@@ -1021,6 +1033,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
 	port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
 
 	memcpy(&port->partner, &initial, sizeof(struct port_params));
+	memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
 
 	/* default states */
 	port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [dpdk-stable] [PATCH 00/24] backport for 19.11.4
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (23 preceding siblings ...)
  2020-08-17  9:25 ` [dpdk-stable] [PATCH 24/24] net/bonding: change state machine to defaulted Wei Hu (Xavier)
@ 2020-08-17  9:51 ` Luca Boccassi
  2020-08-17 11:54   ` Wei Hu (Xavier)
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
  26 siblings, 1 reply; 49+ messages in thread
From: Luca Boccassi @ 2020-08-17  9:51 UTC (permalink / raw)
  To: Wei Hu (Xavier), stable; +Cc: xavier.huwei

On Mon, 2020-08-17 at 17:25 +0800, Wei Hu (Xavier) wrote:
> This series are backport for 19.11.4 about hns3 PMD driver, bonding
> and testpmd.
> 
> Chengchang Tang (6):
>   net/hns3: remove restriction on setting VF MTU
>   net/hns3: support promiscuous and allmulticast mode for VF
>   net/hns3: fix adding multicast MAC address
>   net/hns3: decrease non-nearby memory access in Rx
>   net/hns3: support setting VF PVID by PF driver
>   net/hns3: cleanup duplicated code on processing TSO in Tx
> 
> Chengwen Feng (1):
>   net/hns3: get Rx/Tx queue fbd in xstats
> 
> Hao Chen (1):
>   net/hns3: optimize default RSS algorithm
> 
> Hongbo Zheng (3):
>   net/hns3: get link status change through mailbox
>   net/hns3: support TSO
>   net/hns3: check TSO segment size during Tx
> 
> Lijun Ou (4):
>   net/hns3: remove unnecessary branch
>   net/hns3: support symmetric RSS
>   net/hns3: report Tx descriptor segment limitations
>   app/testpmd: remove hardcoded descriptors limit
> 
> Wei Hu (Xavier) (8):
>   net/hns3: support setting VF MAC address by PF driver
>   net/hns3: get Tx abnormal errors in xstats
>   net/hns3: get PCI revision ID
>   net/hns3: support LRO
>   net/hns3: get device capability in primary process
>   net/hns3: support copper media type
>   net/hns3: fix reassembling multiple segment packets in Tx
>   net/hns3: fix inserted VLAN tag position in Tx
> 
> Weifeng Li (1):
>   net/bonding: change state machine to defaulted
> 
>  app/test-pmd/cmdline.c                        |  11 +-
>  app/test-pmd/testpmd.c                        | 171 ++++++
>  app/test-pmd/testpmd.h                        |   2 +
>  doc/guides/nics/features/hns3.ini             |   2 +
>  doc/guides/nics/features/hns3_vf.ini          |   4 +
>  doc/guides/nics/hns3.rst                      |   2 +
>  drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
>  drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
>  drivers/net/hns3/hns3_ethdev.c                | 269 ++++++--
>  drivers/net/hns3/hns3_ethdev.h                |  34 +-
>  drivers/net/hns3/hns3_ethdev_vf.c             | 578 +++++++++++++++---
>  drivers/net/hns3/hns3_flow.c                  |  12 +-
>  drivers/net/hns3/hns3_mbx.c                   |  93 +++
>  drivers/net/hns3/hns3_mbx.h                   |  13 +
>  drivers/net/hns3/hns3_rss.c                   |  35 +-
>  drivers/net/hns3/hns3_rss.h                   |   6 +-
>  drivers/net/hns3/hns3_rxtx.c                  | 525 ++++++++++++++--
>  drivers/net/hns3/hns3_rxtx.h                  |  65 +-
>  drivers/net/hns3/hns3_stats.c                 | 243 +++++---
>  drivers/net/hns3/hns3_stats.h                 |   3 +-
>  20 files changed, 1779 insertions(+), 313 deletions(-)

Hi,

If I understand correctly, this series adds support for 6 new features:

--- a/doc/guides/nics/features/hns3.ini
+++ b/doc/guides/nics/features/hns3.ini
@@ -8,6 +8,8 @@ Link status          = Y
 Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
+TSO                  = Y
+LRO                  = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y

--- a/doc/guides/nics/features/hns3_vf.ini
+++ b/doc/guides/nics/features/hns3_vf.ini
@@ -8,6 +8,10 @@ Link status          = Y
 Rx interrupt         = Y
 MTU update           = Y
 Jumbo frame          = Y
+TSO                  = Y
+LRO                  = Y
+Promiscuous mode     = Y
+Allmulticast mode    = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y

None of those are available in 20.02, and LRO is not available in
20.05.

What happens if a user upgrades from 19.11.4 with any of these features
enabled to 20.02 or 20.05?

-- 
Kind regards,
Luca Boccassi

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [dpdk-stable] [PATCH 00/24] backport for 19.11.4
  2020-08-17  9:51 ` [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Luca Boccassi
@ 2020-08-17 11:54   ` Wei Hu (Xavier)
  2020-08-17 13:42     ` Luca Boccassi
  0 siblings, 1 reply; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-17 11:54 UTC (permalink / raw)
  To: Luca Boccassi, stable; +Cc: xavier.huwei

Hi, Luca Boccassi

On 2020/8/17 17:51, Luca Boccassi wrote:
> On Mon, 2020-08-17 at 17:25 +0800, Wei Hu (Xavier) wrote:
>> This series are backport for 19.11.4 about hns3 PMD driver, bonding
>> and testpmd.
>>
>> Chengchang Tang (6):
>>    net/hns3: remove restriction on setting VF MTU
>>    net/hns3: support promiscuous and allmulticast mode for VF
>>    net/hns3: fix adding multicast MAC address
>>    net/hns3: decrease non-nearby memory access in Rx
>>    net/hns3: support setting VF PVID by PF driver
>>    net/hns3: cleanup duplicated code on processing TSO in Tx
>>
>> Chengwen Feng (1):
>>    net/hns3: get Rx/Tx queue fbd in xstats
>>
>> Hao Chen (1):
>>    net/hns3: optimize default RSS algorithm
>>
>> Hongbo Zheng (3):
>>    net/hns3: get link status change through mailbox
>>    net/hns3: support TSO
>>    net/hns3: check TSO segment size during Tx
>>
>> Lijun Ou (4):
>>    net/hns3: remove unnecessary branch
>>    net/hns3: support symmetric RSS
>>    net/hns3: report Tx descriptor segment limitations
>>    app/testpmd: remove hardcoded descriptors limit
>>
>> Wei Hu (Xavier) (8):
>>    net/hns3: support setting VF MAC address by PF driver
>>    net/hns3: get Tx abnormal errors in xstats
>>    net/hns3: get PCI revision ID
>>    net/hns3: support LRO
>>    net/hns3: get device capability in primary process
>>    net/hns3: support copper media type
>>    net/hns3: fix reassembling multiple segment packets in Tx
>>    net/hns3: fix inserted VLAN tag position in Tx
>>
>> Weifeng Li (1):
>>    net/bonding: change state machine to defaulted
>>
>>   app/test-pmd/cmdline.c                        |  11 +-
>>   app/test-pmd/testpmd.c                        | 171 ++++++
>>   app/test-pmd/testpmd.h                        |   2 +
>>   doc/guides/nics/features/hns3.ini             |   2 +
>>   doc/guides/nics/features/hns3_vf.ini          |   4 +
>>   doc/guides/nics/hns3.rst                      |   2 +
>>   drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
>>   drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
>>   drivers/net/hns3/hns3_ethdev.c                | 269 ++++++--
>>   drivers/net/hns3/hns3_ethdev.h                |  34 +-
>>   drivers/net/hns3/hns3_ethdev_vf.c             | 578 +++++++++++++++---
>>   drivers/net/hns3/hns3_flow.c                  |  12 +-
>>   drivers/net/hns3/hns3_mbx.c                   |  93 +++
>>   drivers/net/hns3/hns3_mbx.h                   |  13 +
>>   drivers/net/hns3/hns3_rss.c                   |  35 +-
>>   drivers/net/hns3/hns3_rss.h                   |   6 +-
>>   drivers/net/hns3/hns3_rxtx.c                  | 525 ++++++++++++++--
>>   drivers/net/hns3/hns3_rxtx.h                  |  65 +-
>>   drivers/net/hns3/hns3_stats.c                 | 243 +++++---
>>   drivers/net/hns3/hns3_stats.h                 |   3 +-
>>   20 files changed, 1779 insertions(+), 313 deletions(-)
> Hi,
>
> If I understand correctly, this series adds support for 6 new features:
>
> --- a/doc/guides/nics/features/hns3.ini
> +++ b/doc/guides/nics/features/hns3.ini
> @@ -8,6 +8,8 @@ Link status          = Y
>   Rx interrupt         = Y
>   MTU update           = Y
>   Jumbo frame          = Y
> +TSO                  = Y
> +LRO                  = Y
>   Promiscuous mode     = Y
>   Allmulticast mode    = Y
>   Unicast MAC filter   = Y
>
> --- a/doc/guides/nics/features/hns3_vf.ini
> +++ b/doc/guides/nics/features/hns3_vf.ini
> @@ -8,6 +8,10 @@ Link status          = Y
>   Rx interrupt         = Y
>   MTU update           = Y
>   Jumbo frame          = Y
> +TSO                  = Y
> +LRO                  = Y
> +Promiscuous mode     = Y
> +Allmulticast mode    = Y
>   Unicast MAC filter   = Y
>   Multicast MAC filter = Y
>   RSS hash             = Y
>
> None of those are available in 20.02, and LRO is not available in
> 20.05.
>
> What happens if a user upgrades from 19.11.4 with any of these features
> enabled to 20.02 or 20.05?

If a user upgrades from 19.11.4 to 20.02 or 20.05 based on hns3 network 
engine,

some features of hns3 will not be supported.  But in many cases 
customers prefer

to use the LTS version. We will recommend them to upgrade from 19.11.0 
to 19.11.4,

and will recommend that customers upgrade from 19.11.4 to 20.11.0 after the

release of 20.11.0.


     Regards

Xavier


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [dpdk-stable] [PATCH 00/24] backport for 19.11.4
  2020-08-17 11:54   ` Wei Hu (Xavier)
@ 2020-08-17 13:42     ` Luca Boccassi
  2020-08-18  3:25       ` Wei Hu (Xavier)
  0 siblings, 1 reply; 49+ messages in thread
From: Luca Boccassi @ 2020-08-17 13:42 UTC (permalink / raw)
  To: Wei Hu (Xavier), stable; +Cc: xavier.huwei

On Mon, 2020-08-17 at 19:54 +0800, Wei Hu (Xavier) wrote:
> Hi, Luca Boccassi
> 
> On 2020/8/17 17:51, Luca Boccassi wrote:
> > On Mon, 2020-08-17 at 17:25 +0800, Wei Hu (Xavier) wrote:
> > > This series are backport for 19.11.4 about hns3 PMD driver, bonding
> > > and testpmd.
> > > 
> > > Chengchang Tang (6):
> > >    net/hns3: remove restriction on setting VF MTU
> > >    net/hns3: support promiscuous and allmulticast mode for VF
> > >    net/hns3: fix adding multicast MAC address
> > >    net/hns3: decrease non-nearby memory access in Rx
> > >    net/hns3: support setting VF PVID by PF driver
> > >    net/hns3: cleanup duplicated code on processing TSO in Tx
> > > 
> > > Chengwen Feng (1):
> > >    net/hns3: get Rx/Tx queue fbd in xstats
> > > 
> > > Hao Chen (1):
> > >    net/hns3: optimize default RSS algorithm
> > > 
> > > Hongbo Zheng (3):
> > >    net/hns3: get link status change through mailbox
> > >    net/hns3: support TSO
> > >    net/hns3: check TSO segment size during Tx
> > > 
> > > Lijun Ou (4):
> > >    net/hns3: remove unnecessary branch
> > >    net/hns3: support symmetric RSS
> > >    net/hns3: report Tx descriptor segment limitations
> > >    app/testpmd: remove hardcoded descriptors limit
> > > 
> > > Wei Hu (Xavier) (8):
> > >    net/hns3: support setting VF MAC address by PF driver
> > >    net/hns3: get Tx abnormal errors in xstats
> > >    net/hns3: get PCI revision ID
> > >    net/hns3: support LRO
> > >    net/hns3: get device capability in primary process
> > >    net/hns3: support copper media type
> > >    net/hns3: fix reassembling multiple segment packets in Tx
> > >    net/hns3: fix inserted VLAN tag position in Tx
> > > 
> > > Weifeng Li (1):
> > >    net/bonding: change state machine to defaulted
> > > 
> > >   app/test-pmd/cmdline.c                        |  11 +-
> > >   app/test-pmd/testpmd.c                        | 171 ++++++
> > >   app/test-pmd/testpmd.h                        |   2 +
> > >   doc/guides/nics/features/hns3.ini             |   2 +
> > >   doc/guides/nics/features/hns3_vf.ini          |   4 +
> > >   doc/guides/nics/hns3.rst                      |   2 +
> > >   drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
> > >   drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
> > >   drivers/net/hns3/hns3_ethdev.c                | 269 ++++++--
> > >   drivers/net/hns3/hns3_ethdev.h                |  34 +-
> > >   drivers/net/hns3/hns3_ethdev_vf.c             | 578 +++++++++++++++---
> > >   drivers/net/hns3/hns3_flow.c                  |  12 +-
> > >   drivers/net/hns3/hns3_mbx.c                   |  93 +++
> > >   drivers/net/hns3/hns3_mbx.h                   |  13 +
> > >   drivers/net/hns3/hns3_rss.c                   |  35 +-
> > >   drivers/net/hns3/hns3_rss.h                   |   6 +-
> > >   drivers/net/hns3/hns3_rxtx.c                  | 525 ++++++++++++++--
> > >   drivers/net/hns3/hns3_rxtx.h                  |  65 +-
> > >   drivers/net/hns3/hns3_stats.c                 | 243 +++++---
> > >   drivers/net/hns3/hns3_stats.h                 |   3 +-
> > >   20 files changed, 1779 insertions(+), 313 deletions(-)
> > Hi,
> > 
> > If I understand correctly, this series adds support for 6 new features:
> > 
> > --- a/doc/guides/nics/features/hns3.ini
> > +++ b/doc/guides/nics/features/hns3.ini
> > @@ -8,6 +8,8 @@ Link status          = Y
> >   Rx interrupt         = Y
> >   MTU update           = Y
> >   Jumbo frame          = Y
> > +TSO                  = Y
> > +LRO                  = Y
> >   Promiscuous mode     = Y
> >   Allmulticast mode    = Y
> >   Unicast MAC filter   = Y
> > 
> > --- a/doc/guides/nics/features/hns3_vf.ini
> > +++ b/doc/guides/nics/features/hns3_vf.ini
> > @@ -8,6 +8,10 @@ Link status          = Y
> >   Rx interrupt         = Y
> >   MTU update           = Y
> >   Jumbo frame          = Y
> > +TSO                  = Y
> > +LRO                  = Y
> > +Promiscuous mode     = Y
> > +Allmulticast mode    = Y
> >   Unicast MAC filter   = Y
> >   Multicast MAC filter = Y
> >   RSS hash             = Y
> > 
> > None of those are available in 20.02, and LRO is not available in
> > 20.05.
> > 
> > What happens if a user upgrades from 19.11.4 with any of these features
> > enabled to 20.02 or 20.05?
> 
> If a user upgrades from 19.11.4 to 20.02 or 20.05 based on hns3 network 
> engine,
> 
> some features of hns3 will not be supported.  But in many cases 
> customers prefer
> 
> to use the LTS version. We will recommend them to upgrade from 19.11.0 
> to 19.11.4,
> 
> and will recommend that customers upgrade from 19.11.4 to 20.11.0 after the
> 
> release of 20.11.0.
> 
> 
>      Regards
> 
> Xavier

Sorry, but I don't feel too comfortable adding multiple new features to
the LTS branch, especially as they are not available in the following
release. Stable is valuable because it is stable. Since we got ABI
stability now, users that want new features can upgrade to
20.02/20.05/20.08 without any application breakages.

Would it be possible to break this series into a smaller bugfix-only
patchset?

-- 
Kind regards,
Luca Boccassi

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [dpdk-stable] [PATCH 00/24] backport for 19.11.4
  2020-08-17 13:42     ` Luca Boccassi
@ 2020-08-18  3:25       ` Wei Hu (Xavier)
  0 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  3:25 UTC (permalink / raw)
  To: Luca Boccassi; +Cc: stable, xavier.huwei

Hi, Luca Boccassi

On 2020/8/17 21:42, Luca Boccassi wrote:
> On Mon, 2020-08-17 at 19:54 +0800, Wei Hu (Xavier) wrote:
>> Hi, Luca Boccassi
>>
>> On 2020/8/17 17:51, Luca Boccassi wrote:
>>> On Mon, 2020-08-17 at 17:25 +0800, Wei Hu (Xavier) wrote:
>>>> This series are backport for 19.11.4 about hns3 PMD driver, bonding
>>>> and testpmd.
>>>>
>>>> Chengchang Tang (6):
>>>>     net/hns3: remove restriction on setting VF MTU
>>>>     net/hns3: support promiscuous and allmulticast mode for VF
>>>>     net/hns3: fix adding multicast MAC address
>>>>     net/hns3: decrease non-nearby memory access in Rx
>>>>     net/hns3: support setting VF PVID by PF driver
>>>>     net/hns3: cleanup duplicated code on processing TSO in Tx
>>>>
>>>> Chengwen Feng (1):
>>>>     net/hns3: get Rx/Tx queue fbd in xstats
>>>>
>>>> Hao Chen (1):
>>>>     net/hns3: optimize default RSS algorithm
>>>>
>>>> Hongbo Zheng (3):
>>>>     net/hns3: get link status change through mailbox
>>>>     net/hns3: support TSO
>>>>     net/hns3: check TSO segment size during Tx
>>>>
>>>> Lijun Ou (4):
>>>>     net/hns3: remove unnecessary branch
>>>>     net/hns3: support symmetric RSS
>>>>     net/hns3: report Tx descriptor segment limitations
>>>>     app/testpmd: remove hardcoded descriptors limit
>>>>
>>>> Wei Hu (Xavier) (8):
>>>>     net/hns3: support setting VF MAC address by PF driver
>>>>     net/hns3: get Tx abnormal errors in xstats
>>>>     net/hns3: get PCI revision ID
>>>>     net/hns3: support LRO
>>>>     net/hns3: get device capability in primary process
>>>>     net/hns3: support copper media type
>>>>     net/hns3: fix reassembling multiple segment packets in Tx
>>>>     net/hns3: fix inserted VLAN tag position in Tx
>>>>
>>>> Weifeng Li (1):
>>>>     net/bonding: change state machine to defaulted
>>>>
>>>>    app/test-pmd/cmdline.c                        |  11 +-
>>>>    app/test-pmd/testpmd.c                        | 171 ++++++
>>>>    app/test-pmd/testpmd.h                        |   2 +
>>>>    doc/guides/nics/features/hns3.ini             |   2 +
>>>>    doc/guides/nics/features/hns3_vf.ini          |   4 +
>>>>    doc/guides/nics/hns3.rst                      |   2 +
>>>>    drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
>>>>    drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
>>>>    drivers/net/hns3/hns3_ethdev.c                | 269 ++++++--
>>>>    drivers/net/hns3/hns3_ethdev.h                |  34 +-
>>>>    drivers/net/hns3/hns3_ethdev_vf.c             | 578 +++++++++++++++---
>>>>    drivers/net/hns3/hns3_flow.c                  |  12 +-
>>>>    drivers/net/hns3/hns3_mbx.c                   |  93 +++
>>>>    drivers/net/hns3/hns3_mbx.h                   |  13 +
>>>>    drivers/net/hns3/hns3_rss.c                   |  35 +-
>>>>    drivers/net/hns3/hns3_rss.h                   |   6 +-
>>>>    drivers/net/hns3/hns3_rxtx.c                  | 525 ++++++++++++++--
>>>>    drivers/net/hns3/hns3_rxtx.h                  |  65 +-
>>>>    drivers/net/hns3/hns3_stats.c                 | 243 +++++---
>>>>    drivers/net/hns3/hns3_stats.h                 |   3 +-
>>>>    20 files changed, 1779 insertions(+), 313 deletions(-)
>>> Hi,
>>>
>>> If I understand correctly, this series adds support for 6 new features:
>>>
>>> --- a/doc/guides/nics/features/hns3.ini
>>> +++ b/doc/guides/nics/features/hns3.ini
>>> @@ -8,6 +8,8 @@ Link status          = Y
>>>    Rx interrupt         = Y
>>>    MTU update           = Y
>>>    Jumbo frame          = Y
>>> +TSO                  = Y
>>> +LRO                  = Y
>>>    Promiscuous mode     = Y
>>>    Allmulticast mode    = Y
>>>    Unicast MAC filter   = Y
>>>
>>> --- a/doc/guides/nics/features/hns3_vf.ini
>>> +++ b/doc/guides/nics/features/hns3_vf.ini
>>> @@ -8,6 +8,10 @@ Link status          = Y
>>>    Rx interrupt         = Y
>>>    MTU update           = Y
>>>    Jumbo frame          = Y
>>> +TSO                  = Y
>>> +LRO                  = Y
>>> +Promiscuous mode     = Y
>>> +Allmulticast mode    = Y
>>>    Unicast MAC filter   = Y
>>>    Multicast MAC filter = Y
>>>    RSS hash             = Y
>>>
>>> None of those are available in 20.02, and LRO is not available in
>>> 20.05.
>>>
>>> What happens if a user upgrades from 19.11.4 with any of these features
>>> enabled to 20.02 or 20.05?
>> If a user upgrades from 19.11.4 to 20.02 or 20.05 based on hns3 network
>> engine,
>>
>> some features of hns3 will not be supported.  But in many cases
>> customers prefer
>>
>> to use the LTS version. We will recommend them to upgrade from 19.11.0
>> to 19.11.4,
>>
>> and will recommend that customers upgrade from 19.11.4 to 20.11.0 after the
>>
>> release of 20.11.0.
>>
>>
>>       Regards
>>
>> Xavier
> Sorry, but I don't feel too comfortable adding multiple new features to
> the LTS branch, especially as they are not available in the following
> release. Stable is valuable because it is stable. Since we got ABI
> stability now, users that want new features can upgrade to
> 20.02/20.05/20.08 without any application breakages.
>
> Would it be possible to break this series into a smaller bugfix-only
> patchset?

OK, I will send a smaller V2.

Thanks, Xavier


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 00/10] backport for 19.11.4
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (24 preceding siblings ...)
  2020-08-17  9:51 ` [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Luca Boccassi
@ 2020-08-18  6:49 ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 01/10] net/hns3: get link status change through mailbox Wei Hu (Xavier)
                     ` (9 more replies)
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
  26 siblings, 10 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

This series are backport for 19.11.4 about hns3 PMD driver, bonding
and testpmd.

Chengchang Tang (2):
  net/hns3: remove restriction on setting VF MTU
  net/hns3: fix adding multicast MAC address

Hao Chen (1):
  net/hns3: optimize default RSS algorithm

Hongbo Zheng (1):
  net/hns3: get link status change through mailbox

Lijun Ou (3):
  net/hns3: remove unnecessary branch
  net/hns3: report Tx descriptor segment limitations
  app/testpmd: remove hardcoded descriptors limit

Wei Hu (Xavier) (2):
  net/hns3: get device capability in primary process
  net/hns3: fix reassembling multiple segment packets in Tx

Weifeng Li (1):
  net/bonding: change state machine to defaulted

 app/test-pmd/cmdline.c                        |  11 +-
 app/test-pmd/testpmd.c                        | 171 +++++++++++
 app/test-pmd/testpmd.h                        |   2 +
 drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
 drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
 drivers/net/hns3/hns3_ethdev.c                | 197 ++++++++++---
 drivers/net/hns3/hns3_ethdev.h                |   5 +-
 drivers/net/hns3/hns3_ethdev_vf.c             | 277 ++++++++++++++----
 drivers/net/hns3/hns3_mbx.c                   |  37 +++
 drivers/net/hns3/hns3_mbx.h                   |   8 +
 drivers/net/hns3/hns3_rss.c                   |  14 +-
 drivers/net/hns3/hns3_rxtx.c                  |  25 +-
 12 files changed, 662 insertions(+), 109 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 01/10] net/hns3: get link status change through mailbox
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 02/10] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Hongbo Zheng <zhenghongbo3@huawei.com>

[ upstream commit 109e4dd1bd7a5f7e0400be974f2b9e18d10cb3a6 ]

Currently, firmware adds the function of sending message to PF driver
through mailbox when the link status is changed, hns3 PMD driver can
usually recognize link state change faster through the message.

And in some extreme cases, this way is not faster than existing method
regularly updating link status by issuing the command every second in PF
driver, because of the parallel processing of mailbox and command
messages in firmware. So we reserve updating link status using timers in
PF driver, and add querying link status by issuing command to the
firmware in '.link_update' ops implementation function named
hns3_dev_link_update to solve the out of date link status.

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 14 +++++++++++--
 drivers/net/hns3/hns3_ethdev.h |  1 +
 drivers/net/hns3/hns3_mbx.c    | 37 ++++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_mbx.h    |  8 ++++++++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 971f2f900..c31a9328a 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -75,6 +75,7 @@ static enum hns3_reset_level hns3_get_reset_level(struct hns3_adapter *hns,
 static int hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
+static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
@@ -216,6 +217,8 @@ hns3_interrupt_handler(void *param)
 		hns3_schedule_reset(hns);
 	} else if (event_cause == HNS3_VECTOR0_EVENT_RST)
 		hns3_schedule_reset(hns);
+	else if (event_cause == HNS3_VECTOR0_EVENT_MBX)
+		hns3_dev_handle_mbx_msg(hw);
 	else
 		hns3_err(hw, "Received unknown event");
 
@@ -2441,6 +2444,11 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev,
 	struct hns3_mac *mac = &hw->mac;
 	struct rte_eth_link new_link;
 
+	if (!hns3_is_reset_pending(hns)) {
+		hns3_update_speed_duplex(eth_dev);
+		hns3_update_link_status(hw);
+	}
+
 	memset(&new_link, 0, sizeof(new_link));
 	switch (mac->link_speed) {
 	case ETH_SPEED_NUM_10M:
@@ -4067,14 +4075,16 @@ hns3_get_mac_link_status(struct hns3_hw *hw)
 	return !!link_status;
 }
 
-static void
+void
 hns3_update_link_status(struct hns3_hw *hw)
 {
 	int state;
 
 	state = hns3_get_mac_link_status(hw);
-	if (state != hw->mac.link_status)
+	if (state != hw->mac.link_status) {
 		hw->mac.link_status = state;
+		hns3_warn(hw, "Link status change to %s!", state ? "up" : "down");
+	}
 }
 
 static void
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 155099e99..35e64aa5a 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -648,6 +648,7 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
 			 enum rte_filter_op filter_op, void *arg);
 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);
 
 static inline bool
 is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c
index 7b5ef9476..64996c9ae 100644
--- a/drivers/net/hns3/hns3_mbx.c
+++ b/drivers/net/hns3/hns3_mbx.c
@@ -292,6 +292,40 @@ hns3_update_resp_position(struct hns3_hw *hw, uint32_t resp_msg)
 	resp->tail = tail;
 }
 
+static void
+hns3_link_fail_parse(struct hns3_hw *hw, uint8_t link_fail_code)
+{
+	switch (link_fail_code) {
+	case HNS3_MBX_LF_NORMAL:
+		break;
+	case HNS3_MBX_LF_REF_CLOCK_LOST:
+		hns3_warn(hw, "Reference clock lost!");
+		break;
+	case HNS3_MBX_LF_XSFP_TX_DISABLE:
+		hns3_warn(hw, "SFP tx is disabled!");
+		break;
+	case HNS3_MBX_LF_XSFP_ABSENT:
+		hns3_warn(hw, "SFP is absent!");
+		break;
+	default:
+		hns3_warn(hw, "Unknown fail code:%u!", link_fail_code);
+		break;
+	}
+}
+
+static void
+hns3_handle_link_change_event(struct hns3_hw *hw,
+			      struct hns3_mbx_pf_to_vf_cmd *req)
+{
+#define LINK_STATUS_OFFSET     1
+#define LINK_FAIL_CODE_OFFSET  2
+
+	if (!req->msg[LINK_STATUS_OFFSET])
+		hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]);
+
+	hns3_update_link_status(hw);
+}
+
 void
 hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 {
@@ -347,6 +381,9 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 
 			hns3_mbx_handler(hw);
 			break;
+		case HNS3_MBX_PUSH_LINK_STATUS:
+			hns3_handle_link_change_event(hw, req);
+			break;
 		default:
 			hns3_err(hw,
 				 "VF received unsupported(%d) mbx msg from PF",
diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h
index 7bcfbbebc..b01eaacc3 100644
--- a/drivers/net/hns3/hns3_mbx.h
+++ b/drivers/net/hns3/hns3_mbx.h
@@ -42,6 +42,7 @@ enum HNS3_MBX_OPCODE {
 
 	HNS3_MBX_HANDLE_VF_TBL = 38,    /* (VF -> PF) store/clear hw cfg tbl */
 	HNS3_MBX_GET_RING_VECTOR_MAP,   /* (VF -> PF) get ring-to-vector map */
+	HNS3_MBX_PUSH_LINK_STATUS = 201, /* (IMP -> PF) get port link status */
 };
 
 /* below are per-VF mac-vlan subcodes */
@@ -65,6 +66,13 @@ enum hns3_mbx_tbl_cfg_subcode {
 	HNS3_MBX_VPORT_LIST_CLEAR = 0,
 };
 
+enum hns3_mbx_link_fail_subcode {
+	HNS3_MBX_LF_NORMAL = 0,
+	HNS3_MBX_LF_REF_CLOCK_LOST,
+	HNS3_MBX_LF_XSFP_TX_DISABLE,
+	HNS3_MBX_LF_XSFP_ABSENT,
+};
+
 #define HNS3_MBX_MAX_MSG_SIZE	16
 #define HNS3_MBX_MAX_RESP_DATA_SIZE	8
 #define HNS3_MBX_RING_MAP_BASIC_MSG_NUM	3
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 02/10] net/hns3: optimize default RSS algorithm
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 01/10] net/hns3: get link status change through mailbox Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 03/10] net/hns3: remove unnecessary branch Wei Hu (Xavier)
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Hao Chen <chenhao164@huawei.com>

[ upstream commit 8834849a9518db9cc79f5585ce15c4630ff0c0c9 ]

This patch changed the default algorithm of RSS from simle_xor to
toeplitz because toeplitz is used more frequently by upper applications
such as ceph.

Signed-off-by: Hao Chen <chenhao164@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_rss.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index f19b79928..a6cab29c9 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -211,7 +211,11 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw,
 			req->ipv6_fragment_en |= HNS3_IP_OTHER_BIT_MASK;
 			break;
 		default:
-			/* Other unsupported flow types won't change tuples */
+			/*
+			 * rss_hf doesn't include unsupported flow types
+			 * because the API framework has checked it, and
+			 * this branch will never go unless rss_hf is zero.
+			 */
 			break;
 		}
 	}
@@ -251,8 +255,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 	struct hns3_hw *hw = &hns->hw;
 	struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets;
 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
-	uint8_t algo = rss_cfg->conf.func;
 	uint8_t key_len = rss_conf->rss_key_len;
+	uint8_t algo;
 	uint64_t rss_hf = rss_conf->rss_hf;
 	uint8_t *key = rss_conf->rss_key;
 	int ret;
@@ -288,6 +292,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 			ret = -EINVAL;
 			goto conf_err;
 		}
+		algo = rss_cfg->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR ?
+			HNS3_RSS_HASH_ALGO_SIMPLE : HNS3_RSS_HASH_ALGO_TOEPLITZ;
 		ret = hns3_set_rss_algo_key(hw, algo, key);
 		if (ret)
 			goto conf_err;
@@ -505,7 +511,9 @@ hns3_set_default_rss_args(struct hns3_hw *hw)
 	int i;
 
 	/* Default hash algorithm */
-	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+
+	/* Default RSS key */
 	memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE);
 
 	/* Initialize RSS indirection table */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 03/10] net/hns3: remove unnecessary branch
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 01/10] net/hns3: get link status change through mailbox Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 02/10] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 04/10] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit d13a7447a131a3a7078caf1d14e674e8add1d0a5 ]

Because the rte layer of DPDK framework has already processed the case
when the idx is zero before calling the '.mac_addr_remove' ops function,
the input parameter named idx can not be zero in the '.mac_addr_remove'
function. This patch removes unnecessary branch process to check whether
input parameter named idx is zero in the '.mac_addr_remove' ops
implementation function named hns3_remove_mac_addr.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index c31a9328a..128cd793d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -1531,8 +1531,6 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 		return;
 	}
 
-	if (idx == 0)
-		hw->mac.default_addr_setted = false;
 	rte_spinlock_unlock(&hw->lock);
 }
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 04/10] net/hns3: remove restriction on setting VF MTU
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (2 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 03/10] net/hns3: remove unnecessary branch Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 05/10] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit 4bf2c84bd88691bbb9cdc39a8bcf597537abfa80 ]

The hns3 PF/VF devices on the same port share the hardware MTU
configuration. Currently, we send mailbox to inform hns3 PF kernel
ethdev driver to finish hardware MTU configuration in hns3 VF PMD
driver, there is no need to stop the port for hns3 VF device, and
the MTU value issued by hns3 VF PMD driver must be less than or
equal to PF's MTU.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev_vf.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 5e5da8685..63fca0197 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -606,12 +606,14 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	uint32_t frame_size = mtu + HNS3_ETH_OVERHEAD;
 	int ret;
 
-	if (dev->data->dev_started) {
-		hns3_err(hw, "Failed to set mtu, port %u must be stopped "
-			 "before configuration", dev->data->port_id);
-		return -EBUSY;
-	}
-
+	/*
+	 * The hns3 PF/VF devices on the same port share the hardware MTU
+	 * configuration. Currently, we send mailbox to inform hns3 PF kernel
+	 * ethdev driver to finish hardware MTU configuration in hns3 VF PMD
+	 * driver, there is no need to stop the port for hns3 VF device, and the
+	 * MTU value issued by hns3 VF PMD driver must be less than or equal to
+	 * PF's MTU.
+	 */
 	if (rte_atomic16_read(&hw->reset.resetting)) {
 		hns3_err(hw, "Failed to set mtu during resetting");
 		return -EIO;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 05/10] net/hns3: fix adding multicast MAC address
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (3 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 04/10] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 06/10] net/hns3: get device capability in primary process Wei Hu (Xavier)
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit fb94f359481ff6d53f6b7850d3ad393addfb6afb ]

Currently, when upper application calls the rte_eth_dev_mac_addr_add API
function to add a MC mac address based on hns3 PF/VF device, it will
fail.

In hns3 network engine adding UC and MC mac address with different
commands with firmware. We need to determine whether the input address
is a UC or a MC address to call different commands in the
'.mac_addr_add' and '.mac_addr_remove' ops implementation functions in
hns3 PF and VF driver as below:
  hns3_add_mac_addr
  hns3vf_add_uc_mac_addr
  hns3_remove_mac_addr
  hns3vf_remove_mac_addr

By the way, it is recommended calling the rte_eth_dev_set_mc_addr_list API
function to set the MC mac address, because using the
rte_eth_dev_mac_addr_add API function to set MC mac address may affect the
specifications of UC mac addresses.

Fixes: 7d7f9f80bbfb ("net/hns3: support MAC address related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 133 ++++++++++++++---
 drivers/net/hns3/hns3_ethdev_vf.c | 231 +++++++++++++++++++++++-------
 2 files changed, 295 insertions(+), 69 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 128cd793d..217aea4c0 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -77,6 +77,11 @@ static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
 static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
+static int hns3_add_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+static int hns3_remove_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
 {
@@ -1459,6 +1464,53 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	return ret;
 }
 
+static int
+hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3_add_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_remove_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to remove mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		  uint32_t idx, __attribute__ ((unused)) uint32_t pool)
@@ -1468,12 +1520,27 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_add_uc_addr_common(hw, mac_addr);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_add_uc_addr_common(hw, mac_addr);
+
 	if (ret) {
 		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
+			 ret);
 		return ret;
 	}
 
@@ -1495,7 +1562,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Remove unicast mac addr err! addr(%s) invalid",
+		hns3_err(hw, "remove unicast mac addr err! addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1522,16 +1589,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_remove_uc_addr_common(hw, mac_addr);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_remove_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_remove_uc_addr_common(hw, mac_addr);
+	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
-		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s): %d", mac_str, ret);
-		return;
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,
+			 ret);
 	}
-
-	rte_spinlock_unlock(&hw->lock);
 }
 
 static int
@@ -1632,19 +1701,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
 
 	for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		if (del)
-			ret = hns3_remove_uc_addr_common(hw, addr);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3_remove_mc_addr(hw, addr) :
+			      hns3_add_mc_addr(hw, addr);
 		else
-			ret = hns3_add_uc_addr_common(hw, addr);
+			ret = del ? hns3_remove_uc_addr_common(hw, addr) :
+			      hns3_add_uc_addr_common(hw, addr);
+
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
-			hns3_dbg(hw,
-				 "Failed to %s mac addr(%s). ret:%d i:%d",
-				 del ? "remove" : "restore", mac_str, ret, i);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
 	return err;
@@ -1691,7 +1763,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_multicast_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr, addr(%s) invalid",
+		hns3_err(hw, "failed to add mc mac addr, addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1720,7 +1792,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 			hns3_err(hw, "mc mac vlan table is full");
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mc mac addr(%s): %d", mac_str, ret);
 	}
 
 	return ret;
@@ -1785,7 +1857,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
@@ -1798,7 +1870,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
@@ -1809,12 +1881,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 				rte_ether_format_addr(mac_str,
 						      RTE_ETHER_ADDR_FMT_SIZE,
 						      addr);
-				hns3_err(hw, "Failed to set mc mac addr, "
+				hns3_err(hw, "failed to set mc mac addr, "
 					 "addrs invalid. two same addrs(%s).",
 					 mac_str);
 				return -EINVAL;
 			}
 		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
 
 	return 0;
@@ -3597,6 +3687,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code)
 			     "add mac ethertype failed for undefined, code=%d.",
 			     resp_code);
 		return_status = -EIO;
+		break;
 	}
 
 	return return_status;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 63fca0197..b929fbcc8 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -59,6 +59,10 @@ static enum hns3_reset_level hns3vf_get_reset_level(struct hns3_hw *hw,
 static int hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3vf_dev_configure_vlan(struct rte_eth_dev *dev);
 
+static int hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
+				  struct rte_ether_addr *mac_addr);
+static int hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
+				     struct rte_ether_addr *mac_addr);
 /* set PCI bus mastering */
 static void
 hns3vf_set_bus_master(const struct rte_pci_device *device, bool op)
@@ -134,6 +138,76 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op)
 	return -1;
 }
 
+static int
+hns3vf_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
+				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_REMOVE,
+				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN,
+				false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3vf_add_mc_mac_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		    __attribute__ ((unused)) uint32_t idx,
@@ -144,14 +218,26 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
-				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3vf_add_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s) for vf: %d", mac_str,
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
 			 ret);
 	}
 
@@ -168,15 +254,17 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_REMOVE,
-				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, false,
-				NULL, 0);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_remove_mc_mac_addr(hw, mac_addr);
+	else
+		ret = hns3vf_remove_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s) for vf: %d",
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d",
 			 mac_str, ret);
 	}
 }
@@ -228,39 +316,39 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del)
 {
 	struct hns3_hw *hw = &hns->hw;
 	struct rte_ether_addr *addr;
-	enum hns3_mbx_mac_vlan_subcode opcode;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int ret = 0;
+	int err = 0;
+	int ret;
 	int i;
 
-	if (del)
-		opcode = HNS3_MBX_MAC_VLAN_UC_REMOVE;
-	else
-		opcode = HNS3_MBX_MAC_VLAN_UC_ADD;
 	for (i = 0; i < HNS3_VF_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr);
-		hns3_dbg(hw, "rm mac addr: %s", mac_str);
-		ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST, opcode,
-					addr->addr_bytes, RTE_ETHER_ADDR_LEN,
-					false, NULL, 0);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3vf_remove_mc_mac_addr(hw, addr) :
+			      hns3vf_add_mc_mac_addr(hw, addr);
+		else
+			ret = del ? hns3vf_remove_uc_mac_addr(hw, addr) :
+			      hns3vf_add_uc_mac_addr(hw, addr);
+
 		if (ret) {
-			hns3_err(hw, "Failed to remove mac addr for vf: %d",
-				 ret);
-			break;
+			err = ret;
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
-	return ret;
+	return err;
 }
 
 static int
-hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
 		       struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -279,11 +367,10 @@ hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
 			  struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -302,45 +389,92 @@ hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
-			    struct rte_ether_addr *mc_addr_set,
-			    uint32_t nb_mc_addr)
+hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw,
+			     struct rte_ether_addr *mc_addr_set,
+			     uint32_t nb_mc_addr)
 {
-	struct hns3_adapter *hns = dev->data->dev_private;
-	struct hns3_hw *hw = &hns->hw;
-	struct rte_ether_addr *addr;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int cur_addr_num;
-	int set_addr_num;
-	int num;
-	int ret;
-	int i;
+	struct rte_ether_addr *addr;
+	uint32_t i;
+	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
 	}
 
-	set_addr_num = (int)nb_mc_addr;
-	for (i = 0; i < set_addr_num; i++) {
+	/* Check if input mac addresses are valid */
+	for (i = 0; i < nb_mc_addr; i++) {
 		addr = &mc_addr_set[i];
 		if (!rte_is_multicast_ether_addr(addr)) {
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
+
+		/* Check if there are duplicate addresses */
+		for (j = i + 1; j < nb_mc_addr; j++) {
+			if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. two same addrs(%s).",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_VF_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
+
+	return 0;
+}
+
+static int
+hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mc_addr_set,
+			    uint32_t nb_mc_addr)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_ether_addr *addr;
+	int cur_addr_num;
+	int set_addr_num;
+	int num;
+	int ret;
+	int i;
+
+	ret = hns3vf_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
+	if (ret)
+		return ret;
+
 	rte_spinlock_lock(&hw->lock);
 	cur_addr_num = hw->mc_addrs_num;
 	for (i = 0; i < cur_addr_num; i++) {
 		num = cur_addr_num - i - 1;
 		addr = &hw->mc_addrs[num];
-		ret = hns3vf_remove_mc_mac_addr(hns, addr);
+		ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -349,9 +483,10 @@ hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
 		hw->mc_addrs_num--;
 	}
 
+	set_addr_num = (int)nb_mc_addr;
 	for (i = 0; i < set_addr_num; i++) {
 		addr = &mc_addr_set[i];
-		ret = hns3vf_add_mc_mac_addr(hns, addr);
+		ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -380,9 +515,9 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
 		if (!rte_is_multicast_ether_addr(addr))
 			continue;
 		if (del)
-			ret = hns3vf_remove_mc_mac_addr(hns, addr);
+			ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		else
-			ret = hns3vf_add_mc_mac_addr(hns, addr);
+			ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 06/10] net/hns3: get device capability in primary process
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (4 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 05/10] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 07/10] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit ab2e2e34416371817a21a41fc3def231675d4487 ]

This patch optimizes the code to get device capability in primary
process, and moves the code of getting PCI revision id in order to avoid
evaluating the private hw->revision of shared PMD-specific private data
in slave process.

Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 46 +++++++++++++++++++++++++------
 drivers/net/hns3/hns3_ethdev.h    |  4 +--
 drivers/net/hns3/hns3_ethdev_vf.c | 30 ++++++++++++++++++++
 3 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 217aea4c0..ece02d440 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2783,6 +2783,36 @@ hns3_parse_speed(int speed_cmd, uint32_t *speed)
 	return 0;
 }
 
+static int
+hns3_get_capability(struct hns3_hw *hw)
+{
+	struct rte_pci_device *pci_dev;
+	struct rte_eth_dev *eth_dev;
+	uint16_t device_id;
+	uint8_t revision;
+	int ret;
+
+	eth_dev = &rte_eth_devices[hw->data->port_id];
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	device_id = pci_dev->id.device_id;
+
+	if (device_id == HNS3_DEV_ID_25GE_RDMA ||
+	    device_id == HNS3_DEV_ID_50GE_RDMA ||
+	    device_id == HNS3_DEV_ID_100G_RDMA_MACSEC)
+		hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1);
+
+	/* 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: %d", ret);
+		return -EIO;
+	}
+	hw->revision = revision;
+
+	return 0;
+}
+
 static int
 hns3_get_board_configuration(struct hns3_hw *hw)
 {
@@ -2857,6 +2887,13 @@ hns3_get_configuration(struct hns3_hw *hw)
 		return ret;
 	}
 
+	/* Get device capability */
+	ret = hns3_get_capability(hw);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "failed to get device capability: %d.", ret);
+		return ret;
+	}
+
 	/* Get pf resource */
 	ret = hns3_query_pf_resource(hw);
 	if (ret) {
@@ -5383,11 +5420,8 @@ static const struct hns3_reset_ops hns3_reset_ops = {
 static int
 hns3_dev_init(struct rte_eth_dev *eth_dev)
 {
-	struct rte_device *dev = eth_dev->device;
-	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev);
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint16_t device_id = pci_dev->id.device_id;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -5425,12 +5459,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
 	}
 
 	hw->adapter_state = HNS3_NIC_UNINITIALIZED;
-
-	if (device_id == HNS3_DEV_ID_25GE_RDMA ||
-	    device_id == HNS3_DEV_ID_50GE_RDMA ||
-	    device_id == HNS3_DEV_ID_100G_RDMA_MACSEC)
-		hns3_set_bit(hw->flag, HNS3_DEV_SUPPORT_DCB_B, 1);
-
 	hns->is_vf = false;
 	hw->data = eth_dev->data;
 
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 35e64aa5a..6b2cebe22 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -389,7 +389,7 @@ struct hns3_hw {
 	uint16_t alloc_rss_size;    /* RX queue number per TC */
 	uint16_t tx_qnum_per_tc;    /* TX queue number per TC */
 
-	uint32_t flag;
+	uint32_t capability;
 
 	struct hns3_port_base_vlan_config port_base_vlan_cfg;
 	/*
@@ -520,7 +520,7 @@ struct hns3_adapter {
 #define HNS3_DEV_SUPPORT_DCB_B			0x0
 
 #define hns3_dev_dcb_supported(hw) \
-	hns3_get_bit((hw)->flag, HNS3_DEV_SUPPORT_DCB_B)
+	hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B)
 
 #define HNS3_DEV_PRIVATE_TO_HW(adapter) \
 	(&((struct hns3_adapter *)adapter)->hw)
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index b929fbcc8..847e4c61c 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -940,6 +940,29 @@ hns3vf_interrupt_handler(void *param)
 	hns3vf_enable_irq0(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: %d", ret);
+		return -EIO;
+	}
+	hw->revision = revision;
+
+	return 0;
+}
+
 static int
 hns3vf_check_tqp_info(struct hns3_hw *hw)
 {
@@ -1026,6 +1049,13 @@ hns3vf_get_configuration(struct hns3_hw *hw)
 	hw->mac.media_type = HNS3_MEDIA_TYPE_NONE;
 	hw->rss_dis_flag = false;
 
+	/* Get device capability */
+	ret = hns3vf_get_capability(hw);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "failed to get device capability: %d.", ret);
+		return ret;
+	}
+
 	/* Get queue configuration from PF */
 	ret = hns3vf_get_queue_info(hw);
 	if (ret)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 07/10] net/hns3: report Tx descriptor segment limitations
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (5 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 06/10] net/hns3: get device capability in primary process Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 08/10] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit eb8b3a0d829bc109dfb13de9c8cdeacda5449e69 ]

According to the user manual of Kunpeng920 SoC, the max allowed number
of segments per whole packet is 63 and the max number of segments per
packet is 8 in datapath.

This patch reports the Two segment parameters of Tx descriptor
limitations to DPDK framework.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 2 ++
 drivers/net/hns3/hns3_ethdev_vf.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index ece02d440..baa80e9a4 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2489,6 +2489,8 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
 		.nb_align = HNS3_ALIGN_RING_DESC,
+		.nb_seg_max = HNS3_MAX_TSO_BD_PER_PKT,
+		.nb_mtu_seg_max = HNS3_MAX_NON_TSO_BD_PER_PKT,
 	};
 
 	info->vmdq_queue_num = 0;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 847e4c61c..23a5f23ed 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -826,6 +826,8 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
 		.nb_align = HNS3_ALIGN_RING_DESC,
+		.nb_seg_max = HNS3_MAX_TSO_BD_PER_PKT,
+		.nb_mtu_seg_max = HNS3_MAX_NON_TSO_BD_PER_PKT,
 	};
 
 	info->vmdq_queue_num = 0;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 08/10] net/hns3: fix reassembling multiple segment packets in Tx
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (6 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 07/10] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 09/10] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 10/10] net/bonding: change state machine to defaulted Wei Hu (Xavier)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: "Wei Hu (Xavier)" <xavier.huwei@huawei.com>

[ upstream commit 6c44219f9907a064049d160d366d98bb840724a6 ]

Because of the hardware constraints, hns3 network engine doesn't support
sending packets with more than eight fragments. And hns3 pmd driver
tries to reassemble these kind of packets to meet hardware requirements.
Currently, there are two problems:
1) when the input buffer_len * 8 < pkt_len, the packets are impossible
   to be reassembled into 8 Buffer Descriptors. In this case, the
   packets will be passed to hardware, which eventually causes a
   hardware reset.
2) The meta data in origin packets which are required to fill into the
   descriptor haven't been copied into the reassembled pkts.

This patch adds a check for 1) to ensure such packets will be dropped by
driver and copies useful meta data from the origin packets to the
reassembled packets.

Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_rxtx.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index c1ffa136b..e04f62c9d 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1940,6 +1940,20 @@ hns3_tx_alloc_mbufs(struct hns3_tx_queue *txq, struct rte_mempool *mb_pool,
 	return 0;
 }
 
+static inline void
+hns3_pktmbuf_copy_hdr(struct rte_mbuf *new_pkt, struct rte_mbuf *old_pkt)
+{
+	new_pkt->ol_flags = old_pkt->ol_flags;
+	new_pkt->pkt_len = rte_pktmbuf_pkt_len(old_pkt);
+	new_pkt->outer_l2_len = old_pkt->outer_l2_len;
+	new_pkt->outer_l3_len = old_pkt->outer_l3_len;
+	new_pkt->l2_len = old_pkt->l2_len;
+	new_pkt->l3_len = old_pkt->l3_len;
+	new_pkt->l4_len = old_pkt->l4_len;
+	new_pkt->vlan_tci_outer = old_pkt->vlan_tci_outer;
+	new_pkt->vlan_tci = old_pkt->vlan_tci;
+}
+
 static int
 hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 			struct rte_mbuf **new_pkt)
@@ -1963,9 +1977,11 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 
 	mb_pool = tx_pkt->pool;
 	buf_size = tx_pkt->buf_len - RTE_PKTMBUF_HEADROOM;
-	nb_new_buf = (tx_pkt->pkt_len - 1) / buf_size + 1;
+	nb_new_buf = (rte_pktmbuf_pkt_len(tx_pkt) - 1) / buf_size + 1;
+	if (nb_new_buf > HNS3_MAX_NON_TSO_BD_PER_PKT)
+		return -EINVAL;
 
-	last_buf_len = tx_pkt->pkt_len % buf_size;
+	last_buf_len = rte_pktmbuf_pkt_len(tx_pkt) % buf_size;
 	if (last_buf_len == 0)
 		last_buf_len = buf_size;
 
@@ -1977,7 +1993,7 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 	/* Copy the original packet content to the new mbufs */
 	temp = tx_pkt;
 	s = rte_pktmbuf_mtod(temp, char *);
-	len_s = temp->data_len;
+	len_s = rte_pktmbuf_data_len(temp);
 	temp_new = new_mbuf;
 	for (i = 0; i < nb_new_buf; i++) {
 		d = rte_pktmbuf_mtod(temp_new, char *);
@@ -2000,13 +2016,14 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt,
 				if (temp == NULL)
 					break;
 				s = rte_pktmbuf_mtod(temp, char *);
-				len_s = temp->data_len;
+				len_s = rte_pktmbuf_data_len(temp);
 			}
 		}
 
 		temp_new->data_len = buf_len;
 		temp_new = temp_new->next;
 	}
+	hns3_pktmbuf_copy_hdr(new_mbuf, tx_pkt);
 
 	/* free original mbufs */
 	rte_pktmbuf_free(tx_pkt);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 09/10] app/testpmd: remove hardcoded descriptors limit
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (7 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 08/10] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 10/10] net/bonding: change state machine to defaulted Wei Hu (Xavier)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit 99e040d3adc9ee2284e315219f2a6baee680f4e3 ]

When users configure rxds and txds by used port config cmd based
on testpmd application, it will not be able to configure rxd and
txd according to the max capability range supported by the actual
NIC hardware. Due testpmd defects, it can only configure a fixed
range to 0 to 2048.
The final result is that an incorrect printing prompt appears and
cannot be applied using rxd && txd according to the actual
capabilities supported by the device.
In order to solve the above problems, we modify the testpmd. First
by calling the rte_eth_dev_info_get api to obtain the max and min
rx/tx capability supported by the hns3, and then use this range
to compare with the actual value by users configured and make
reasonable limitation.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c |  11 +--
 app/test-pmd/testpmd.c | 171 +++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d508d1e26..2d18b6caf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1913,18 +1913,13 @@ cmd_config_rx_tx_parsed(void *parsed_result,
 		nb_txq = res->value;
 	}
 	else if (!strcmp(res->name, "rxd")) {
-		if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
-			printf("rxd %d invalid - must be > 0 && <= %d\n",
-					res->value, RTE_TEST_RX_DESC_MAX);
+		if (check_nb_rxd(res->value) != 0)
 			return;
-		}
 		nb_rxd = res->value;
 	} else if (!strcmp(res->name, "txd")) {
-		if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
-			printf("txd %d invalid - must be > 0 && <= %d\n",
-					res->value, RTE_TEST_TX_DESC_MAX);
+		if (check_nb_txd(res->value) != 0)
 			return;
-		}
+
 		nb_txd = res->value;
 	} else {
 		printf("Unknown parameter\n");
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 0ef7ecfe8..8d3b7b2a3 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1071,6 +1071,177 @@ check_nb_txq(queueid_t txq)
 	return 0;
 }
 
+/*
+ * Get the allowed maximum number of RXDs of every rx queue.
+ * *pid return the port id which has minimal value of
+ * max_rxd in all queues of all ports.
+ */
+static uint16_t
+get_allowed_max_nb_rxd(portid_t *pid)
+{
+	uint16_t allowed_max_rxd = UINT16_MAX;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.rx_desc_lim.nb_max < allowed_max_rxd) {
+			allowed_max_rxd = dev_info.rx_desc_lim.nb_max;
+			*pid = pi;
+		}
+	}
+	return allowed_max_rxd;
+}
+
+/*
+ * Get the allowed minimal number of RXDs of every rx queue.
+ * *pid return the port id which has minimal value of
+ * min_rxd in all queues of all ports.
+ */
+static uint16_t
+get_allowed_min_nb_rxd(portid_t *pid)
+{
+	uint16_t allowed_min_rxd = 0;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.rx_desc_lim.nb_min > allowed_min_rxd) {
+			allowed_min_rxd = dev_info.rx_desc_lim.nb_min;
+			*pid = pi;
+		}
+	}
+
+	return allowed_min_rxd;
+}
+
+/*
+ * Check input rxd is valid or not.
+ * If input rxd is not greater than any of maximum number
+ * of RXDs of every Rx queues and is not less than any of
+ * minimal number of RXDs of every Rx queues, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_rxd(queueid_t rxd)
+{
+	uint16_t allowed_max_rxd;
+	uint16_t allowed_min_rxd;
+	portid_t pid = 0;
+
+	allowed_max_rxd = get_allowed_max_nb_rxd(&pid);
+	if (rxd > allowed_max_rxd) {
+		printf("Fail: input rxd (%u) can't be greater "
+		       "than max_rxds (%u) of port %u\n",
+		       rxd,
+		       allowed_max_rxd,
+		       pid);
+		return -1;
+	}
+
+	allowed_min_rxd = get_allowed_min_nb_rxd(&pid);
+	if (rxd < allowed_min_rxd) {
+		printf("Fail: input rxd (%u) can't be less "
+		       "than min_rxds (%u) of port %u\n",
+		       rxd,
+		       allowed_min_rxd,
+		       pid);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Get the allowed maximum number of TXDs of every rx queues.
+ * *pid return the port id which has minimal value of
+ * max_txd in every tx queue.
+ */
+static uint16_t
+get_allowed_max_nb_txd(portid_t *pid)
+{
+	uint16_t allowed_max_txd = UINT16_MAX;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.tx_desc_lim.nb_max < allowed_max_txd) {
+			allowed_max_txd = dev_info.tx_desc_lim.nb_max;
+			*pid = pi;
+		}
+	}
+	return allowed_max_txd;
+}
+
+/*
+ * Get the allowed maximum number of TXDs of every tx queues.
+ * *pid return the port id which has minimal value of
+ * min_txd in every tx queue.
+ */
+static uint16_t
+get_allowed_min_nb_txd(portid_t *pid)
+{
+	uint16_t allowed_min_txd = 0;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.tx_desc_lim.nb_min > allowed_min_txd) {
+			allowed_min_txd = dev_info.tx_desc_lim.nb_min;
+			*pid = pi;
+		}
+	}
+
+	return allowed_min_txd;
+}
+
+/*
+ * Check input txd is valid or not.
+ * If input txd is not greater than any of maximum number
+ * of TXDs of every Rx queues, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_txd(queueid_t txd)
+{
+	uint16_t allowed_max_txd;
+	uint16_t allowed_min_txd;
+	portid_t pid = 0;
+
+	allowed_max_txd = get_allowed_max_nb_txd(&pid);
+	if (txd > allowed_max_txd) {
+		printf("Fail: input txd (%u) can't be greater "
+		       "than max_txds (%u) of port %u\n",
+		       txd,
+		       allowed_max_txd,
+		       pid);
+		return -1;
+	}
+
+	allowed_min_txd = get_allowed_min_nb_txd(&pid);
+	if (txd < allowed_min_txd) {
+		printf("Fail: input txd (%u) can't be less "
+		       "than min_txds (%u) of port %u\n",
+		       txd,
+		       allowed_min_txd,
+		       pid);
+		return -1;
+	}
+	return 0;
+}
+
+
 /*
  * Get the allowed maximum number of hairpin queues.
  * *pid return the port id which has minimal value of
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 0694e1ef8..2b1e9a24f 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -859,6 +859,8 @@ queueid_t get_allowed_max_nb_rxq(portid_t *pid);
 int check_nb_rxq(queueid_t rxq);
 queueid_t get_allowed_max_nb_txq(portid_t *pid);
 int check_nb_txq(queueid_t txq);
+int check_nb_rxd(queueid_t rxd);
+int check_nb_txd(queueid_t txd);
 queueid_t get_allowed_max_nb_hairpinq(portid_t *pid);
 int check_nb_hairpinq(queueid_t hairpinq);
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v2 10/10] net/bonding: change state machine to defaulted
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
                     ` (8 preceding siblings ...)
  2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 09/10] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
@ 2020-08-18  6:49   ` Wei Hu (Xavier)
  9 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  6:49 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Weifeng Li <liweifeng96@126.com>

[ upstream commit 0bf68c660e932e76087dc8c87f8b1dacba89c2be ]

A dpdk bonding 802.3ad network as follows:
+----------+                        +-----------+
|dpdk lacp |bond1.1 <------> bond2.1|switch lacp|
|          |bond1.2 <------> bond2.2|           |
+----------+                        +-----------+
If a fiber optic go wrong about single pass during normal running like
this:
bond1.2 -----> bond2.2 ok
bond1.2 <--x-- bond2.2 error: bond1.2 receive no LACPDU Some packets
			      from switch to dpdk will choose bond2.2
			      and lost.

DPDK lacp state machine will transits to the expired state if no LACPDU
is received before the current_while_timer expires. But if no LACPDU is
received before the current_while_timer expires again, DPDK lacp state
machine has no change. Bond2.2 can not change to inactive depend on the
received LACPDU.
According to IEEE 802.3ad, if no lacpdu is received before the
current_while_timer expires again, the state machine should transits
from expired to defaulted. Bond2.2 will change to inactive depend on the
LACPDU with defaulted state.

This patch adds a state machine change from expired to defaulted when no
lacpdu is received before the current_while_timer expires again
according to IEEE 802.3ad:
If no LACPDU is received before the current_while timer expires again,
the state machine transits to the DEFAULTED state. The record Default
function overwrites the current operational parameters for the Partner
with administratively configured values. This allows configuration of
aggregations and individual links when no protocol partner is present,
while still permitting an active partner to override default settings.
The update_Default_Selected function sets the Selected variable FALSE
if the Link Aggregation Group has changed. Since all operational
parameters are now set to locally administered values there can be no
disagreement as to the Link Aggregation Group, so the Matched variable
is set TRUE.

The relevant description is in the chapter 43.4.12 of the link below:
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=850426

Signed-off-by: Weifeng Li <liweifeng96@126.com>
Acked-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/bonding/eth_bond_8023ad_private.h |  3 +++
 drivers/net/bonding/rte_eth_bond_8023ad.c     | 21 +++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/eth_bond_8023ad_private.h b/drivers/net/bonding/eth_bond_8023ad_private.h
index 6e44ffdb1..9b5738afe 100644
--- a/drivers/net/bonding/eth_bond_8023ad_private.h
+++ b/drivers/net/bonding/eth_bond_8023ad_private.h
@@ -50,6 +50,7 @@
 #define SM_FLAGS_MOVED                      0x0100
 #define SM_FLAGS_PARTNER_SHORT_TIMEOUT      0x0200
 #define SM_FLAGS_NTT                        0x0400
+#define SM_FLAGS_EXPIRED                    0x0800
 
 #define BOND_LINK_FULL_DUPLEX_KEY           0x01
 #define BOND_LINK_SPEED_KEY_10M             0x02
@@ -103,6 +104,8 @@ struct port {
 
 	/** The operational Partner's port parameters */
 	struct port_params partner;
+	/** Partner administrative parameter values */
+	struct port_params partner_admin;
 
 	/* Additional port parameters not listed in documentation */
 	/** State machine flags */
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b24a44686..67ca0730f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -356,16 +356,28 @@ rx_machine(struct bond_dev_private *internals, uint16_t slave_id,
 
 		timer_set(&port->current_while_timer, timeout);
 		ACTOR_STATE_CLR(port, EXPIRED);
+		SM_FLAG_CLR(port, EXPIRED);
 		return; /* No state change */
 	}
 
 	/* If CURRENT state timer is not running (stopped or expired)
 	 * transit to EXPIRED state from DISABLED or CURRENT */
 	if (!timer_is_running(&port->current_while_timer)) {
-		ACTOR_STATE_SET(port, EXPIRED);
-		PARTNER_STATE_CLR(port, SYNCHRONIZATION);
-		PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
-		timer_set(&port->current_while_timer, internals->mode4.short_timeout);
+		if (SM_FLAG(port, EXPIRED)) {
+			port->selected = UNSELECTED;
+			memcpy(&port->partner, &port->partner_admin,
+				sizeof(struct port_params));
+			record_default(port);
+			ACTOR_STATE_CLR(port, EXPIRED);
+			timer_cancel(&port->current_while_timer);
+		} else {
+			SM_FLAG_SET(port, EXPIRED);
+			ACTOR_STATE_SET(port, EXPIRED);
+			PARTNER_STATE_CLR(port, SYNCHRONIZATION);
+			PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
+			timer_set(&port->current_while_timer,
+				internals->mode4.short_timeout);
+		}
 	}
 }
 
@@ -1021,6 +1033,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
 	port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
 
 	memcpy(&port->partner, &initial, sizeof(struct port_params));
+	memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
 
 	/* default states */
 	port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4
  2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
                   ` (25 preceding siblings ...)
  2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
@ 2020-08-18  7:15 ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 1/7] net/hns3: get link status change through mailbox Wei Hu (Xavier)
                     ` (7 more replies)
  26 siblings, 8 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

This series are backport for 19.11.4 about hns3 PMD driver, bonding
and testpmd.

Chengchang Tang (2):
  net/hns3: remove restriction on setting VF MTU
  net/hns3: fix adding multicast MAC address

Hao Chen (1):
  net/hns3: optimize default RSS algorithm

Hongbo Zheng (1):
  net/hns3: get link status change through mailbox

Lijun Ou (2):
  net/hns3: remove unnecessary branch
  app/testpmd: remove hardcoded descriptors limit

Weifeng Li (1):
  net/bonding: change state machine to defaulted

 app/test-pmd/cmdline.c                        |  11 +-
 app/test-pmd/testpmd.c                        | 171 ++++++++++++
 app/test-pmd/testpmd.h                        |   2 +
 drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
 drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
 drivers/net/hns3/hns3_ethdev.c                | 149 +++++++++--
 drivers/net/hns3/hns3_ethdev.h                |   1 +
 drivers/net/hns3/hns3_ethdev_vf.c             | 245 ++++++++++++++----
 drivers/net/hns3/hns3_mbx.c                   |  37 +++
 drivers/net/hns3/hns3_mbx.h                   |   8 +
 drivers/net/hns3/hns3_rss.c                   |  14 +-
 11 files changed, 568 insertions(+), 94 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 1/7] net/hns3: get link status change through mailbox
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 2/7] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Hongbo Zheng <zhenghongbo3@huawei.com>

[ upstream commit 109e4dd1bd7a5f7e0400be974f2b9e18d10cb3a6 ]

Currently, firmware adds the function of sending message to PF driver
through mailbox when the link status is changed, hns3 PMD driver can
usually recognize link state change faster through the message.

And in some extreme cases, this way is not faster than existing method
regularly updating link status by issuing the command every second in PF
driver, because of the parallel processing of mailbox and command
messages in firmware. So we reserve updating link status using timers in
PF driver, and add querying link status by issuing command to the
firmware in '.link_update' ops implementation function named
hns3_dev_link_update to solve the out of date link status.

Signed-off-by: Hongbo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 14 +++++++++++--
 drivers/net/hns3/hns3_ethdev.h |  1 +
 drivers/net/hns3/hns3_mbx.c    | 37 ++++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_mbx.h    |  8 ++++++++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 971f2f900..c31a9328a 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -75,6 +75,7 @@ static enum hns3_reset_level hns3_get_reset_level(struct hns3_adapter *hns,
 static int hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
+static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
@@ -216,6 +217,8 @@ hns3_interrupt_handler(void *param)
 		hns3_schedule_reset(hns);
 	} else if (event_cause == HNS3_VECTOR0_EVENT_RST)
 		hns3_schedule_reset(hns);
+	else if (event_cause == HNS3_VECTOR0_EVENT_MBX)
+		hns3_dev_handle_mbx_msg(hw);
 	else
 		hns3_err(hw, "Received unknown event");
 
@@ -2441,6 +2444,11 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev,
 	struct hns3_mac *mac = &hw->mac;
 	struct rte_eth_link new_link;
 
+	if (!hns3_is_reset_pending(hns)) {
+		hns3_update_speed_duplex(eth_dev);
+		hns3_update_link_status(hw);
+	}
+
 	memset(&new_link, 0, sizeof(new_link));
 	switch (mac->link_speed) {
 	case ETH_SPEED_NUM_10M:
@@ -4067,14 +4075,16 @@ hns3_get_mac_link_status(struct hns3_hw *hw)
 	return !!link_status;
 }
 
-static void
+void
 hns3_update_link_status(struct hns3_hw *hw)
 {
 	int state;
 
 	state = hns3_get_mac_link_status(hw);
-	if (state != hw->mac.link_status)
+	if (state != hw->mac.link_status) {
 		hw->mac.link_status = state;
+		hns3_warn(hw, "Link status change to %s!", state ? "up" : "down");
+	}
 }
 
 static void
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 155099e99..35e64aa5a 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -648,6 +648,7 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
 			 enum rte_filter_op filter_op, void *arg);
 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);
 
 static inline bool
 is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c
index 7b5ef9476..64996c9ae 100644
--- a/drivers/net/hns3/hns3_mbx.c
+++ b/drivers/net/hns3/hns3_mbx.c
@@ -292,6 +292,40 @@ hns3_update_resp_position(struct hns3_hw *hw, uint32_t resp_msg)
 	resp->tail = tail;
 }
 
+static void
+hns3_link_fail_parse(struct hns3_hw *hw, uint8_t link_fail_code)
+{
+	switch (link_fail_code) {
+	case HNS3_MBX_LF_NORMAL:
+		break;
+	case HNS3_MBX_LF_REF_CLOCK_LOST:
+		hns3_warn(hw, "Reference clock lost!");
+		break;
+	case HNS3_MBX_LF_XSFP_TX_DISABLE:
+		hns3_warn(hw, "SFP tx is disabled!");
+		break;
+	case HNS3_MBX_LF_XSFP_ABSENT:
+		hns3_warn(hw, "SFP is absent!");
+		break;
+	default:
+		hns3_warn(hw, "Unknown fail code:%u!", link_fail_code);
+		break;
+	}
+}
+
+static void
+hns3_handle_link_change_event(struct hns3_hw *hw,
+			      struct hns3_mbx_pf_to_vf_cmd *req)
+{
+#define LINK_STATUS_OFFSET     1
+#define LINK_FAIL_CODE_OFFSET  2
+
+	if (!req->msg[LINK_STATUS_OFFSET])
+		hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]);
+
+	hns3_update_link_status(hw);
+}
+
 void
 hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 {
@@ -347,6 +381,9 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 
 			hns3_mbx_handler(hw);
 			break;
+		case HNS3_MBX_PUSH_LINK_STATUS:
+			hns3_handle_link_change_event(hw, req);
+			break;
 		default:
 			hns3_err(hw,
 				 "VF received unsupported(%d) mbx msg from PF",
diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h
index 7bcfbbebc..b01eaacc3 100644
--- a/drivers/net/hns3/hns3_mbx.h
+++ b/drivers/net/hns3/hns3_mbx.h
@@ -42,6 +42,7 @@ enum HNS3_MBX_OPCODE {
 
 	HNS3_MBX_HANDLE_VF_TBL = 38,    /* (VF -> PF) store/clear hw cfg tbl */
 	HNS3_MBX_GET_RING_VECTOR_MAP,   /* (VF -> PF) get ring-to-vector map */
+	HNS3_MBX_PUSH_LINK_STATUS = 201, /* (IMP -> PF) get port link status */
 };
 
 /* below are per-VF mac-vlan subcodes */
@@ -65,6 +66,13 @@ enum hns3_mbx_tbl_cfg_subcode {
 	HNS3_MBX_VPORT_LIST_CLEAR = 0,
 };
 
+enum hns3_mbx_link_fail_subcode {
+	HNS3_MBX_LF_NORMAL = 0,
+	HNS3_MBX_LF_REF_CLOCK_LOST,
+	HNS3_MBX_LF_XSFP_TX_DISABLE,
+	HNS3_MBX_LF_XSFP_ABSENT,
+};
+
 #define HNS3_MBX_MAX_MSG_SIZE	16
 #define HNS3_MBX_MAX_RESP_DATA_SIZE	8
 #define HNS3_MBX_RING_MAP_BASIC_MSG_NUM	3
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 2/7] net/hns3: optimize default RSS algorithm
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 1/7] net/hns3: get link status change through mailbox Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 3/7] net/hns3: remove unnecessary branch Wei Hu (Xavier)
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Hao Chen <chenhao164@huawei.com>

[ upstream commit 8834849a9518db9cc79f5585ce15c4630ff0c0c9 ]

This patch changed the default algorithm of RSS from simle_xor to
toeplitz because toeplitz is used more frequently by upper applications
such as ceph.

Signed-off-by: Hao Chen <chenhao164@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_rss.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c
index f19b79928..a6cab29c9 100644
--- a/drivers/net/hns3/hns3_rss.c
+++ b/drivers/net/hns3/hns3_rss.c
@@ -211,7 +211,11 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw,
 			req->ipv6_fragment_en |= HNS3_IP_OTHER_BIT_MASK;
 			break;
 		default:
-			/* Other unsupported flow types won't change tuples */
+			/*
+			 * rss_hf doesn't include unsupported flow types
+			 * because the API framework has checked it, and
+			 * this branch will never go unless rss_hf is zero.
+			 */
 			break;
 		}
 	}
@@ -251,8 +255,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 	struct hns3_hw *hw = &hns->hw;
 	struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets;
 	struct hns3_rss_conf *rss_cfg = &hw->rss_info;
-	uint8_t algo = rss_cfg->conf.func;
 	uint8_t key_len = rss_conf->rss_key_len;
+	uint8_t algo;
 	uint64_t rss_hf = rss_conf->rss_hf;
 	uint8_t *key = rss_conf->rss_key;
 	int ret;
@@ -288,6 +292,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev,
 			ret = -EINVAL;
 			goto conf_err;
 		}
+		algo = rss_cfg->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR ?
+			HNS3_RSS_HASH_ALGO_SIMPLE : HNS3_RSS_HASH_ALGO_TOEPLITZ;
 		ret = hns3_set_rss_algo_key(hw, algo, key);
 		if (ret)
 			goto conf_err;
@@ -505,7 +511,9 @@ hns3_set_default_rss_args(struct hns3_hw *hw)
 	int i;
 
 	/* Default hash algorithm */
-	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+	rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+
+	/* Default RSS key */
 	memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE);
 
 	/* Initialize RSS indirection table */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 3/7] net/hns3: remove unnecessary branch
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 1/7] net/hns3: get link status change through mailbox Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 2/7] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 4/7] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit d13a7447a131a3a7078caf1d14e674e8add1d0a5 ]

Because the rte layer of DPDK framework has already processed the case
when the idx is zero before calling the '.mac_addr_remove' ops function,
the input parameter named idx can not be zero in the '.mac_addr_remove'
function. This patch removes unnecessary branch process to check whether
input parameter named idx is zero in the '.mac_addr_remove' ops
implementation function named hns3_remove_mac_addr.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index c31a9328a..128cd793d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -1531,8 +1531,6 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 		return;
 	}
 
-	if (idx == 0)
-		hw->mac.default_addr_setted = false;
 	rte_spinlock_unlock(&hw->lock);
 }
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 4/7] net/hns3: remove restriction on setting VF MTU
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
                     ` (2 preceding siblings ...)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 3/7] net/hns3: remove unnecessary branch Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 5/7] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit 4bf2c84bd88691bbb9cdc39a8bcf597537abfa80 ]

The hns3 PF/VF devices on the same port share the hardware MTU
configuration. Currently, we send mailbox to inform hns3 PF kernel
ethdev driver to finish hardware MTU configuration in hns3 VF PMD
driver, there is no need to stop the port for hns3 VF device, and
the MTU value issued by hns3 VF PMD driver must be less than or
equal to PF's MTU.

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/hns3/hns3_ethdev_vf.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 5e5da8685..63fca0197 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -606,12 +606,14 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	uint32_t frame_size = mtu + HNS3_ETH_OVERHEAD;
 	int ret;
 
-	if (dev->data->dev_started) {
-		hns3_err(hw, "Failed to set mtu, port %u must be stopped "
-			 "before configuration", dev->data->port_id);
-		return -EBUSY;
-	}
-
+	/*
+	 * The hns3 PF/VF devices on the same port share the hardware MTU
+	 * configuration. Currently, we send mailbox to inform hns3 PF kernel
+	 * ethdev driver to finish hardware MTU configuration in hns3 VF PMD
+	 * driver, there is no need to stop the port for hns3 VF device, and the
+	 * MTU value issued by hns3 VF PMD driver must be less than or equal to
+	 * PF's MTU.
+	 */
 	if (rte_atomic16_read(&hw->reset.resetting)) {
 		hns3_err(hw, "Failed to set mtu during resetting");
 		return -EIO;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 5/7] net/hns3: fix adding multicast MAC address
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
                     ` (3 preceding siblings ...)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 4/7] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 6/7] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit fb94f359481ff6d53f6b7850d3ad393addfb6afb ]

Currently, when upper application calls the rte_eth_dev_mac_addr_add API
function to add a MC mac address based on hns3 PF/VF device, it will
fail.

In hns3 network engine adding UC and MC mac address with different
commands with firmware. We need to determine whether the input address
is a UC or a MC address to call different commands in the
'.mac_addr_add' and '.mac_addr_remove' ops implementation functions in
hns3 PF and VF driver as below:
  hns3_add_mac_addr
  hns3vf_add_uc_mac_addr
  hns3_remove_mac_addr
  hns3vf_remove_mac_addr

By the way, it is recommended calling the rte_eth_dev_set_mc_addr_list API
function to set the MC mac address, because using the
rte_eth_dev_mac_addr_add API function to set MC mac address may affect the
specifications of UC mac addresses.

Fixes: 7d7f9f80bbfb ("net/hns3: support MAC address related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 133 ++++++++++++++---
 drivers/net/hns3/hns3_ethdev_vf.c | 231 +++++++++++++++++++++++-------
 2 files changed, 295 insertions(+), 69 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 128cd793d..217aea4c0 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -77,6 +77,11 @@ static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
 static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
+static int hns3_add_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+static int hns3_remove_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
 {
@@ -1459,6 +1464,53 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	return ret;
 }
 
+static int
+hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3_add_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_remove_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to remove mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		  uint32_t idx, __attribute__ ((unused)) uint32_t pool)
@@ -1468,12 +1520,27 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_add_uc_addr_common(hw, mac_addr);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_add_uc_addr_common(hw, mac_addr);
+
 	if (ret) {
 		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
+			 ret);
 		return ret;
 	}
 
@@ -1495,7 +1562,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Remove unicast mac addr err! addr(%s) invalid",
+		hns3_err(hw, "remove unicast mac addr err! addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1522,16 +1589,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_remove_uc_addr_common(hw, mac_addr);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_remove_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_remove_uc_addr_common(hw, mac_addr);
+	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
-		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s): %d", mac_str, ret);
-		return;
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,
+			 ret);
 	}
-
-	rte_spinlock_unlock(&hw->lock);
 }
 
 static int
@@ -1632,19 +1701,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
 
 	for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		if (del)
-			ret = hns3_remove_uc_addr_common(hw, addr);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3_remove_mc_addr(hw, addr) :
+			      hns3_add_mc_addr(hw, addr);
 		else
-			ret = hns3_add_uc_addr_common(hw, addr);
+			ret = del ? hns3_remove_uc_addr_common(hw, addr) :
+			      hns3_add_uc_addr_common(hw, addr);
+
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
-			hns3_dbg(hw,
-				 "Failed to %s mac addr(%s). ret:%d i:%d",
-				 del ? "remove" : "restore", mac_str, ret, i);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
 	return err;
@@ -1691,7 +1763,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_multicast_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr, addr(%s) invalid",
+		hns3_err(hw, "failed to add mc mac addr, addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1720,7 +1792,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 			hns3_err(hw, "mc mac vlan table is full");
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mc mac addr(%s): %d", mac_str, ret);
 	}
 
 	return ret;
@@ -1785,7 +1857,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
@@ -1798,7 +1870,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
@@ -1809,12 +1881,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 				rte_ether_format_addr(mac_str,
 						      RTE_ETHER_ADDR_FMT_SIZE,
 						      addr);
-				hns3_err(hw, "Failed to set mc mac addr, "
+				hns3_err(hw, "failed to set mc mac addr, "
 					 "addrs invalid. two same addrs(%s).",
 					 mac_str);
 				return -EINVAL;
 			}
 		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
 
 	return 0;
@@ -3597,6 +3687,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code)
 			     "add mac ethertype failed for undefined, code=%d.",
 			     resp_code);
 		return_status = -EIO;
+		break;
 	}
 
 	return return_status;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 63fca0197..b929fbcc8 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -59,6 +59,10 @@ static enum hns3_reset_level hns3vf_get_reset_level(struct hns3_hw *hw,
 static int hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3vf_dev_configure_vlan(struct rte_eth_dev *dev);
 
+static int hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
+				  struct rte_ether_addr *mac_addr);
+static int hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
+				     struct rte_ether_addr *mac_addr);
 /* set PCI bus mastering */
 static void
 hns3vf_set_bus_master(const struct rte_pci_device *device, bool op)
@@ -134,6 +138,76 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op)
 	return -1;
 }
 
+static int
+hns3vf_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
+				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_REMOVE,
+				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN,
+				false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3vf_add_mc_mac_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		    __attribute__ ((unused)) uint32_t idx,
@@ -144,14 +218,26 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
-				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3vf_add_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s) for vf: %d", mac_str,
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
 			 ret);
 	}
 
@@ -168,15 +254,17 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_REMOVE,
-				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, false,
-				NULL, 0);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_remove_mc_mac_addr(hw, mac_addr);
+	else
+		ret = hns3vf_remove_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s) for vf: %d",
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d",
 			 mac_str, ret);
 	}
 }
@@ -228,39 +316,39 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del)
 {
 	struct hns3_hw *hw = &hns->hw;
 	struct rte_ether_addr *addr;
-	enum hns3_mbx_mac_vlan_subcode opcode;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int ret = 0;
+	int err = 0;
+	int ret;
 	int i;
 
-	if (del)
-		opcode = HNS3_MBX_MAC_VLAN_UC_REMOVE;
-	else
-		opcode = HNS3_MBX_MAC_VLAN_UC_ADD;
 	for (i = 0; i < HNS3_VF_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr);
-		hns3_dbg(hw, "rm mac addr: %s", mac_str);
-		ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST, opcode,
-					addr->addr_bytes, RTE_ETHER_ADDR_LEN,
-					false, NULL, 0);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3vf_remove_mc_mac_addr(hw, addr) :
+			      hns3vf_add_mc_mac_addr(hw, addr);
+		else
+			ret = del ? hns3vf_remove_uc_mac_addr(hw, addr) :
+			      hns3vf_add_uc_mac_addr(hw, addr);
+
 		if (ret) {
-			hns3_err(hw, "Failed to remove mac addr for vf: %d",
-				 ret);
-			break;
+			err = ret;
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
-	return ret;
+	return err;
 }
 
 static int
-hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
 		       struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -279,11 +367,10 @@ hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
 			  struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -302,45 +389,92 @@ hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
-			    struct rte_ether_addr *mc_addr_set,
-			    uint32_t nb_mc_addr)
+hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw,
+			     struct rte_ether_addr *mc_addr_set,
+			     uint32_t nb_mc_addr)
 {
-	struct hns3_adapter *hns = dev->data->dev_private;
-	struct hns3_hw *hw = &hns->hw;
-	struct rte_ether_addr *addr;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int cur_addr_num;
-	int set_addr_num;
-	int num;
-	int ret;
-	int i;
+	struct rte_ether_addr *addr;
+	uint32_t i;
+	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
 	}
 
-	set_addr_num = (int)nb_mc_addr;
-	for (i = 0; i < set_addr_num; i++) {
+	/* Check if input mac addresses are valid */
+	for (i = 0; i < nb_mc_addr; i++) {
 		addr = &mc_addr_set[i];
 		if (!rte_is_multicast_ether_addr(addr)) {
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
+
+		/* Check if there are duplicate addresses */
+		for (j = i + 1; j < nb_mc_addr; j++) {
+			if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. two same addrs(%s).",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_VF_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
+
+	return 0;
+}
+
+static int
+hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mc_addr_set,
+			    uint32_t nb_mc_addr)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_ether_addr *addr;
+	int cur_addr_num;
+	int set_addr_num;
+	int num;
+	int ret;
+	int i;
+
+	ret = hns3vf_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
+	if (ret)
+		return ret;
+
 	rte_spinlock_lock(&hw->lock);
 	cur_addr_num = hw->mc_addrs_num;
 	for (i = 0; i < cur_addr_num; i++) {
 		num = cur_addr_num - i - 1;
 		addr = &hw->mc_addrs[num];
-		ret = hns3vf_remove_mc_mac_addr(hns, addr);
+		ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -349,9 +483,10 @@ hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
 		hw->mc_addrs_num--;
 	}
 
+	set_addr_num = (int)nb_mc_addr;
 	for (i = 0; i < set_addr_num; i++) {
 		addr = &mc_addr_set[i];
-		ret = hns3vf_add_mc_mac_addr(hns, addr);
+		ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -380,9 +515,9 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
 		if (!rte_is_multicast_ether_addr(addr))
 			continue;
 		if (del)
-			ret = hns3vf_remove_mc_mac_addr(hns, addr);
+			ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		else
-			ret = hns3vf_add_mc_mac_addr(hns, addr);
+			ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 6/7] app/testpmd: remove hardcoded descriptors limit
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
                     ` (4 preceding siblings ...)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 5/7] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 7/7] net/bonding: change state machine to defaulted Wei Hu (Xavier)
  2020-08-18 18:00   ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Luca Boccassi
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Lijun Ou <oulijun@huawei.com>

[ upstream commit 99e040d3adc9ee2284e315219f2a6baee680f4e3 ]

When users configure rxds and txds by used port config cmd based
on testpmd application, it will not be able to configure rxd and
txd according to the max capability range supported by the actual
NIC hardware. Due testpmd defects, it can only configure a fixed
range to 0 to 2048.
The final result is that an incorrect printing prompt appears and
cannot be applied using rxd && txd according to the actual
capabilities supported by the device.
In order to solve the above problems, we modify the testpmd. First
by calling the rte_eth_dev_info_get api to obtain the max and min
rx/tx capability supported by the hns3, and then use this range
to compare with the actual value by users configured and make
reasonable limitation.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c |  11 +--
 app/test-pmd/testpmd.c | 171 +++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index d508d1e26..2d18b6caf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1913,18 +1913,13 @@ cmd_config_rx_tx_parsed(void *parsed_result,
 		nb_txq = res->value;
 	}
 	else if (!strcmp(res->name, "rxd")) {
-		if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
-			printf("rxd %d invalid - must be > 0 && <= %d\n",
-					res->value, RTE_TEST_RX_DESC_MAX);
+		if (check_nb_rxd(res->value) != 0)
 			return;
-		}
 		nb_rxd = res->value;
 	} else if (!strcmp(res->name, "txd")) {
-		if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
-			printf("txd %d invalid - must be > 0 && <= %d\n",
-					res->value, RTE_TEST_TX_DESC_MAX);
+		if (check_nb_txd(res->value) != 0)
 			return;
-		}
+
 		nb_txd = res->value;
 	} else {
 		printf("Unknown parameter\n");
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 0ef7ecfe8..8d3b7b2a3 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1071,6 +1071,177 @@ check_nb_txq(queueid_t txq)
 	return 0;
 }
 
+/*
+ * Get the allowed maximum number of RXDs of every rx queue.
+ * *pid return the port id which has minimal value of
+ * max_rxd in all queues of all ports.
+ */
+static uint16_t
+get_allowed_max_nb_rxd(portid_t *pid)
+{
+	uint16_t allowed_max_rxd = UINT16_MAX;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.rx_desc_lim.nb_max < allowed_max_rxd) {
+			allowed_max_rxd = dev_info.rx_desc_lim.nb_max;
+			*pid = pi;
+		}
+	}
+	return allowed_max_rxd;
+}
+
+/*
+ * Get the allowed minimal number of RXDs of every rx queue.
+ * *pid return the port id which has minimal value of
+ * min_rxd in all queues of all ports.
+ */
+static uint16_t
+get_allowed_min_nb_rxd(portid_t *pid)
+{
+	uint16_t allowed_min_rxd = 0;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.rx_desc_lim.nb_min > allowed_min_rxd) {
+			allowed_min_rxd = dev_info.rx_desc_lim.nb_min;
+			*pid = pi;
+		}
+	}
+
+	return allowed_min_rxd;
+}
+
+/*
+ * Check input rxd is valid or not.
+ * If input rxd is not greater than any of maximum number
+ * of RXDs of every Rx queues and is not less than any of
+ * minimal number of RXDs of every Rx queues, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_rxd(queueid_t rxd)
+{
+	uint16_t allowed_max_rxd;
+	uint16_t allowed_min_rxd;
+	portid_t pid = 0;
+
+	allowed_max_rxd = get_allowed_max_nb_rxd(&pid);
+	if (rxd > allowed_max_rxd) {
+		printf("Fail: input rxd (%u) can't be greater "
+		       "than max_rxds (%u) of port %u\n",
+		       rxd,
+		       allowed_max_rxd,
+		       pid);
+		return -1;
+	}
+
+	allowed_min_rxd = get_allowed_min_nb_rxd(&pid);
+	if (rxd < allowed_min_rxd) {
+		printf("Fail: input rxd (%u) can't be less "
+		       "than min_rxds (%u) of port %u\n",
+		       rxd,
+		       allowed_min_rxd,
+		       pid);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Get the allowed maximum number of TXDs of every rx queues.
+ * *pid return the port id which has minimal value of
+ * max_txd in every tx queue.
+ */
+static uint16_t
+get_allowed_max_nb_txd(portid_t *pid)
+{
+	uint16_t allowed_max_txd = UINT16_MAX;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.tx_desc_lim.nb_max < allowed_max_txd) {
+			allowed_max_txd = dev_info.tx_desc_lim.nb_max;
+			*pid = pi;
+		}
+	}
+	return allowed_max_txd;
+}
+
+/*
+ * Get the allowed maximum number of TXDs of every tx queues.
+ * *pid return the port id which has minimal value of
+ * min_txd in every tx queue.
+ */
+static uint16_t
+get_allowed_min_nb_txd(portid_t *pid)
+{
+	uint16_t allowed_min_txd = 0;
+	portid_t pi;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_FOREACH_DEV(pi) {
+		if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
+			continue;
+
+		if (dev_info.tx_desc_lim.nb_min > allowed_min_txd) {
+			allowed_min_txd = dev_info.tx_desc_lim.nb_min;
+			*pid = pi;
+		}
+	}
+
+	return allowed_min_txd;
+}
+
+/*
+ * Check input txd is valid or not.
+ * If input txd is not greater than any of maximum number
+ * of TXDs of every Rx queues, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_txd(queueid_t txd)
+{
+	uint16_t allowed_max_txd;
+	uint16_t allowed_min_txd;
+	portid_t pid = 0;
+
+	allowed_max_txd = get_allowed_max_nb_txd(&pid);
+	if (txd > allowed_max_txd) {
+		printf("Fail: input txd (%u) can't be greater "
+		       "than max_txds (%u) of port %u\n",
+		       txd,
+		       allowed_max_txd,
+		       pid);
+		return -1;
+	}
+
+	allowed_min_txd = get_allowed_min_nb_txd(&pid);
+	if (txd < allowed_min_txd) {
+		printf("Fail: input txd (%u) can't be less "
+		       "than min_txds (%u) of port %u\n",
+		       txd,
+		       allowed_min_txd,
+		       pid);
+		return -1;
+	}
+	return 0;
+}
+
+
 /*
  * Get the allowed maximum number of hairpin queues.
  * *pid return the port id which has minimal value of
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 0694e1ef8..2b1e9a24f 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -859,6 +859,8 @@ queueid_t get_allowed_max_nb_rxq(portid_t *pid);
 int check_nb_rxq(queueid_t rxq);
 queueid_t get_allowed_max_nb_txq(portid_t *pid);
 int check_nb_txq(queueid_t txq);
+int check_nb_rxd(queueid_t rxd);
+int check_nb_txd(queueid_t txd);
 queueid_t get_allowed_max_nb_hairpinq(portid_t *pid);
 int check_nb_hairpinq(queueid_t hairpinq);
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [dpdk-stable] [PATCH v3 7/7] net/bonding: change state machine to defaulted
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
                     ` (5 preceding siblings ...)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 6/7] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
@ 2020-08-18  7:15   ` Wei Hu (Xavier)
  2020-08-18 18:00   ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Luca Boccassi
  7 siblings, 0 replies; 49+ messages in thread
From: Wei Hu (Xavier) @ 2020-08-18  7:15 UTC (permalink / raw)
  To: stable, bluca; +Cc: xavier.huwei

From: Weifeng Li <liweifeng96@126.com>

[ upstream commit 0bf68c660e932e76087dc8c87f8b1dacba89c2be ]

A dpdk bonding 802.3ad network as follows:
+----------+                        +-----------+
|dpdk lacp |bond1.1 <------> bond2.1|switch lacp|
|          |bond1.2 <------> bond2.2|           |
+----------+                        +-----------+
If a fiber optic go wrong about single pass during normal running like
this:
bond1.2 -----> bond2.2 ok
bond1.2 <--x-- bond2.2 error: bond1.2 receive no LACPDU Some packets
			      from switch to dpdk will choose bond2.2
			      and lost.

DPDK lacp state machine will transits to the expired state if no LACPDU
is received before the current_while_timer expires. But if no LACPDU is
received before the current_while_timer expires again, DPDK lacp state
machine has no change. Bond2.2 can not change to inactive depend on the
received LACPDU.
According to IEEE 802.3ad, if no lacpdu is received before the
current_while_timer expires again, the state machine should transits
from expired to defaulted. Bond2.2 will change to inactive depend on the
LACPDU with defaulted state.

This patch adds a state machine change from expired to defaulted when no
lacpdu is received before the current_while_timer expires again
according to IEEE 802.3ad:
If no LACPDU is received before the current_while timer expires again,
the state machine transits to the DEFAULTED state. The record Default
function overwrites the current operational parameters for the Partner
with administratively configured values. This allows configuration of
aggregations and individual links when no protocol partner is present,
while still permitting an active partner to override default settings.
The update_Default_Selected function sets the Selected variable FALSE
if the Link Aggregation Group has changed. Since all operational
parameters are now set to locally administered values there can be no
disagreement as to the Link Aggregation Group, so the Matched variable
is set TRUE.

The relevant description is in the chapter 43.4.12 of the link below:
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=850426

Signed-off-by: Weifeng Li <liweifeng96@126.com>
Acked-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
---
 drivers/net/bonding/eth_bond_8023ad_private.h |  3 +++
 drivers/net/bonding/rte_eth_bond_8023ad.c     | 21 +++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/eth_bond_8023ad_private.h b/drivers/net/bonding/eth_bond_8023ad_private.h
index 6e44ffdb1..9b5738afe 100644
--- a/drivers/net/bonding/eth_bond_8023ad_private.h
+++ b/drivers/net/bonding/eth_bond_8023ad_private.h
@@ -50,6 +50,7 @@
 #define SM_FLAGS_MOVED                      0x0100
 #define SM_FLAGS_PARTNER_SHORT_TIMEOUT      0x0200
 #define SM_FLAGS_NTT                        0x0400
+#define SM_FLAGS_EXPIRED                    0x0800
 
 #define BOND_LINK_FULL_DUPLEX_KEY           0x01
 #define BOND_LINK_SPEED_KEY_10M             0x02
@@ -103,6 +104,8 @@ struct port {
 
 	/** The operational Partner's port parameters */
 	struct port_params partner;
+	/** Partner administrative parameter values */
+	struct port_params partner_admin;
 
 	/* Additional port parameters not listed in documentation */
 	/** State machine flags */
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b24a44686..67ca0730f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -356,16 +356,28 @@ rx_machine(struct bond_dev_private *internals, uint16_t slave_id,
 
 		timer_set(&port->current_while_timer, timeout);
 		ACTOR_STATE_CLR(port, EXPIRED);
+		SM_FLAG_CLR(port, EXPIRED);
 		return; /* No state change */
 	}
 
 	/* If CURRENT state timer is not running (stopped or expired)
 	 * transit to EXPIRED state from DISABLED or CURRENT */
 	if (!timer_is_running(&port->current_while_timer)) {
-		ACTOR_STATE_SET(port, EXPIRED);
-		PARTNER_STATE_CLR(port, SYNCHRONIZATION);
-		PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
-		timer_set(&port->current_while_timer, internals->mode4.short_timeout);
+		if (SM_FLAG(port, EXPIRED)) {
+			port->selected = UNSELECTED;
+			memcpy(&port->partner, &port->partner_admin,
+				sizeof(struct port_params));
+			record_default(port);
+			ACTOR_STATE_CLR(port, EXPIRED);
+			timer_cancel(&port->current_while_timer);
+		} else {
+			SM_FLAG_SET(port, EXPIRED);
+			ACTOR_STATE_SET(port, EXPIRED);
+			PARTNER_STATE_CLR(port, SYNCHRONIZATION);
+			PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
+			timer_set(&port->current_while_timer,
+				internals->mode4.short_timeout);
+		}
 	}
 }
 
@@ -1021,6 +1033,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
 	port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
 
 	memcpy(&port->partner, &initial, sizeof(struct port_params));
+	memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
 
 	/* default states */
 	port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4
  2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
                     ` (6 preceding siblings ...)
  2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 7/7] net/bonding: change state machine to defaulted Wei Hu (Xavier)
@ 2020-08-18 18:00   ` Luca Boccassi
  7 siblings, 0 replies; 49+ messages in thread
From: Luca Boccassi @ 2020-08-18 18:00 UTC (permalink / raw)
  To: Wei Hu (Xavier), stable; +Cc: xavier.huwei

On Tue, 2020-08-18 at 15:15 +0800, Wei Hu (Xavier) wrote:
> This series are backport for 19.11.4 about hns3 PMD driver, bonding
> and testpmd.
> 
> Chengchang Tang (2):
>   net/hns3: remove restriction on setting VF MTU
>   net/hns3: fix adding multicast MAC address
> 
> Hao Chen (1):
>   net/hns3: optimize default RSS algorithm
> 
> Hongbo Zheng (1):
>   net/hns3: get link status change through mailbox
> 
> Lijun Ou (2):
>   net/hns3: remove unnecessary branch
>   app/testpmd: remove hardcoded descriptors limit
> 
> Weifeng Li (1):
>   net/bonding: change state machine to defaulted
> 
>  app/test-pmd/cmdline.c                        |  11 +-
>  app/test-pmd/testpmd.c                        | 171 ++++++++++++
>  app/test-pmd/testpmd.h                        |   2 +
>  drivers/net/bonding/eth_bond_8023ad_private.h |   3 +
>  drivers/net/bonding/rte_eth_bond_8023ad.c     |  21 +-
>  drivers/net/hns3/hns3_ethdev.c                | 149 +++++++++--
>  drivers/net/hns3/hns3_ethdev.h                |   1 +
>  drivers/net/hns3/hns3_ethdev_vf.c             | 245 ++++++++++++++
> ----
>  drivers/net/hns3/hns3_mbx.c                   |  37 +++
>  drivers/net/hns3/hns3_mbx.h                   |   8 +
>  drivers/net/hns3/hns3_rss.c                   |  14 +-
>  11 files changed, 568 insertions(+), 94 deletions(-)

Thanks, applied and pushed.

-- 
Kind regards,
Luca Boccassi

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2020-08-18 18:00 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 01/24] net/hns3: get link status change through mailbox Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 02/24] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 03/24] net/hns3: support setting VF MAC address by PF driver Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 04/24] net/hns3: remove unnecessary branch Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 05/24] net/hns3: support TSO Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 06/24] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 07/24] net/hns3: support promiscuous and allmulticast mode for VF Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 08/24] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 09/24] net/hns3: get Rx/Tx queue fbd in xstats Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 10/24] net/hns3: get Tx abnormal errors " Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 11/24] net/hns3: get PCI revision ID Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 12/24] net/hns3: check TSO segment size during Tx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 13/24] net/hns3: support symmetric RSS Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 14/24] net/hns3: support LRO Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 15/24] net/hns3: decrease non-nearby memory access in Rx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 16/24] net/hns3: support setting VF PVID by PF driver Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 17/24] net/hns3: get device capability in primary process Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 18/24] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 19/24] net/hns3: cleanup duplicated code on processing TSO in Tx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 20/24] net/hns3: support copper media type Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 21/24] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 22/24] net/hns3: fix inserted VLAN tag position " Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 23/24] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 24/24] net/bonding: change state machine to defaulted Wei Hu (Xavier)
2020-08-17  9:51 ` [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Luca Boccassi
2020-08-17 11:54   ` Wei Hu (Xavier)
2020-08-17 13:42     ` Luca Boccassi
2020-08-18  3:25       ` Wei Hu (Xavier)
2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 01/10] net/hns3: get link status change through mailbox Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 02/10] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 03/10] net/hns3: remove unnecessary branch Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 04/10] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 05/10] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 06/10] net/hns3: get device capability in primary process Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 07/10] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 08/10] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 09/10] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 10/10] net/bonding: change state machine to defaulted Wei Hu (Xavier)
2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 1/7] net/hns3: get link status change through mailbox Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 2/7] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 3/7] net/hns3: remove unnecessary branch Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 4/7] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 5/7] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 6/7] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 7/7] net/bonding: change state machine to defaulted Wei Hu (Xavier)
2020-08-18 18:00   ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Luca Boccassi

patches for DPDK stable branches

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/stable/0 stable/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 stable stable/ https://inbox.dpdk.org/stable \
		stable@dpdk.org
	public-inbox-index stable

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.stable


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git