diff --git a/0001-dpdk-add-secure-compile-option-and-fPIC-option.patch b/0001-dpdk-add-secure-compile-option-and-fPIC-option.patch deleted file mode 100644 index 0ac0273..0000000 --- a/0001-dpdk-add-secure-compile-option-and-fPIC-option.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 62729b425f3b3a9ccb53b7a57f3dcc0db76d039e Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:10:51 +0800 -Subject: [PATCH] dpdk: - add-secure-compile-option-and-compile-with-fPIC-for-static-lib - -Signed-off-by: zhuhengbo ---- - lib/librte_eal/common/include/rte_log.h | 1 + - mk/rte.lib.mk | 1 + - mk/target/generic/rte.vars.mk | 2 ++ - 3 files changed, 4 insertions(+) - -diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h -index 1bb0e66..6426ea2 100644 ---- a/lib/librte_eal/common/include/rte_log.h -+++ b/lib/librte_eal/common/include/rte_log.h -@@ -311,6 +311,7 @@ int rte_log(uint32_t level, uint32_t logtype, const char *format, ...) - * - Negative on error. - */ - int rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap) -+ __attribute__((weak)) - __attribute__((format(printf,3,0))); - - /** -diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk -index 655a1b1..4516d1c 100644 ---- a/mk/rte.lib.mk -+++ b/mk/rte.lib.mk -@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/internal/rte.install-pre.mk - include $(RTE_SDK)/mk/internal/rte.clean-pre.mk - include $(RTE_SDK)/mk/internal/rte.build-pre.mk - -+CFLAGS += -fPIC - EXTLIB_BUILD ?= n - - # VPATH contains at least SRCDIR -diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk -index 3747221..bf3f4ff 100644 ---- a/mk/target/generic/rte.vars.mk -+++ b/mk/target/generic/rte.vars.mk -@@ -75,6 +75,8 @@ ifeq ($(KERNELRELEASE),) - include $(RTE_SDK)/mk/rte.cpuflags.mk - - # merge all CFLAGS -+CPU_CFLAGS += -fPIE -pie -fPIC -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -Wall -+CPU_CFLAGS += -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines - CFLAGS := $(CPU_CFLAGS) $(EXECENV_CFLAGS) $(TOOLCHAIN_CFLAGS) $(MACHINE_CFLAGS) - CFLAGS += $(TARGET_CFLAGS) - --- -2.19.1 - diff --git a/0001-net-hns3-adjust-MAC-address-logging.patch b/0001-net-hns3-adjust-MAC-address-logging.patch new file mode 100644 index 0000000..0258b34 --- /dev/null +++ b/0001-net-hns3-adjust-MAC-address-logging.patch @@ -0,0 +1,396 @@ +From 8124e9841e2563dc916d4c8b0fce83d1ae470b85 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Thu, 10 Dec 2020 20:48:42 +0800 +Subject: [PATCH 001/189] net/hns3: adjust MAC address logging + +Here the printing of MAC addresses is adjusted. After the +modification, only some bytes of the MAC address are +displayed. + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 53 +++++++++++++++++++++++---------------- + drivers/net/hns3/hns3_ethdev.h | 2 ++ + drivers/net/hns3/hns3_ethdev_vf.c | 32 +++++++++++------------ + 3 files changed, 49 insertions(+), 38 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 2011378..d6d3f03 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -102,6 +102,15 @@ static int hns3_remove_mc_addr(struct hns3_hw *hw, + static int hns3_restore_fec(struct hns3_hw *hw); + static int hns3_query_dev_fec_info(struct rte_eth_dev *dev); + ++void hns3_ether_format_addr(char *buf, uint16_t size, ++ const struct rte_ether_addr *ether_addr) ++{ ++ snprintf(buf, size, "%02X:**:**:**:%02X:%02X", ++ ether_addr->addr_bytes[0], ++ ether_addr->addr_bytes[4], ++ ether_addr->addr_bytes[5]); ++} ++ + static void + hns3_pf_disable_irq0(struct hns3_hw *hw) + { +@@ -1449,7 +1458,7 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + /* check if mac addr is valid */ + if (!rte_is_valid_assigned_ether_addr(mac_addr)) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "Add unicast mac addr err! addr(%s) invalid", + mac_str); +@@ -1489,7 +1498,7 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + return -ENOSPC; + } + +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); + + /* check if we just hit the duplicate */ + if (ret == 0) { +@@ -1515,7 +1524,7 @@ hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + 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, ++ hns3_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 " +@@ -1526,7 +1535,7 @@ hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + ret = hns3_add_mc_addr(hw, mac_addr); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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); +@@ -1542,7 +1551,7 @@ hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + ret = hns3_remove_mc_addr(hw, mac_addr); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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); +@@ -1576,7 +1585,7 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, + + if (ret) { + rte_spinlock_unlock(&hw->lock); +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str, + ret); +@@ -1599,7 +1608,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + /* check if mac addr is valid */ + if (!rte_is_valid_assigned_ether_addr(mac_addr)) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "remove unicast mac addr err! addr(%s) invalid", + mac_str); +@@ -1635,7 +1644,7 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) + ret = hns3_remove_uc_addr_common(hw, mac_addr); + rte_spinlock_unlock(&hw->lock); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str, + ret); +@@ -1666,7 +1675,7 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + if (default_addr_setted) { + ret = hns3_remove_uc_addr_common(hw, oaddr); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + oaddr); + hns3_warn(hw, "Remove old uc mac address(%s) fail: %d", + mac_str, ret); +@@ -1677,7 +1686,7 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + + ret = hns3_add_uc_addr_common(hw, mac_addr); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "Failed to set mac addr(%s): %d", mac_str, ret); + goto err_add_uc_addr; +@@ -1699,7 +1708,7 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + err_pause_addr_cfg: + ret_val = hns3_remove_uc_addr_common(hw, mac_addr); + if (ret_val) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_warn(hw, + "Failed to roll back to del setted mac addr(%s): %d", +@@ -1710,7 +1719,7 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + if (rm_succes) { + ret_val = hns3_add_uc_addr_common(hw, oaddr); + if (ret_val) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + oaddr); + hns3_warn(hw, + "Failed to restore old uc mac addr(%s): %d", +@@ -1746,7 +1755,7 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del) + + if (ret) { + err = ret; +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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", +@@ -1795,7 +1804,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + /* Check if mac addr is valid */ + if (!rte_is_multicast_ether_addr(mac_addr)) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "failed to add mc mac addr, addr(%s) invalid", + mac_str); +@@ -1823,7 +1832,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + if (ret) { + if (ret == -ENOSPC) + hns3_err(hw, "mc mac vlan table is full"); +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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); + } +@@ -1842,7 +1851,7 @@ hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + /* Check if mac addr is valid */ + if (!rte_is_multicast_ether_addr(mac_addr)) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "Failed to rm mc mac addr, addr(%s) invalid", + mac_str); +@@ -1870,7 +1879,7 @@ hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + } + + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "Failed to rm mc mac addr(%s): %d", mac_str, ret); + } +@@ -1899,7 +1908,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, + 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, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, + "failed to set mc mac addr, addr(%s) invalid.", +@@ -1910,7 +1919,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, + /* 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, ++ hns3_ether_format_addr(mac_str, + RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, "failed to set mc mac addr, " +@@ -1927,7 +1936,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, + 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, ++ hns3_ether_format_addr(mac_str, + RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, "failed to set mc mac addr, " +@@ -2101,7 +2110,7 @@ hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del) + ret = hns3_add_mc_addr(hw, addr); + if (ret) { + err = ret; +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_dbg(hw, "%s mc mac addr: %s failed for pf: ret = %d", + del ? "Remove" : "Restore", mac_str, ret); +@@ -6160,7 +6169,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + eth_addr = (struct rte_ether_addr *)hw->mac.mac_addr; + if (!rte_is_valid_assigned_ether_addr(eth_addr)) { + rte_eth_random_addr(hw->mac.mac_addr); +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + (struct rte_ether_addr *)hw->mac.mac_addr); + hns3_warn(hw, "default mac_addr from firmware is an invalid " + "unicast address, using random MAC address %s", +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 4c40df1..31f78a1 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -935,6 +935,8 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev, + bool hns3_is_reset_pending(struct hns3_adapter *hns); + bool hns3vf_is_reset_pending(struct hns3_adapter *hns); + void hns3_update_link_status(struct hns3_hw *hw); ++void hns3_ether_format_addr(char *buf, uint16_t size, ++ const struct rte_ether_addr *ether_addr); + + static inline bool + is_reset_pending(struct hns3_adapter *hns) +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 0366b9d..f09cabc 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -170,7 +170,7 @@ hns3vf_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + 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, ++ hns3_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); +@@ -190,7 +190,7 @@ hns3vf_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, + false, NULL, 0); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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); +@@ -210,7 +210,7 @@ hns3vf_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + 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, ++ hns3_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 " +@@ -221,7 +221,7 @@ hns3vf_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + + ret = hns3vf_add_mc_mac_addr(hw, mac_addr); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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); +@@ -256,7 +256,7 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, + + rte_spinlock_unlock(&hw->lock); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str, + ret); +@@ -283,7 +283,7 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) + + rte_spinlock_unlock(&hw->lock); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "failed to remove mac addr(%s), ret = %d", + mac_str, ret); +@@ -324,12 +324,12 @@ hns3vf_set_default_mac_addr(struct rte_eth_dev *dev, + * -EPREM to VF driver through mailbox. + */ + if (ret == -EPERM) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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, ++ hns3_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); +@@ -366,7 +366,7 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del) + + if (ret) { + err = ret; +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_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", +@@ -388,7 +388,7 @@ hns3vf_add_mc_mac_addr(struct hns3_hw *hw, + mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, false, + NULL, 0); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "Failed to add mc mac addr(%s) for vf: %d", + mac_str, ret); +@@ -409,7 +409,7 @@ hns3vf_remove_mc_mac_addr(struct hns3_hw *hw, + mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, false, + NULL, 0); + if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + mac_addr); + hns3_err(hw, "Failed to remove mc mac addr(%s) for vf: %d", + mac_str, ret); +@@ -439,7 +439,7 @@ hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw, + 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, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, + "failed to set mc mac addr, addr(%s) invalid.", +@@ -450,7 +450,7 @@ hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw, + /* 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, ++ hns3_ether_format_addr(mac_str, + RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, "failed to set mc mac addr, " +@@ -467,7 +467,7 @@ hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw, + 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, ++ hns3_ether_format_addr(mac_str, + RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, "failed to set mc mac addr, " +@@ -550,7 +550,7 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del) + ret = hns3vf_add_mc_mac_addr(hw, addr); + if (ret) { + err = ret; +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, + addr); + hns3_err(hw, "Failed to %s mc mac addr: %s for vf: %d", + del ? "Remove" : "Restore", mac_str, ret); +@@ -2468,7 +2468,7 @@ hns3vf_check_default_mac_change(struct hns3_hw *hw) + 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, ++ hns3_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", +-- +2.7.4 + diff --git a/0002-dpdk-add-secure-option-in-makefile.patch b/0002-dpdk-add-secure-option-in-makefile.patch deleted file mode 100644 index d1e7ad6..0000000 --- a/0002-dpdk-add-secure-option-in-makefile.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 94cc085f2890fefd1f91c38b245262c4da232e02 Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:31:31 +0800 -Subject: [PATCH] dpdk: add secure option in makefile. - -reason: add secure option in makefile. - -Signed-off-by: zhuhengbo ---- - mk/exec-env/linux/rte.vars.mk | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/mk/exec-env/linux/rte.vars.mk b/mk/exec-env/linux/rte.vars.mk -index bea3f76..6844281 100644 ---- a/mk/exec-env/linux/rte.vars.mk -+++ b/mk/exec-env/linux/rte.vars.mk -@@ -11,10 +11,13 @@ - # - # examples for RTE_EXEC_ENV: linux, freebsd - # -+ -+SEC_FLAGS = -fstack-protector-all -Wall -Wl,-z,relro,-z,now -Wl,-z,noexecstack -Wtrampolines -fPIC -+ - ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y) --EXECENV_CFLAGS = -pthread -fPIC -+EXECENV_CFLAGS = -pthread -fPIC $(SEC_FLAGS) - else --EXECENV_CFLAGS = -pthread -+EXECENV_CFLAGS = -pthread $(SEC_FLAGS) - endif - - # include in every library to build --- -2.19.1 - diff --git a/0002-net-hns3-fix-FEC-state-query.patch b/0002-net-hns3-fix-FEC-state-query.patch new file mode 100644 index 0000000..8c130ce --- /dev/null +++ b/0002-net-hns3-fix-FEC-state-query.patch @@ -0,0 +1,128 @@ +From e435d9efcb10bc24f528aacee20a25061a7fb70f Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 10 Dec 2020 20:48:43 +0800 +Subject: [PATCH 002/189] net/hns3: fix FEC state query + +As FEC is not supported below 10 Gbps, +CMD(HNS3_OPC_CONFIG_FEC_MODE) offered from +Firmware read will return fail in 10 Gbps device. + +This patch will prevent read this CMD when below 10 Gbps, +as this is non-sense. + +Fixes: 9bf2ea8dbc65 ("net/hns3: support FEC") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 40 ++++++++++++++++++++++++++-------------- + drivers/net/hns3/hns3_ethdev.h | 2 ++ + 2 files changed, 28 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index d6d3f03..7c34e38 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -100,7 +100,7 @@ static int hns3_add_mc_addr(struct hns3_hw *hw, + static int hns3_remove_mc_addr(struct hns3_hw *hw, + struct rte_ether_addr *mac_addr); + static int hns3_restore_fec(struct hns3_hw *hw); +-static int hns3_query_dev_fec_info(struct rte_eth_dev *dev); ++static int hns3_query_dev_fec_info(struct hns3_hw *hw); + + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr) +@@ -3010,13 +3010,6 @@ hns3_get_capability(struct hns3_hw *hw) + device_id == HNS3_DEV_ID_200G_RDMA) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1); + +- ret = hns3_query_dev_fec_info(eth_dev); +- if (ret) { +- PMD_INIT_LOG(ERR, +- "failed to query FEC information, ret = %d", ret); +- return ret; +- } +- + /* Get PCI revision id */ + ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN, + HNS3_PCI_REVISION_ID); +@@ -3148,8 +3141,15 @@ hns3_get_configuration(struct hns3_hw *hw) + } + + ret = hns3_get_board_configuration(hw); +- if (ret) ++ if (ret) { + PMD_INIT_LOG(ERR, "failed to get board configuration: %d", ret); ++ return ret; ++ } ++ ++ ret = hns3_query_dev_fec_info(hw); ++ if (ret) ++ PMD_INIT_LOG(ERR, ++ "failed to query FEC information, ret = %d", ret); + + return ret; + } +@@ -5797,6 +5797,16 @@ get_current_fec_auto_state(struct hns3_hw *hw, uint8_t *state) + struct hns3_cmd_desc desc; + int ret; + ++ /* ++ * CMD(HNS3_OPC_CONFIG_FEC_MODE) read is not supported ++ * in device of link speed ++ * below 10 Gbps. ++ */ ++ if (hw->mac.link_speed < ETH_SPEED_NUM_10G) { ++ *state = 0; ++ return 0; ++ } ++ + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CONFIG_FEC_MODE, true); + req = (struct hns3_config_fec_cmd *)desc.data; + ret = hns3_cmd_send(hw, &desc, 1); +@@ -6003,14 +6013,14 @@ hns3_restore_fec(struct hns3_hw *hw) + } + + static int +-hns3_query_dev_fec_info(struct rte_eth_dev *dev) ++hns3_query_dev_fec_info(struct hns3_hw *hw) + { +- struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns); +- struct hns3_pf *pf = &hns->pf; ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(hns); ++ struct rte_eth_dev *eth_dev = hns->eth_dev; + int ret; + +- ret = hns3_fec_get(dev, &pf->fec_mode); ++ ret = hns3_fec_get(eth_dev, &pf->fec_mode); + if (ret) + hns3_err(hw, "query device FEC info failed, ret = %d", ret); + +@@ -6096,6 +6106,8 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + + PMD_INIT_FUNC_TRACE(); + ++ hns->eth_dev = eth_dev; ++ + 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 31f78a1..8d6b8cd 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -743,6 +743,8 @@ struct hns3_adapter { + struct hns3_vf vf; + }; + ++ struct rte_eth_dev *eth_dev; ++ + bool rx_simple_allowed; + bool rx_vec_allowed; + bool tx_simple_allowed; +-- +2.7.4 + diff --git a/0003-dpdk-bugfix-the-deadlock-in-rte_eal_init.patch b/0003-dpdk-bugfix-the-deadlock-in-rte_eal_init.patch deleted file mode 100644 index a77728e..0000000 --- a/0003-dpdk-bugfix-the-deadlock-in-rte_eal_init.patch +++ /dev/null @@ -1,72 +0,0 @@ -From dee3ff16473b956d8cfca15baa419e5dfdf47130 Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:14:25 +0800 -Subject: [PATCH] dpdk: bugfix the deadlock in rte_eal_init when executes this - function concurrently - -Signed-off-by: zhuhengbo ---- - lib/librte_eal/linux/eal/eal.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c -index c4233ec..a3bb9c6 100644 ---- a/lib/librte_eal/linux/eal/eal.c -+++ b/lib/librte_eal/linux/eal/eal.c -@@ -1128,7 +1128,7 @@ rte_eal_init(int argc, char **argv) - rte_eal_init_alert("Cannot get hugepage information."); - rte_errno = EACCES; - rte_atomic32_clear(&run_once); -- return -1; -+ goto out; - } - } - -@@ -1152,7 +1152,7 @@ rte_eal_init(int argc, char **argv) - rte_eal_init_alert("Cannot init logging."); - rte_errno = ENOMEM; - rte_atomic32_clear(&run_once); -- return -1; -+ goto out; - } - - #ifdef VFIO_PRESENT -@@ -1160,7 +1160,7 @@ rte_eal_init(int argc, char **argv) - rte_eal_init_alert("Cannot init VFIO"); - rte_errno = EAGAIN; - rte_atomic32_clear(&run_once); -- return -1; -+ goto out; - } - #endif - /* in secondary processes, memory init may allocate additional fbarrays -@@ -1170,13 +1170,13 @@ rte_eal_init(int argc, char **argv) - if (rte_eal_memzone_init() < 0) { - rte_eal_init_alert("Cannot init memzone"); - rte_errno = ENODEV; -- return -1; -+ goto out; - } - - if (rte_eal_memory_init() < 0) { - rte_eal_init_alert("Cannot init memory"); - rte_errno = ENOMEM; -- return -1; -+ goto out; - } - - /* the directories are locked during eal_hugepage_info_init */ -@@ -1297,6 +1297,10 @@ rte_eal_init(int argc, char **argv) - rte_option_init(); - - return fctret; -+ -+out: -+ eal_hugedirs_unlock(); -+ return -1; - } - - static int --- -2.19.1 - diff --git a/0003-net-hns3-fix-build-with-SVE.patch b/0003-net-hns3-fix-build-with-SVE.patch new file mode 100644 index 0000000..3a28f65 --- /dev/null +++ b/0003-net-hns3-fix-build-with-SVE.patch @@ -0,0 +1,64 @@ +From 0114915c86b2cadefe4c0323f28868c4f11be2f2 Mon Sep 17 00:00:00 2001 +From: Ruifeng Wang +Date: Tue, 12 Jan 2021 02:57:05 +0000 +Subject: [PATCH 003/189] net/hns3: fix build with SVE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Building with SVE extension enabled stopped with error: + + error: ACLE function ‘svwhilelt_b64_s32’ requires ISA extension ‘sve’ + 18 | #define PG64_256BIT svwhilelt_b64(0, 4) + +This is caused by unintentional cflags reset. +Fixed the issue by not touching cflags, and using flags defined by +compiler. + +Fixes: 952ebacce4f2 ("net/hns3: support SVE Rx") +Cc: stable@dpdk.org + +Signed-off-by: Ruifeng Wang +Reviewed-by: Honnappa Nagarahalli +--- + drivers/net/hns3/hns3_rxtx.c | 4 ++-- + drivers/net/hns3/meson.build | 1 - + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 88d3bab..5ac36b3 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -10,7 +10,7 @@ + #include + #include + #include +-#if defined(RTE_ARCH_ARM64) && defined(CC_SVE_SUPPORT) ++#if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE) + #include + #endif + +@@ -2467,7 +2467,7 @@ hns3_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, + static bool + hns3_check_sve_support(void) + { +-#if defined(RTE_ARCH_ARM64) && defined(CC_SVE_SUPPORT) ++#if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE) + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SVE)) + return true; + #endif +diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build +index 45cee34..5674d98 100644 +--- a/drivers/net/hns3/meson.build ++++ b/drivers/net/hns3/meson.build +@@ -32,7 +32,6 @@ deps += ['hash'] + if arch_subdir == 'arm' and dpdk_conf.get('RTE_ARCH_64') + sources += files('hns3_rxtx_vec.c') + if cc.get_define('__ARM_FEATURE_SVE', args: machine_args) != '' +- cflags = ['-DCC_SVE_SUPPORT'] + sources += files('hns3_rxtx_vec_sve.c') + endif + endif +-- +2.7.4 + diff --git a/0004-dpdk-master-core-donot-set-affinity-in-libstorage.patch b/0004-dpdk-master-core-donot-set-affinity-in-libstorage.patch deleted file mode 100644 index ce6ef10..0000000 --- a/0004-dpdk-master-core-donot-set-affinity-in-libstorage.patch +++ /dev/null @@ -1,73 +0,0 @@ -From c2d29472c3ddd1b2d66f34ae4025c9e074913eaa Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:38:13 +0800 -Subject: [PATCH] dpdk: master core donot set affinity in libstorage - -Signed-off-by: zhuhengbo ---- - lib/librte_eal/common/eal_private.h | 6 ++++++ - lib/librte_eal/linux/eal/eal.c | 12 ++++++++++++ - lib/librte_eal/linux/eal/eal_thread.c | 2 +- - 3 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h -index 8a9d493..597fd02 100644 ---- a/lib/librte_eal/common/eal_private.h -+++ b/lib/librte_eal/common/eal_private.h -@@ -444,4 +444,10 @@ rte_option_usage(void); - uint64_t - eal_get_baseaddr(void); - -+/** -+ * Determine whether the master core needs to set affinity. -+ * The master thread in the LibStorage application cannot set affinity. -+ **/ -+bool -+eal_is_master_set_affinity(void); - #endif /* _EAL_PRIVATE_H_ */ -diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c -index a3bb9c6..8bb1842 100644 ---- a/lib/librte_eal/linux/eal/eal.c -+++ b/lib/librte_eal/linux/eal/eal.c -@@ -103,6 +103,13 @@ static char runtime_dir[PATH_MAX]; - - static const char *default_runtime_dir = "/var/run"; - -+static bool master_set_affinity = true; -+bool -+eal_is_master_set_affinity(void) -+{ -+ return master_set_affinity; -+} -+ - int - eal_create_runtime_dir(void) - { -@@ -985,6 +992,11 @@ rte_eal_init(int argc, char **argv) - strlcpy(logid, p ? p + 1 : argv[0], sizeof(logid)); - thread_id = pthread_self(); - -+ /* Master thread don't set affinity in LibStorage application */ -+ if (strstr(logid, "LibStorage") != NULL) { -+ master_set_affinity = false; -+ } -+ - eal_reset_internal_config(&internal_config); - - /* set log level as early as possible */ -diff --git a/lib/librte_eal/linux/eal/eal_thread.c b/lib/librte_eal/linux/eal/eal_thread.c -index 379773b..5b06108 100644 ---- a/lib/librte_eal/linux/eal/eal_thread.c -+++ b/lib/librte_eal/linux/eal/eal_thread.c -@@ -84,7 +84,7 @@ void eal_thread_init_master(unsigned lcore_id) - RTE_PER_LCORE(_lcore_id) = lcore_id; - - /* set CPU affinity */ -- if (eal_thread_set_affinity() < 0) -+ if (eal_is_master_set_affinity() && eal_thread_set_affinity() < 0) - rte_panic("cannot set affinity\n"); - } - --- -2.19.1 - diff --git a/0004-net-hns3-fix-interception-with-flow-director.patch b/0004-net-hns3-fix-interception-with-flow-director.patch new file mode 100644 index 0000000..c651c93 --- /dev/null +++ b/0004-net-hns3-fix-interception-with-flow-director.patch @@ -0,0 +1,37 @@ +From 7a6944f354740866bc35cf716ce3979999b7396e Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Wed, 6 Jan 2021 11:46:27 +0800 +Subject: [PATCH 004/189] net/hns3: fix interception with flow director + +The rte_fdir_conf structure has deprecated and users need +to use the specified rule parameters of rte_flow structure +when configure a flow rule. As a result, it is incorrectly +used in the rte_flow API. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index ee6ec15..f303df4 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1208,11 +1208,6 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Fdir not supported in VF"); + +- if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) +- return rte_flow_error_set(error, ENOTSUP, +- RTE_FLOW_ERROR_TYPE_HANDLE, NULL, +- "fdir_conf.mode isn't perfect"); +- + step_mngr.items = first_items; + step_mngr.count = ARRAY_SIZE(first_items); + for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { +-- +2.7.4 + diff --git a/0005-dpdk-change-the-log-level-in-prepare_numa.patch b/0005-dpdk-change-the-log-level-in-prepare_numa.patch deleted file mode 100644 index 6adec3b..0000000 --- a/0005-dpdk-change-the-log-level-in-prepare_numa.patch +++ /dev/null @@ -1,28 +0,0 @@ -From e970ca944126de31844a323b8e9e014ee2a9e128 Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:44:24 +0800 -Subject: [PATCH] dpdk: change the log level in prepare_numa - -reason: prevent rushing logs - -Signed-off-by: zhuhengbo ---- - lib/librte_eal/linux/eal/eal_memalloc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/librte_eal/linux/eal/eal_memalloc.c b/lib/librte_eal/linux/eal/eal_memalloc.c -index af6d0d0..cad4934 100644 ---- a/lib/librte_eal/linux/eal/eal_memalloc.c -+++ b/lib/librte_eal/linux/eal/eal_memalloc.c -@@ -167,7 +167,7 @@ prepare_numa(int *oldpolicy, struct bitmask *oldmask, int socket_id) - RTE_LOG(DEBUG, EAL, "Trying to obtain current memory policy.\n"); - if (get_mempolicy(oldpolicy, oldmask->maskp, - oldmask->size + 1, 0, 0) < 0) { -- RTE_LOG(ERR, EAL, -+ RTE_LOG(DEBUG, EAL, - "Failed to get current mempolicy: %s. " - "Assuming MPOL_DEFAULT.\n", strerror(errno)); - *oldpolicy = MPOL_DEFAULT; --- -2.19.1 - diff --git a/0005-net-hns3-fix-xstats-with-id-and-names.patch b/0005-net-hns3-fix-xstats-with-id-and-names.patch new file mode 100644 index 0000000..311f37f --- /dev/null +++ b/0005-net-hns3-fix-xstats-with-id-and-names.patch @@ -0,0 +1,85 @@ +From 094b7303b76507e93d4b8e1eaa7e0c819362b67a Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 6 Jan 2021 11:46:28 +0800 +Subject: [PATCH 005/189] net/hns3: fix xstats with id and names + +Currently, validity check for ids and values in the +hns3_dev_xstats_get_by_id API is incorrect, which will +cause a problem. Namely, if the ID range of the xstats +stats item does not include the basic stats item, the +app can not obtain the corresponding xstats statistics +in hns3_dev_xstats_get_by_id. + +Similarly, the hns3_dev_xstats_get_names_by_id interface +also has a problem. + +Although the input parameter verification code cannot be +executed due to the implementation of the ethdev framework +interface, the driver needs to ensure the correctness of +the input parameters. + +Fixes: 8839c5e202f3 ("net/hns3: support device stats") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_stats.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 91168ac..1597af3 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -933,9 +933,13 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + uint32_t i; + int ret; + +- if (ids == NULL || size < cnt_stats) ++ if (ids == NULL && values == NULL) + return cnt_stats; + ++ if (ids == NULL) ++ if (size < cnt_stats) ++ return cnt_stats; ++ + /* Update tqp stats by read register */ + ret = hns3_update_tqp_stats(hw); + if (ret) { +@@ -957,6 +961,15 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + return -EINVAL; + } + ++ if (ids == NULL && values != NULL) { ++ for (i = 0; i < cnt_stats; i++) ++ memcpy(&values[i], &values_copy[i].value, ++ sizeof(values[i])); ++ ++ rte_free(values_copy); ++ return cnt_stats; ++ } ++ + for (i = 0; i < size; i++) { + if (ids[i] >= cnt_stats) { + hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, " +@@ -1005,9 +1018,16 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, + uint64_t len; + uint32_t i; + +- if (ids == NULL || xstats_names == NULL) ++ if (xstats_names == NULL) + return cnt_stats; + ++ if (ids == NULL) { ++ if (size < cnt_stats) ++ return cnt_stats; ++ ++ return hns3_dev_xstats_get_names(dev, xstats_names, cnt_stats); ++ } ++ + len = cnt_stats * sizeof(struct rte_eth_xstat_name); + names_copy = rte_zmalloc("hns3_xstats_names", len, 0); + if (names_copy == NULL) { +-- +2.7.4 + diff --git a/0006-dpdk-fix-dpdk-coredump-problem.patch b/0006-dpdk-fix-dpdk-coredump-problem.patch deleted file mode 100644 index 57815d4..0000000 --- a/0006-dpdk-fix-dpdk-coredump-problem.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a78efd329d52e1adf813eb1b76352c2680b75961 Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:49:53 +0800 -Subject: [PATCH] dpdk: modification summary - -Signed-off-by: zhuhengbo ---- - lib/librte_eal/linux/eal/eal_interrupts.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal_interrupts.c b/lib/librte_eal/linux/eal/eal_interrupts.c -index 1955324..3d73cce 100644 ---- a/lib/librte_eal/linux/eal/eal_interrupts.c -+++ b/lib/librte_eal/linux/eal/eal_interrupts.c -@@ -1070,7 +1070,7 @@ eal_intr_thread_main(__rte_unused void *arg) - */ - if (epoll_ctl(pfd, EPOLL_CTL_ADD, intr_pipe.readfd, - &pipe_event) < 0) { -- rte_panic("Error adding fd to %d epoll_ctl, %s\n", -+ RTE_LOG(ERR, EAL, "Error adding fd to %d epoll_ctl, %s\n", - intr_pipe.readfd, strerror(errno)); - } - numfds++; -@@ -1089,7 +1089,7 @@ eal_intr_thread_main(__rte_unused void *arg) - */ - if (epoll_ctl(pfd, EPOLL_CTL_ADD, - src->intr_handle.fd, &ev) < 0){ -- rte_panic("Error adding fd %d epoll_ctl, %s\n", -+ RTE_LOG(ERR, EAL, "Error adding fd %d epoll_ctl, %s\n", - src->intr_handle.fd, strerror(errno)); - } - else --- -2.19.1 - diff --git a/0006-net-hns3-fix-error-code-in-xstats.patch b/0006-net-hns3-fix-error-code-in-xstats.patch new file mode 100644 index 0000000..0679b9f --- /dev/null +++ b/0006-net-hns3-fix-error-code-in-xstats.patch @@ -0,0 +1,38 @@ +From 8cbd6fc2895cdbb0a64c2d2a31e53ff4b0608752 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 6 Jan 2021 11:46:29 +0800 +Subject: [PATCH 006/189] net/hns3: fix error code in xstats + +The ethdev API has processed the failure to obtain +xstats statistics. Therefore, driver should return +an error code instead of 0 in 'hns3_dev_xstats_get' +API. + +Fixes: 8839c5e202f3 ("net/hns3: support device stats") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_stats.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 1597af3..42ec9b8 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -739,9 +739,9 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + if (!hns->is_vf) { + /* Update Mac stats */ + ret = hns3_query_update_mac_stats(dev); +- if (ret) { ++ if (ret < 0) { + hns3_err(hw, "Update Mac stats fail : %d", ret); +- return 0; ++ return ret; + } + + /* Get MAC stats from hw->hw_xstats.mac_stats struct */ +-- +2.7.4 + diff --git a/0007-dpdk-add-secure-compile-option-in-pmdinfogen-Makefil.patch b/0007-dpdk-add-secure-compile-option-in-pmdinfogen-Makefil.patch deleted file mode 100644 index 0cd8210..0000000 --- a/0007-dpdk-add-secure-compile-option-in-pmdinfogen-Makefil.patch +++ /dev/null @@ -1,26 +0,0 @@ -From e7c97339d38f9d2655ca7834a99cc95b7427dd5c Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 19 Mar 2020 17:53:22 +0800 -Subject: [PATCH] dpdk: add secure compile option in pmdinfogen Makefile - -Signed-off-by: zhuhengbo ---- - buildtools/pmdinfogen/Makefile | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/buildtools/pmdinfogen/Makefile b/buildtools/pmdinfogen/Makefile -index a97a764..af41c74 100644 ---- a/buildtools/pmdinfogen/Makefile -+++ b/buildtools/pmdinfogen/Makefile -@@ -15,6 +15,8 @@ HOSTAPP = dpdk-pmdinfogen - SRCS-y += pmdinfogen.c - - HOST_CFLAGS += $(HOST_WERROR_FLAGS) -g -+HOST_CFLAGS += -fPIE -fPIC -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -Wall -Werror - HOST_CFLAGS += -I$(RTE_OUTPUT)/include - -+HOST_LDFLAGS += -Wl,-z,relro,-z,now -pie - include $(RTE_SDK)/mk/rte.hostapp.mk --- -2.19.1 - diff --git a/0007-net-hns3-fix-Rx-Tx-errors-stats.patch b/0007-net-hns3-fix-Rx-Tx-errors-stats.patch new file mode 100644 index 0000000..7ff3cf3 --- /dev/null +++ b/0007-net-hns3-fix-Rx-Tx-errors-stats.patch @@ -0,0 +1,119 @@ +From d799cf475d2d9b22264cef9c4447e48671e8d76a Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 6 Jan 2021 11:46:30 +0800 +Subject: [PATCH 007/189] net/hns3: fix Rx/Tx errors stats + +Abnormal errors stats in Rx/Tx datapath are statistics +items in driver, and displayed in xstats. They should +be cleared by the rte_eth_xstats_reset api, instead of +the rte_eth_stats_reset. + +Fixes: c4b7d6761d01 ("net/hns3: get Tx abnormal errors in xstats") +Fixes: 521ab3e93361 ("net/hns3: add simple Rx path") +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_stats.c | 59 ++++++++++++++++++++++++++++--------------- + 1 file changed, 39 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 42ec9b8..62a712b 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -551,7 +551,6 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + struct hns3_hw *hw = &hns->hw; + struct hns3_cmd_desc desc_reset; + struct hns3_rx_queue *rxq; +- struct hns3_tx_queue *txq; + uint16_t i; + int ret; + +@@ -581,29 +580,15 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + } + } + +- /* Clear the Rx BD errors stats */ +- for (i = 0; i != eth_dev->data->nb_rx_queues; ++i) { ++ /* ++ * Clear soft stats of rx error packet which will be dropped ++ * in driver. ++ */ ++ for (i = 0; i < eth_dev->data->nb_rx_queues; ++i) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq) { + rxq->pkt_len_errors = 0; + rxq->l2_errors = 0; +- rxq->l3_csum_errors = 0; +- rxq->l4_csum_errors = 0; +- rxq->ol3_csum_errors = 0; +- rxq->ol4_csum_errors = 0; +- } +- } +- +- /* 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; + } + } + +@@ -1053,6 +1038,38 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, + return size; + } + ++static void ++hns3_tqp_dfx_stats_clear(struct rte_eth_dev *dev) ++{ ++ struct hns3_rx_queue *rxq; ++ struct hns3_tx_queue *txq; ++ int i; ++ ++ /* Clear Rx dfx stats */ ++ for (i = 0; i < dev->data->nb_rx_queues; ++i) { ++ rxq = dev->data->rx_queues[i]; ++ if (rxq) { ++ rxq->l3_csum_errors = 0; ++ rxq->l4_csum_errors = 0; ++ rxq->ol3_csum_errors = 0; ++ rxq->ol4_csum_errors = 0; ++ } ++ } ++ ++ /* Clear Tx dfx stats */ ++ for (i = 0; i < dev->data->nb_tx_queues; ++i) { ++ txq = 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; ++ } ++ } ++} ++ + int + hns3_dev_xstats_reset(struct rte_eth_dev *dev) + { +@@ -1068,6 +1085,8 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) + /* Clear reset stats */ + memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats)); + ++ hns3_tqp_dfx_stats_clear(dev); ++ + if (hns->is_vf) + return 0; + +-- +2.7.4 + diff --git a/0008-dpdk-fix-cpu-flag-error-in-Intel-R-Xeon-R-CPU-E5-262.patch b/0008-dpdk-fix-cpu-flag-error-in-Intel-R-Xeon-R-CPU-E5-262.patch deleted file mode 100644 index 170eb50..0000000 --- a/0008-dpdk-fix-cpu-flag-error-in-Intel-R-Xeon-R-CPU-E5-262.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 145e9a29777cc660bd031670a7aeb8a4d3cb88a8 Mon Sep 17 00:00:00 2001 -From: zhuhengbo -Date: Thu, 30 Apr 2020 02:53:08 -0400 -Subject: [PATCH] dpdk: fix cpu flag error in Intel(R) Xeon(R) CPU E5-2620 v3 @ - 2.40GHz - -Signed-off-by: zhuhengbo ---- - config/defconfig_x86_64-cpu_v2-linux-gcc | 1 + - config/defconfig_x86_64-cpu_v2-linuxapp-gcc | 14 ++++++++ - mk/machine/cpu_v2/rte.vars.mk | 39 +++++++++++++++++++++ - 3 files changed, 54 insertions(+) - create mode 120000 config/defconfig_x86_64-cpu_v2-linux-gcc - create mode 100644 config/defconfig_x86_64-cpu_v2-linuxapp-gcc - create mode 100644 mk/machine/cpu_v2/rte.vars.mk - -diff --git a/config/defconfig_x86_64-cpu_v2-linux-gcc b/config/defconfig_x86_64-cpu_v2-linux-gcc -new file mode 120000 -index 0000000..64f21b6 ---- /dev/null -+++ b/config/defconfig_x86_64-cpu_v2-linux-gcc -@@ -0,0 +1 @@ -+defconfig_x86_64-cpu_v2-linuxapp-gcc -\ No newline at end of file -diff --git a/config/defconfig_x86_64-cpu_v2-linuxapp-gcc b/config/defconfig_x86_64-cpu_v2-linuxapp-gcc -new file mode 100644 -index 0000000..2748e30 ---- /dev/null -+++ b/config/defconfig_x86_64-cpu_v2-linuxapp-gcc -@@ -0,0 +1,14 @@ -+# SPDX-License-Identifier: BSD-3-Clause -+# Copyright(c) 2010-2014 Intel Corporation -+ -+#include "common_linux" -+ -+CONFIG_RTE_MACHINE="cpu_v2" -+ -+CONFIG_RTE_ARCH="x86_64" -+CONFIG_RTE_ARCH_X86_64=y -+CONFIG_RTE_ARCH_X86=y -+CONFIG_RTE_ARCH_64=y -+ -+CONFIG_RTE_TOOLCHAIN="gcc" -+CONFIG_RTE_TOOLCHAIN_GCC=y -diff --git a/mk/machine/cpu_v2/rte.vars.mk b/mk/machine/cpu_v2/rte.vars.mk -new file mode 100644 -index 0000000..ffa7d3f ---- /dev/null -+++ b/mk/machine/cpu_v2/rte.vars.mk -@@ -0,0 +1,39 @@ -+# SPDX-License-Identifier: BSD-3-Clause -+# Copyright(c) 2010-2014 Intel Corporation -+ -+# -+# machine: -+# -+# - can define ARCH variable (overridden by cmdline value) -+# - can define CROSS variable (overridden by cmdline value) -+# - define MACHINE_CFLAGS variable (overridden by cmdline value) -+# - define MACHINE_LDFLAGS variable (overridden by cmdline value) -+# - define MACHINE_ASFLAGS variable (overridden by cmdline value) -+# - can define CPU_CFLAGS variable (overridden by cmdline value) that -+# overrides the one defined in arch. -+# - can define CPU_LDFLAGS variable (overridden by cmdline value) that -+# overrides the one defined in arch. -+# - can define CPU_ASFLAGS variable (overridden by cmdline value) that -+# overrides the one defined in arch. -+# - may override any previously defined variable -+# -+ -+# ARCH = -+# CROSS = -+# MACHINE_CFLAGS = -+# MACHINE_LDFLAGS = -+# MACHINE_ASFLAGS = -+# CPU_CFLAGS = -+# CPU_LDFLAGS = -+# CPU_ASFLAGS = -+ -+MACHINE_CFLAGS = -march=core-avx-i -+ -+# On FreeBSD systems, sometimes the correct CPU type is not picked up. -+# To get everything to compile, we need SSE4.2 support, so check if that is -+# reported by compiler. If not, check if the CPU actually supports it, and if -+# so, set the compilation target to be a corei7, minimum target with SSE4.2. -+SSE42_SUPPORT=$(shell $(CC) -march=native -dM -E - +Date: Wed, 6 Jan 2021 11:46:31 +0800 +Subject: [PATCH 008/189] net/hns3: fix crash with multi-process + +In current version, procedure of saving eth_dev in +hns3 PMD init will be called more than twice, one +for primary, the other for secondary. That will cause +segmentation fault in Multi-process as eth_dev will +be changed in secondary process, which is different +from one in primary process. + +The initial problem was access to 'rte_eth_devices' +global variable, which is wrong. But current approach +can cause problem for the secondaries, moving 'eth_dev' +to process private can work but before making things +more complex. + +This patch deserted the procedure of saving eth_dev in +hns3 PMD init. Instead, it creates an internal function +that gets "struct hns3_hw" as parameter and it can be +called internally without knowing 'eth_dev'and the +.dev_ops can be wrapper to this. + +Fixes: 2390bf217f4d ("net/hns3: fix FEC state query") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 16 ++++++++++------ + drivers/net/hns3/hns3_ethdev.h | 2 -- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7c34e38..90544fe 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5821,10 +5821,9 @@ get_current_fec_auto_state(struct hns3_hw *hw, uint8_t *state) + } + + static int +-hns3_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa) ++hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa) + { + #define QUERY_ACTIVE_SPEED 1 +- struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_sfp_speed_cmd *resp; + uint32_t tmp_fec_capa; + uint8_t auto_state; +@@ -5885,6 +5884,14 @@ hns3_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa) + } + + static int ++hns3_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ ++ return hns3_fec_get_internal(hw, fec_capa); ++} ++ ++static int + hns3_set_fec_hw(struct hns3_hw *hw, uint32_t mode) + { + struct hns3_config_fec_cmd *req; +@@ -6017,10 +6024,9 @@ hns3_query_dev_fec_info(struct hns3_hw *hw) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(hns); +- struct rte_eth_dev *eth_dev = hns->eth_dev; + int ret; + +- ret = hns3_fec_get(eth_dev, &pf->fec_mode); ++ ret = hns3_fec_get_internal(hw, &pf->fec_mode); + if (ret) + hns3_err(hw, "query device FEC info failed, ret = %d", ret); + +@@ -6106,8 +6112,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + + PMD_INIT_FUNC_TRACE(); + +- hns->eth_dev = eth_dev; +- + 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 8d6b8cd..31f78a1 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -743,8 +743,6 @@ struct hns3_adapter { + struct hns3_vf vf; + }; + +- struct rte_eth_dev *eth_dev; +- + bool rx_simple_allowed; + bool rx_vec_allowed; + bool tx_simple_allowed; +-- +2.7.4 + diff --git a/0009-dpdk-support-gazelle-01-include.patch b/0009-dpdk-support-gazelle-01-include.patch deleted file mode 100644 index 2999995..0000000 --- a/0009-dpdk-support-gazelle-01-include.patch +++ /dev/null @@ -1,194 +0,0 @@ -From bca7c742a8f956212c5ad9661b602676c71b7028 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 16:24:55 +0800 -Subject: [PATCH] dpdk-support-gazelle-01-include - ---- - lib/librte_eal/common/include/rte_eal.h | 10 ++- - lib/librte_eal/common/include/rte_fbarray.h | 7 ++ - lib/librte_eal/common/include/rte_memory.h | 20 +++++- - lib/librte_ring/rte_ring.h | 75 +++++++++++++++++++++ - 4 files changed, 108 insertions(+), 4 deletions(-) - -diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h -index 2f9ed29..ac1dc1d 100644 ---- a/lib/librte_eal/common/include/rte_eal.h -+++ b/lib/librte_eal/common/include/rte_eal.h -@@ -485,9 +485,17 @@ rte_eal_mbuf_user_pool_ops(void); - * @return - * The runtime directory path of DPDK - */ --const char * -+char * - rte_eal_get_runtime_dir(void); - -+/****** APIs for libnet ******/ -+char *rte_eal_sec_get_runtime_dir(const int sec_idx); -+struct rte_config *rte_eal_sec_get_configuration(const int sec_idx); -+struct internal_config *rte_eal_sec_get_internal_config(const int sec_idx); -+ -+int rte_eal_sec_attach(int argc, char **argv); -+int rte_eal_sec_detach(const char *file_prefix, int length); -+ - #ifdef __cplusplus - } - #endif -diff --git a/lib/librte_eal/common/include/rte_fbarray.h b/lib/librte_eal/common/include/rte_fbarray.h -index 6dccdbe..dffee1e 100644 ---- a/lib/librte_eal/common/include/rte_fbarray.h -+++ b/lib/librte_eal/common/include/rte_fbarray.h -@@ -101,6 +101,10 @@ __rte_experimental - int - rte_fbarray_attach(struct rte_fbarray *arr); - -+int -+rte_sec_fbarray_attach(struct rte_fbarray *arr, -+ const int switch_pri_and_sec, const int sec_idx); -+ - - /** - * Deallocate resources for an already allocated and correctly set up -@@ -123,6 +127,9 @@ __rte_experimental - int - rte_fbarray_destroy(struct rte_fbarray *arr); - -+int -+rte_sec_fbarray_destroy(struct rte_fbarray *arr, -+ const int sec_idx); - - /** - * Deallocate resources for an already allocated and correctly set up -diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h -index 3d8d0bd..4dd6daa 100644 ---- a/lib/librte_eal/common/include/rte_memory.h -+++ b/lib/librte_eal/common/include/rte_memory.h -@@ -152,7 +152,12 @@ rte_mem_iova2virt(rte_iova_t iova); - __rte_experimental - struct rte_memseg * - rte_mem_virt2memseg(const void *virt, const struct rte_memseg_list *msl); -- -+/* -+__rte_experimental -+struct rte_memseg * -+rte_sec_mem_virt2memseg(const void *addr, const struct rte_memseg_list *msl, -+ const struct rte_config *rte_cfg); -+*/ - /** - * Get memseg list corresponding to virtual memory address. - * -@@ -164,7 +169,11 @@ rte_mem_virt2memseg(const void *virt, const struct rte_memseg_list *msl); - __rte_experimental - struct rte_memseg_list * - rte_mem_virt2memseg_list(const void *virt); -- -+/* -+__rte_experimental -+struct rte_memseg_list * -+rte_sec_mem_virt2memseg_list(const void *addr, const struct rte_config *rte_cfg); -+*/ - /** - * Memseg walk function prototype. - * -@@ -282,7 +291,12 @@ rte_memseg_list_walk(rte_memseg_list_walk_t func, void *arg); - __rte_experimental - int - rte_memseg_walk_thread_unsafe(rte_memseg_walk_t func, void *arg); -- -+/* -+__rte_experimental -+int -+rte_sec_memseg_list_walk_thread_unsafe(rte_memseg_list_walk_t func, void *arg, -+ struct rte_config *rte_cfg); -+*/ - /** - * Walk each VA-contiguous area without performing any locking. - * -diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h -index 2a9f768..0eb3a48 100644 ---- a/lib/librte_ring/rte_ring.h -+++ b/lib/librte_ring/rte_ring.h -@@ -953,6 +953,81 @@ rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table, - r->cons.single, available); - } - -+/****** APIs for libnet ******/ -+static __rte_always_inline unsigned -+rte_ring_cn_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned int n) -+{ -+ const uint32_t old_head = r->prod.tail; -+ rte_smp_rmb(); -+ -+ const uint32_t entries = r->cons.head - old_head; -+ if (n > entries) { -+ n = entries; -+ } -+ if (unlikely(n == 0)) { -+ return 0; -+ } -+ -+ r->prod.head = old_head + n; -+ rte_smp_rmb(); -+ -+ DEQUEUE_PTRS(r, &r[1], old_head, obj_table, n, void *); -+ return n; -+} -+ -+static __rte_always_inline void -+rte_ring_cn_enqueue(struct rte_ring *r) -+{ -+ rte_smp_wmb(); -+ r->prod.tail = r->prod.head; -+} -+ -+static __rte_always_inline unsigned -+rte_ring_en_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned int n) -+{ -+ const uint32_t old_tail = r->cons.tail; -+ rte_smp_rmb(); -+ -+ const uint32_t entries = r->prod.tail - old_tail; -+ if (n > entries) { -+ n = entries; -+ } -+ if (unlikely(n == 0)) { -+ return 0; -+ } -+ -+ const uint32_t new_tail = old_tail + n; -+ rte_smp_rmb(); -+ -+ DEQUEUE_PTRS(r, &r[1], old_tail, obj_table, n, void *); -+ rte_smp_rmb(); -+ -+ r->cons.tail = new_tail; -+ return n; -+} -+ -+static __rte_always_inline unsigned -+rte_ring_en_enqueue_bulk(struct rte_ring *r, void **obj_table, unsigned int n) -+{ -+ const uint32_t capacity = r->capacity; -+ const uint32_t old_head = r->cons.head; -+ rte_smp_rmb(); -+ -+ const uint32_t entries = capacity + r->cons.tail - old_head; -+ if (n > entries) { -+ return 0; -+ } -+ -+ const uint32_t new_head = old_head + n; -+ rte_smp_rmb(); -+ -+ ENQUEUE_PTRS(r, &r[1], old_head, obj_table, n, void *); -+ rte_smp_wmb(); -+ -+ r->cons.head = new_head; -+ return n; -+} -+ - #ifdef __cplusplus - } - #endif --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-02-include-base.patch b/0009-dpdk-support-gazelle-02-include-base.patch deleted file mode 100644 index 5e4807c..0000000 --- a/0009-dpdk-support-gazelle-02-include-base.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 8b468249a77d0dc7af6732bcbc4881dba388135d Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 16:25:39 +0800 -Subject: [PATCH] dpdk-support-gazelle-02-include-base - ---- - config/common_base | 3 +- - lib/librte_eal/common/eal_filesystem.h | 56 ++++++++++++++++++++++---- - lib/librte_eal/common/eal_private.h | 25 +++++++++++- - 3 files changed, 74 insertions(+), 10 deletions(-) - -diff --git a/config/common_base b/config/common_base -index 7dec7ed..57b1349 100644 ---- a/config/common_base -+++ b/config/common_base -@@ -95,7 +95,8 @@ CONFIG_RTE_MAX_MEMSEG_PER_TYPE=32768 - CONFIG_RTE_MAX_MEM_MB_PER_TYPE=131072 - # global maximum usable amount of VA, in megabytes - CONFIG_RTE_MAX_MEM_MB=524288 --CONFIG_RTE_MAX_MEMZONE=2560 -+CONFIG_RTE_MAX_MEMZONE=65535 -+CONFIG_RTE_MAX_SECONDARY=256 - CONFIG_RTE_MAX_TAILQ=32 - CONFIG_RTE_ENABLE_ASSERT=n - CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO -diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h -index 5d21f07..e65a183 100644 ---- a/lib/librte_eal/common/eal_filesystem.h -+++ b/lib/librte_eal/common/eal_filesystem.h -@@ -23,7 +23,8 @@ - - /* sets up platform-specific runtime data dir */ - int --eal_create_runtime_dir(void); -+eal_create_runtime_dir(char *runtime_dir, const int buflen, -+ const struct internal_config *conf); - - int - eal_clean_runtime_dir(void); -@@ -34,15 +35,27 @@ eal_get_hugefile_prefix(void); - - #define RUNTIME_CONFIG_FNAME "config" - static inline const char * --eal_runtime_config_path(void) -+__eal_runtime_config_path(const char *runtime_dir) - { - static char buffer[PATH_MAX]; /* static so auto-zeroed */ - -- snprintf(buffer, sizeof(buffer), "%s/%s", rte_eal_get_runtime_dir(), -+ snprintf(buffer, sizeof(buffer), "%s/%s", runtime_dir, - RUNTIME_CONFIG_FNAME); - return buffer; - } - -+static inline const char * -+eal_runtime_config_path(void) -+{ -+ return __eal_runtime_config_path(rte_eal_get_runtime_dir()); -+} -+ -+static inline const char * -+eal_sec_runtime_config_path(const char *runtime_dir) -+{ -+ return __eal_runtime_config_path(runtime_dir); -+} -+ - /** Path of primary/secondary communication unix socket file. */ - #define MP_SOCKET_FNAME "mp_socket" - static inline const char * -@@ -57,12 +70,29 @@ eal_mp_socket_path(void) - - #define FBARRAY_NAME_FMT "%s/fbarray_%s" - static inline const char * --eal_get_fbarray_path(char *buffer, size_t buflen, const char *name) { -- snprintf(buffer, buflen, FBARRAY_NAME_FMT, rte_eal_get_runtime_dir(), -+__eal_get_fbarray_path(char *buffer, size_t buflen, const char *name, -+ const char *runtime_dir) -+{ -+ snprintf(buffer, buflen, FBARRAY_NAME_FMT, runtime_dir, - name); - return buffer; - } - -+static inline const char * -+eal_get_fbarray_path(char *buffer, size_t buflen, const char *name) -+{ -+ return __eal_get_fbarray_path(buffer, buflen, name, -+ rte_eal_get_runtime_dir()); -+} -+ -+static inline const char * -+eal_sec_get_fbarray_path(char *buffer, size_t buflen, -+ const char *name, const char *runtime_dir) -+{ -+ return __eal_get_fbarray_path(buffer, buflen, name, -+ runtime_dir); -+} -+ - /** Path of hugepage info file. */ - #define HUGEPAGE_INFO_FNAME "hugepage_info" - static inline const char * -@@ -78,15 +108,27 @@ eal_hugepage_info_path(void) - /** Path of hugepage data file. */ - #define HUGEPAGE_DATA_FNAME "hugepage_data" - static inline const char * --eal_hugepage_data_path(void) -+__eal_hugepage_data_path(const char *runtime_dir) - { - static char buffer[PATH_MAX]; /* static so auto-zeroed */ - -- snprintf(buffer, sizeof(buffer), "%s/%s", rte_eal_get_runtime_dir(), -+ snprintf(buffer, sizeof(buffer), "%s/%s", runtime_dir, - HUGEPAGE_DATA_FNAME); - return buffer; - } - -+static inline const char * -+eal_hugepage_data_path(void) -+{ -+ return __eal_hugepage_data_path(rte_eal_get_runtime_dir()); -+} -+ -+static inline const char * -+eal_sec_hugepage_data_path(const char *runtime_dir) -+{ -+ return __eal_hugepage_data_path(runtime_dir); -+} -+ - /** String format for hugepage map files. */ - #define HUGEFILE_FMT "%s/%smap_%d" - static inline const char * -diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h -index 597fd02..1fd32a9 100644 ---- a/lib/librte_eal/common/eal_private.h -+++ b/lib/librte_eal/common/eal_private.h -@@ -113,7 +113,8 @@ int rte_eal_cpu_init(void); - * @return - * 0 on success, negative on error - */ --int rte_eal_memseg_init(void); -+//int rte_eal_memseg_init(void); -+int rte_eal_memseg_init(const int switch_pri_and_sec, const int sec_idx); - - /** - * Map memory -@@ -127,6 +128,9 @@ int rte_eal_memseg_init(void); - */ - int rte_eal_memory_init(void); - -+int rte_eal_sec_memory_init(const int sec_idx); -+int rte_eal_sec_memory_cleanup(const int sec_idx); -+ - /** - * Configure timers - * -@@ -291,7 +295,8 @@ int rte_eal_hugepage_init(void); - * - * This function is private to the EAL. - */ --int rte_eal_hugepage_attach(void); -+//int rte_eal_hugepage_attach(void); -+int rte_eal_hugepage_attach(const int switch_pri_and_sec, const int sec_idx); - - /** - * Find a bus capable of identifying a device. -@@ -450,4 +455,20 @@ eal_get_baseaddr(void); - **/ - bool - eal_is_master_set_affinity(void); -+ -+ -+/****** APIs for libnet ******/ -+#include -+ -+struct rte_memseg * -+rte_sec_mem_virt2memseg(const void *addr, const struct rte_memseg_list *msl, -+ const struct rte_config *rte_cfg); -+ -+struct rte_memseg_list * -+rte_sec_mem_virt2memseg_list(const void *addr, const struct rte_config *rte_cfg); -+ -+int -+rte_sec_memseg_list_walk_thread_unsafe(rte_memseg_list_walk_t func, void *arg, -+ struct rte_config *rte_cfg); -+ - #endif /* _EAL_PRIVATE_H_ */ --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-03-memory.patch b/0009-dpdk-support-gazelle-03-memory.patch deleted file mode 100644 index 5db1b11..0000000 --- a/0009-dpdk-support-gazelle-03-memory.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 482dc8035cfae1c792ca1fa1a2d79e7ea938ee14 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 16:26:22 +0800 -Subject: [PATCH] dpdk-support-gazelle-03-memory - ---- - lib/librte_eal/common/eal_common_memory.c | 88 ++++++++++++++++++----- - lib/librte_eal/common/eal_memalloc.h | 7 ++ - 2 files changed, 79 insertions(+), 16 deletions(-) - -diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c -index 4a9cc1f..842fc9b 100644 ---- a/lib/librte_eal/common/eal_common_memory.c -+++ b/lib/librte_eal/common/eal_common_memory.c -@@ -206,9 +206,9 @@ virt2memseg(const void *addr, const struct rte_memseg_list *msl) - } - - static struct rte_memseg_list * --virt2memseg_list(const void *addr) -+virt2memseg_list(const void *addr, const struct rte_config *rte_cfg) - { -- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; -+ struct rte_mem_config *mcfg = rte_cfg->mem_config; - struct rte_memseg_list *msl; - int msl_idx; - -@@ -230,7 +230,13 @@ virt2memseg_list(const void *addr) - struct rte_memseg_list * - rte_mem_virt2memseg_list(const void *addr) - { -- return virt2memseg_list(addr); -+ return virt2memseg_list(addr, rte_eal_get_configuration()); -+} -+ -+struct rte_memseg_list * -+rte_sec_mem_virt2memseg_list(const void *addr, const struct rte_config *rte_cfg) -+{ -+ return virt2memseg_list(addr, rte_cfg); - } - - struct virtiova { -@@ -283,11 +289,25 @@ rte_mem_iova2virt(rte_iova_t iova) - return vi.virt; - } - -+static struct rte_memseg * -+__rte_mem_virt2memseg(const void *addr, const struct rte_memseg_list *msl, -+ const struct rte_config *rte_cfg) -+{ -+ return virt2memseg(addr, msl != NULL ? msl : -+ rte_sec_mem_virt2memseg_list(addr, rte_cfg)); -+} -+ - struct rte_memseg * - rte_mem_virt2memseg(const void *addr, const struct rte_memseg_list *msl) - { -- return virt2memseg(addr, msl != NULL ? msl : -- rte_mem_virt2memseg_list(addr)); -+ return __rte_mem_virt2memseg(addr, msl, rte_eal_get_configuration()); -+} -+ -+struct rte_memseg * -+rte_sec_mem_virt2memseg(const void *addr, const struct rte_memseg_list *msl, -+ const struct rte_config *rte_cfg) -+{ -+ return __rte_mem_virt2memseg(addr, msl, rte_cfg); - } - - static int -@@ -889,10 +909,14 @@ rte_extmem_detach(void *va_addr, size_t len) - } - - /* init memory subsystem */ --int --rte_eal_memory_init(void) -+static int -+__rte_eal_memory_init(__attribute__((__unused__)) const char *runtime_dir, -+ const struct internal_config *internal_cfg, -+ struct rte_config *rte_cfg, -+ const int switch_pri_and_sec, -+ const int sec_idx) - { -- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; -+ struct rte_mem_config *mcfg = rte_cfg->mem_config; - int retval; - RTE_LOG(DEBUG, EAL, "Setting up physically contiguous memory...\n"); - -@@ -900,25 +924,57 @@ rte_eal_memory_init(void) - return -1; - - /* lock mem hotplug here, to prevent races while we init */ -- rte_mcfg_mem_read_lock(); -+ rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); - -- if (rte_eal_memseg_init() < 0) -+ if (rte_eal_memseg_init(switch_pri_and_sec, sec_idx) < 0) - goto fail; - -- if (eal_memalloc_init() < 0) -- goto fail; -+ if (!internal_cfg->pri_and_sec) -+ if (eal_memalloc_init() < 0) -+ goto fail; - -- retval = rte_eal_process_type() == RTE_PROC_PRIMARY ? -+ retval = rte_cfg->process_type == RTE_PROC_PRIMARY ? - rte_eal_hugepage_init() : -- rte_eal_hugepage_attach(); -+ rte_eal_hugepage_attach(switch_pri_and_sec, sec_idx); - if (retval < 0) - goto fail; - -- if (internal_config.no_shconf == 0 && rte_eal_memdevice_init() < 0) -+ if (internal_cfg->no_shconf == 0 && rte_eal_memdevice_init() < 0) - goto fail; - - return 0; - fail: -- rte_mcfg_mem_read_unlock(); -+ rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); - return -1; - } -+ -+int -+rte_eal_memory_init(void) -+{ -+ const int unused_idx = -1; -+ -+ return __rte_eal_memory_init(rte_eal_get_runtime_dir(), -+ &internal_config, rte_eal_get_configuration(), -+ false, unused_idx); -+} -+ -+int -+rte_eal_sec_memory_init(const int sec_idx) -+{ -+ int ret; -+ struct rte_config *rte_cfg = rte_eal_sec_get_configuration(sec_idx); -+ -+ ret = __rte_eal_memory_init(rte_eal_sec_get_runtime_dir(sec_idx), -+ rte_eal_sec_get_internal_config(sec_idx), rte_cfg, -+ true, sec_idx); -+ -+ rte_rwlock_read_unlock(&rte_cfg->mem_config->memory_hotplug_lock); -+ -+ return ret; -+} -+ -+int -+rte_eal_sec_memory_cleanup(const int sec_idx) -+{ -+ return eal_memalloc_destroy(sec_idx); -+} -diff --git a/lib/librte_eal/common/eal_memalloc.h b/lib/librte_eal/common/eal_memalloc.h -index e953cd8..d5ea6e1 100644 ---- a/lib/librte_eal/common/eal_memalloc.h -+++ b/lib/librte_eal/common/eal_memalloc.h -@@ -83,6 +83,10 @@ eal_memalloc_get_seg_fd(int list_idx, int seg_idx); - int - eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd); - -+int -+eal_sec_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd, -+ const int switch_pri_and_sec, const int sec_idx); -+ - /* returns 0 or -errno */ - int - eal_memalloc_set_seg_list_fd(int list_idx, int fd); -@@ -93,4 +97,7 @@ eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset); - int - eal_memalloc_init(void); - -+int -+eal_memalloc_destroy(const int sec_idx); -+ - #endif /* EAL_MEMALLOC_H */ --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-04-cfg-options.patch b/0009-dpdk-support-gazelle-04-cfg-options.patch deleted file mode 100644 index 8969be8..0000000 --- a/0009-dpdk-support-gazelle-04-cfg-options.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 8eea6474f37eff51eb6f9a178ec6790cf5bed53a Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 16:27:35 +0800 -Subject: [PATCH] dpdk-support-gazelle-03-cfg-options - ---- - config/rte_config.h | 3 +- - lib/librte_eal/common/eal_common_options.c | 46 ++++++++++++++++++---- - lib/librte_eal/common/eal_internal_cfg.h | 2 + - lib/librte_eal/common/eal_options.h | 7 +++- - 4 files changed, 49 insertions(+), 9 deletions(-) - -diff --git a/config/rte_config.h b/config/rte_config.h -index d30786b..b848b1c 100644 ---- a/config/rte_config.h -+++ b/config/rte_config.h -@@ -39,7 +39,8 @@ - #define RTE_MAX_MEMSEG_PER_TYPE 32768 - #define RTE_MAX_MEM_MB_PER_TYPE 65536 - #define RTE_MAX_MEM_MB 524288 --#define RTE_MAX_MEMZONE 2560 -+#define RTE_MAX_MEMZONE 65535 -+#define RTE_MAX_SECONDARY 256 - #define RTE_MAX_TAILQ 32 - #define RTE_LOG_DP_LEVEL RTE_LOG_INFO - #define RTE_BACKTRACE 1 -diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c -index a7f9c5f..34f4199 100644 ---- a/lib/librte_eal/common/eal_common_options.c -+++ b/lib/librte_eal/common/eal_common_options.c -@@ -82,6 +82,7 @@ eal_long_options[] = { - {OPT_LEGACY_MEM, 0, NULL, OPT_LEGACY_MEM_NUM }, - {OPT_SINGLE_FILE_SEGMENTS, 0, NULL, OPT_SINGLE_FILE_SEGMENTS_NUM}, - {OPT_MATCH_ALLOCATIONS, 0, NULL, OPT_MATCH_ALLOCATIONS_NUM}, -+ {OPT_MAP_PERFECT, 0, NULL, OPT_MAP_PERFECT_NUM }, - {0, 0, NULL, 0 } - }; - -@@ -221,6 +222,7 @@ eal_reset_internal_config(struct internal_config *internal_cfg) - internal_cfg->user_mbuf_pool_ops_name = NULL; - CPU_ZERO(&internal_cfg->ctrl_cpuset); - internal_cfg->init_complete = 0; -+ internal_cfg->map_perfect = 0; - } - - static int -@@ -1097,7 +1099,7 @@ eal_parse_iova_mode(const char *name) - } - - static int --eal_parse_base_virtaddr(const char *arg) -+eal_parse_base_virtaddr(const char *arg, struct internal_config *conf) - { - char *end; - uint64_t addr; -@@ -1120,7 +1122,7 @@ eal_parse_base_virtaddr(const char *arg) - * it can align to 2MB for x86. So this alignment can also be used - * on x86 and other architectures. - */ -- internal_config.base_virtaddr = -+ conf->base_virtaddr = - RTE_PTR_ALIGN_CEIL((uintptr_t)addr, (size_t)RTE_PGSIZE_16M); - - return 0; -@@ -1440,7 +1442,7 @@ eal_parse_common_option(int opt, const char *optarg, - } - break; - case OPT_BASE_VIRTADDR_NUM: -- if (eal_parse_base_virtaddr(optarg) < 0) { -+ if (eal_parse_base_virtaddr(optarg, conf) < 0) { - RTE_LOG(ERR, EAL, "invalid parameter for --" - OPT_BASE_VIRTADDR "\n"); - return -1; -@@ -1553,11 +1555,33 @@ eal_adjust_config(struct internal_config *internal_cfg) - } - - int --eal_check_common_options(struct internal_config *internal_cfg) -+eal_sec_adjust_config(struct internal_config *internal_cfg) - { -- struct rte_config *cfg = rte_eal_get_configuration(); -+ struct internal_config *internal_cfg_head; -+ internal_cfg->process_type = RTE_PROC_SECONDARY; -+ -+ internal_cfg_head = rte_eal_sec_get_internal_config(0); -+ for (int i = 0; i < RTE_MAX_SECONDARY; ++i) { -+ if (!internal_cfg_head[i].pri_and_sec) -+ continue; -+ if (internal_cfg == &internal_cfg_head[i]) -+ continue; -+ if (!strcmp(internal_cfg_head[i].hugefile_prefix, internal_cfg->hugefile_prefix)) -+ return -EALREADY; -+ } -+ -+ for (int i = 0; i < RTE_MAX_NUMA_NODES; i++) -+ internal_cfg->memory += internal_cfg->socket_mem[i]; -+ -+ return 0; -+} - -- if (cfg->lcore_role[cfg->master_lcore] != ROLE_RTE) { -+int -+eal_check_common_options(struct internal_config *internal_cfg, -+ struct rte_config *cfg) -+{ -+ if (!internal_cfg->pri_and_sec && -+ cfg->lcore_role[cfg->master_lcore] != ROLE_RTE) { - RTE_LOG(ERR, EAL, "Master lcore is not enabled for DPDK\n"); - return -1; - } -@@ -1602,7 +1626,7 @@ eal_check_common_options(struct internal_config *internal_cfg) - "be specified together with --"OPT_NO_HUGE"\n"); - return -1; - } -- if (internal_config.force_socket_limits && internal_config.legacy_mem) { -+ if (internal_cfg->force_socket_limits && internal_config.legacy_mem) { - RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_LIMIT - " is only supported in non-legacy memory mode\n"); - } -@@ -1635,6 +1659,14 @@ eal_check_common_options(struct internal_config *internal_cfg) - "-m or --"OPT_SOCKET_MEM"\n"); - } - -+ if (internal_cfg->map_perfect || internal_cfg->pri_and_sec) { -+ if (!internal_cfg->legacy_mem || internal_cfg->in_memory || internal_cfg->no_hugetlbfs) { -+ RTE_LOG(ERR, EAL, "Option --"OPT_LEGACY_MEM" or "OPT_IN_MEMORY" or "OPT_NO_HUGE" " -+ "is not compatible with --"OPT_MAP_PERFECT" and "OPT_PRI_AND_SEC"\n"); -+ return -1; -+ } -+ } -+ - return 0; - } - -diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h -index a42f349..50d5da1 100644 ---- a/lib/librte_eal/common/eal_internal_cfg.h -+++ b/lib/librte_eal/common/eal_internal_cfg.h -@@ -82,6 +82,8 @@ struct internal_config { - rte_cpuset_t ctrl_cpuset; /**< cpuset for ctrl threads */ - volatile unsigned int init_complete; - /**< indicates whether EAL has completed initialization */ -+ volatile unsigned pri_and_sec; -+ volatile unsigned map_perfect; - }; - extern struct internal_config internal_config; /**< Global EAL configuration. */ - -diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h -index 9855429..b42d41d 100644 ---- a/lib/librte_eal/common/eal_options.h -+++ b/lib/librte_eal/common/eal_options.h -@@ -69,6 +69,10 @@ enum { - OPT_IOVA_MODE_NUM, - #define OPT_MATCH_ALLOCATIONS "match-allocations" - OPT_MATCH_ALLOCATIONS_NUM, -+#define OPT_PRI_AND_SEC "pri-and-sec" -+ OPT_PRI_AND_SEC_NUM, -+#define OPT_MAP_PERFECT "map-perfect" -+ OPT_MAP_PERFECT_NUM, - OPT_LONG_MAX_NUM - }; - -@@ -79,8 +83,9 @@ int eal_parse_common_option(int opt, const char *argv, - struct internal_config *conf); - int eal_option_device_parse(void); - int eal_adjust_config(struct internal_config *internal_cfg); -+int eal_sec_adjust_config(struct internal_config *internal_cfg); - int eal_cleanup_config(struct internal_config *internal_cfg); --int eal_check_common_options(struct internal_config *internal_cfg); -+int eal_check_common_options(struct internal_config *internal_cfg, struct rte_config *cfg); - void eal_common_usage(void); - enum rte_proc_type_t eal_proc_type_detect(void); - int eal_plugins_init(void); --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-05-fbarray-hugepageinfo.patch b/0009-dpdk-support-gazelle-05-fbarray-hugepageinfo.patch deleted file mode 100644 index 27fc959..0000000 --- a/0009-dpdk-support-gazelle-05-fbarray-hugepageinfo.patch +++ /dev/null @@ -1,186 +0,0 @@ -From ab23196a30701353f626b099fc9c957bcd5bf2a0 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 16:29:00 +0800 -Subject: [PATCH] dpdk-support-gazelle-05-fbarray-hugepageinfo - ---- - lib/librte_eal/common/eal_common_fbarray.c | 106 ++++++++++++++++--- - lib/librte_eal/linux/eal/eal_hugepage_info.c | 2 +- - 2 files changed, 95 insertions(+), 13 deletions(-) - -diff --git a/lib/librte_eal/common/eal_common_fbarray.c b/lib/librte_eal/common/eal_common_fbarray.c -index 1312f93..b611ffa 100644 ---- a/lib/librte_eal/common/eal_common_fbarray.c -+++ b/lib/librte_eal/common/eal_common_fbarray.c -@@ -833,8 +833,9 @@ fail: - return -1; - } - --int --rte_fbarray_attach(struct rte_fbarray *arr) -+static int -+__rte_fbarray_attach(struct rte_fbarray *arr, const char *runtime_dir, -+ const struct internal_config *internal_cfg) - { - struct mem_area *ma = NULL, *tmp = NULL; - size_t page_sz, mmap_len; -@@ -870,13 +871,15 @@ rte_fbarray_attach(struct rte_fbarray *arr) - - mmap_len = calc_data_size(page_sz, arr->elt_sz, arr->len); - -- /* check the tailq - maybe user has already mapped this address space */ -- rte_spinlock_lock(&mem_area_lock); -+ if (!internal_cfg->pri_and_sec) { -+ /* check the tailq - maybe user has already mapped this address space */ -+ rte_spinlock_lock(&mem_area_lock); - -- TAILQ_FOREACH(tmp, &mem_area_tailq, next) { -- if (overlap(tmp, arr->data, mmap_len)) { -- rte_errno = EEXIST; -- goto fail; -+ TAILQ_FOREACH(tmp, &mem_area_tailq, next) { -+ if (overlap(tmp, arr->data, mmap_len)) { -+ rte_errno = EEXIST; -+ goto fail; -+ } - } - } - -@@ -886,7 +889,7 @@ rte_fbarray_attach(struct rte_fbarray *arr) - if (data == NULL) - goto fail; - -- eal_get_fbarray_path(path, sizeof(path), arr->name); -+ eal_sec_get_fbarray_path(path, sizeof(path), arr->name, runtime_dir); - - fd = open(path, O_RDWR); - if (fd < 0) { -@@ -903,16 +906,27 @@ rte_fbarray_attach(struct rte_fbarray *arr) - if (resize_and_map(fd, data, mmap_len)) - goto fail; - -+ if (internal_cfg->pri_and_sec) { -+ if (flock(fd, LOCK_UN)) { -+ rte_errno = errno; -+ goto fail; -+ } -+ close(fd); -+ fd = -1; -+ } -+ - /* store our new memory area */ - ma->addr = data; - ma->fd = fd; /* keep fd until detach/destroy */ - ma->len = mmap_len; - -- TAILQ_INSERT_TAIL(&mem_area_tailq, ma, next); -+ if (!internal_cfg->pri_and_sec) { -+ TAILQ_INSERT_TAIL(&mem_area_tailq, ma, next); - -- /* we're done */ -+ /* we're done */ - -- rte_spinlock_unlock(&mem_area_lock); -+ rte_spinlock_unlock(&mem_area_lock); -+ } - return 0; - fail: - if (data) -@@ -924,6 +938,30 @@ fail: - return -1; - } - -+int -+rte_fbarray_attach(struct rte_fbarray *arr) -+{ -+ return __rte_fbarray_attach(arr, rte_eal_get_runtime_dir(), &internal_config); -+} -+ -+int -+rte_sec_fbarray_attach(struct rte_fbarray *arr, -+ const int switch_pri_and_sec, const int sec_idx) -+{ -+ struct internal_config *internal_cfg = NULL; -+ char *runtime_dir = NULL; -+ -+ if (!switch_pri_and_sec) { -+ runtime_dir = rte_eal_get_runtime_dir(); -+ internal_cfg = &internal_config; -+ } else { -+ runtime_dir = rte_eal_sec_get_runtime_dir(sec_idx); -+ internal_cfg = rte_eal_sec_get_internal_config(sec_idx); -+ } -+ -+ return __rte_fbarray_attach(arr, runtime_dir, internal_cfg); -+} -+ - int - rte_fbarray_detach(struct rte_fbarray *arr) - { -@@ -1063,6 +1101,50 @@ out: - return ret; - } - -+int -+rte_sec_fbarray_destroy(struct rte_fbarray *arr, -+ const int sec_idx) -+{ -+ int fd, ret; -+ size_t mmap_len; -+ char path[PATH_MAX]; -+ -+ if (arr == NULL) { -+ rte_errno = EINVAL; -+ return -1; -+ } -+ -+ size_t page_sz = sysconf(_SC_PAGESIZE); -+ -+ if (page_sz == (size_t)-1) -+ return -1; -+ -+ mmap_len = calc_data_size(page_sz, arr->elt_sz, arr->len); -+ munmap(arr->data, mmap_len); -+ -+ /* try deleting the file */ -+ eal_sec_get_fbarray_path(path, sizeof(path), arr->name, rte_eal_sec_get_runtime_dir(sec_idx)); -+ -+ fd = open(path, O_RDONLY); -+ if (fd < 0) { -+ RTE_LOG(ERR, EAL, "Could not open fbarray file: %s\n", -+ strerror(errno)); -+ return -1; -+ } -+ if (flock(fd, LOCK_EX | LOCK_NB)) { -+ RTE_LOG(DEBUG, EAL, "Cannot destroy fbarray - another process is using it\n"); -+ rte_errno = EBUSY; -+ ret = -1; -+ } else { -+ ret = 0; -+ unlink(path); -+ memset(arr, 0, sizeof(*arr)); -+ } -+ close(fd); -+ -+ return ret; -+} -+ - void * - rte_fbarray_get(const struct rte_fbarray *arr, unsigned int idx) - { -diff --git a/lib/librte_eal/linux/eal/eal_hugepage_info.c b/lib/librte_eal/linux/eal/eal_hugepage_info.c -index 91a4fed..911acec 100644 ---- a/lib/librte_eal/linux/eal/eal_hugepage_info.c -+++ b/lib/librte_eal/linux/eal/eal_hugepage_info.c -@@ -350,7 +350,7 @@ calc_num_pages(struct hugepage_info *hpi, struct dirent *dirent) - */ - total_pages = 0; - /* we also don't want to do this for legacy init */ -- if (!internal_config.legacy_mem) -+ if (!internal_config.legacy_mem || internal_config.map_perfect) - for (i = 0; i < rte_socket_count(); i++) { - int socket = rte_socket_id_by_idx(i); - unsigned int num_pages = --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-06-memalloc.patch b/0009-dpdk-support-gazelle-06-memalloc.patch deleted file mode 100644 index 1e3ba3c..0000000 --- a/0009-dpdk-support-gazelle-06-memalloc.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 5bcdc98f579f8fa2699318b3400f18ee9d629936 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 16:29:41 +0800 -Subject: [PATCH] dpdk-support-gazelle-06-memalloc - ---- - lib/librte_eal/linux/eal/eal_memalloc.c | 127 ++++++++++++++++++++---- - 1 file changed, 110 insertions(+), 17 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal_memalloc.c b/lib/librte_eal/linux/eal/eal_memalloc.c -index cad4934..8e7f120 100644 ---- a/lib/librte_eal/linux/eal/eal_memalloc.c -+++ b/lib/librte_eal/linux/eal/eal_memalloc.c -@@ -95,12 +95,14 @@ static int fallocate_supported = -1; /* unknown */ - * they will be initialized at startup, and filled as we allocate/deallocate - * segments. - */ --static struct { -+struct fd_list{ - int *fds; /**< dynamically allocated array of segment lock fd's */ - int memseg_list_fd; /**< memseg list fd */ - int len; /**< total length of the array */ - int count; /**< entries used in an array */ --} fd_list[RTE_MAX_MEMSEG_LISTS]; -+}; -+static struct fd_list fd_list[RTE_MAX_MEMSEG_LISTS]; -+static struct fd_list sec_fd_list[RTE_MAX_SECONDARY][RTE_MAX_MEMSEG_LISTS]; - - /** local copy of a memory map, used to synchronize memory hotplug in MP */ - static struct rte_memseg_list local_memsegs[RTE_MAX_MEMSEG_LISTS]; -@@ -1391,13 +1393,13 @@ secondary_msl_create_walk(const struct rte_memseg_list *msl, - } - - static int --alloc_list(int list_idx, int len) -+__alloc_list(int list_idx, int len, struct fd_list *fd_ls) - { - int *data; - int i; - - /* single-file segments mode does not need fd list */ -- if (!internal_config.single_file_segments) { -+ if (!internal_config.single_file_segments) { // sec todo - /* ensure we have space to store fd per each possible segment */ - data = malloc(sizeof(int) * len); - if (data == NULL) { -@@ -1407,19 +1409,31 @@ alloc_list(int list_idx, int len) - /* set all fd's as invalid */ - for (i = 0; i < len; i++) - data[i] = -1; -- fd_list[list_idx].fds = data; -- fd_list[list_idx].len = len; -+ fd_ls[list_idx].fds = data; -+ fd_ls[list_idx].len = len; - } else { -- fd_list[list_idx].fds = NULL; -- fd_list[list_idx].len = 0; -+ fd_ls[list_idx].fds = NULL; -+ fd_ls[list_idx].len = 0; - } - -- fd_list[list_idx].count = 0; -- fd_list[list_idx].memseg_list_fd = -1; -+ fd_ls[list_idx].count = 0; -+ fd_ls[list_idx].memseg_list_fd = -1; - - return 0; - } - -+static int -+alloc_list(int list_idx, int len) -+{ -+ return __alloc_list(list_idx, len, fd_list); -+} -+ -+static int -+sec_alloc_list(int list_idx, int len, struct fd_list *fd_ls) -+{ -+ return __alloc_list(list_idx, len, fd_ls); -+} -+ - static int - fd_list_create_walk(const struct rte_memseg_list *msl, - void *arg __rte_unused) -@@ -1437,27 +1451,71 @@ fd_list_create_walk(const struct rte_memseg_list *msl, - return alloc_list(msl_idx, len); - } - --int --eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd) -+static int -+fd_list_destroy_walk(const struct rte_memseg_list *msl, const int sec_idx) - { -- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; -+ struct rte_mem_config *mcfg = rte_eal_sec_get_configuration(sec_idx)->mem_config; -+ struct fd_list *fd_ls = sec_fd_list[sec_idx]; -+ int list_idx; -+ -+ list_idx = msl - mcfg->memsegs; -+ if (fd_ls[list_idx].len != 0) { -+ free(fd_ls[list_idx].fds); -+ /* We have closed fd, seeing in function of eal_legacy_hugepage_attach. */ -+ //close(fd_ls[list_idx].fds[seg_idx]); -+ } -+ memset(&fd_ls[list_idx], 0, sizeof(fd_ls[list_idx])); -+ -+ return 0; -+} -+ -+static int -+__eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd, -+ const struct rte_config *rte_cfg, struct fd_list *fd_ls) -+{ -+ struct rte_mem_config *mcfg = rte_cfg->mem_config; - - /* single file segments mode doesn't support individual segment fd's */ -- if (internal_config.single_file_segments) -+ if (internal_config.single_file_segments) // sec todo - return -ENOTSUP; - - /* if list is not allocated, allocate it */ -- if (fd_list[list_idx].len == 0) { -+ if (fd_ls[list_idx].len == 0) { - int len = mcfg->memsegs[list_idx].memseg_arr.len; - -- if (alloc_list(list_idx, len) < 0) -+ if (sec_alloc_list(list_idx, len, fd_ls) < 0) - return -ENOMEM; - } -- fd_list[list_idx].fds[seg_idx] = fd; -+ fd_ls[list_idx].fds[seg_idx] = fd; - - return 0; - } - -+int -+eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd) -+{ -+ return __eal_memalloc_set_seg_fd(list_idx, seg_idx, fd, -+ rte_eal_get_configuration(), fd_list); -+} -+ -+int -+eal_sec_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd, -+ const int switch_pri_and_sec, const int sec_idx) -+{ -+ struct rte_config *rte_cfg = NULL; -+ struct fd_list *fd_ls = NULL; -+ -+ if (!switch_pri_and_sec) { -+ rte_cfg = rte_eal_get_configuration(); -+ fd_ls = &fd_list[0]; -+ } else { -+ rte_cfg = rte_eal_sec_get_configuration(sec_idx); -+ fd_ls = &sec_fd_list[sec_idx][0]; -+ } -+ -+ return __eal_memalloc_set_seg_fd(list_idx, seg_idx, fd, rte_cfg, fd_ls); -+} -+ - int - eal_memalloc_set_seg_list_fd(int list_idx, int fd) - { -@@ -1602,3 +1660,38 @@ eal_memalloc_init(void) - return -1; - return 0; - } -+ -+int -+eal_memalloc_destroy(const int sec_idx) -+{ -+ int msl_idx = 0; -+ struct rte_memseg_list *msl; -+ struct rte_mem_config *mcfg = rte_eal_sec_get_configuration(sec_idx)->mem_config; -+ -+ for (msl_idx = 0; msl_idx < RTE_MAX_MEMSEG_LISTS; msl_idx++) { -+ -+ msl = &mcfg->memsegs[msl_idx]; -+ -+ /* skip empty memseg lists */ -+ if (msl->memseg_arr.len == 0) -+ continue; -+ -+ if (rte_sec_fbarray_destroy(&msl->memseg_arr, sec_idx)) { -+ RTE_LOG(ERR, EAL, "Cannot clear secondary process local memseg lists\n"); -+ return -1; -+ } -+ -+ if (munmap(msl->base_va, msl->len) < 0) { -+ RTE_LOG(ERR, EAL, "Failed to unmap memseg lists\n"); -+ return -1; -+ } -+ memset(msl, 0, sizeof(*msl)); -+ -+ if (fd_list_destroy_walk(msl, sec_idx)) { -+ RTE_LOG(ERR, EAL, "Failed to clear secondary fd_list.\n"); -+ return -1; -+ } -+ } -+ -+ return 0; -+} --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-07-eal-add-sec-attach.patch b/0009-dpdk-support-gazelle-07-eal-add-sec-attach.patch deleted file mode 100644 index 0f979fd..0000000 --- a/0009-dpdk-support-gazelle-07-eal-add-sec-attach.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 036103c944eac5c6c50e68fc1dad9d72a00b5c2c Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 17:02:45 +0800 -Subject: [PATCH] dpdk-support-gazelle-07-eal-add-sec-attach - ---- - lib/librte_eal/linux/eal/eal.c | 66 ++++++++++++++++++++++++++-------- - 1 file changed, 52 insertions(+), 14 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c -index 8bb1842..735afcd 100644 ---- a/lib/librte_eal/linux/eal/eal.c -+++ b/lib/librte_eal/linux/eal/eal.c -@@ -103,6 +103,12 @@ static char runtime_dir[PATH_MAX]; - - static const char *default_runtime_dir = "/var/run"; - -+/****** APIs for libnet ******/ -+static unsigned int sec_count = 0; -+static struct rte_config sec_rte_config[RTE_MAX_SECONDARY]; -+static struct internal_config sec_internal_config[RTE_MAX_SECONDARY]; -+static char sec_runtime_dir[RTE_MAX_SECONDARY][PATH_MAX]; -+ - static bool master_set_affinity = true; - bool - eal_is_master_set_affinity(void) -@@ -111,7 +117,8 @@ eal_is_master_set_affinity(void) - } - - int --eal_create_runtime_dir(void) -+eal_create_runtime_dir(char *runtime_dir, const int buflen, -+ const struct internal_config *conf) - { - const char *directory = default_runtime_dir; - const char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR"); -@@ -134,8 +141,8 @@ eal_create_runtime_dir(void) - } - - /* create prefix-specific subdirectory under DPDK runtime dir */ -- ret = snprintf(runtime_dir, sizeof(runtime_dir), "%s/%s", -- tmp, eal_get_hugefile_prefix()); -+ ret = snprintf(runtime_dir, buflen, "%s/%s", -+ tmp, conf->hugefile_prefix); - if (ret < 0 || ret == sizeof(runtime_dir)) { - RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n"); - return -1; -@@ -246,12 +253,18 @@ eal_clean_runtime_dir(void) - return -1; - } - --const char * -+char * - rte_eal_get_runtime_dir(void) - { - return runtime_dir; - } - -+char * -+rte_eal_sec_get_runtime_dir(const int sec_idx) -+{ -+ return sec_runtime_dir[sec_idx]; -+} -+ - /* Return user provided mbuf pool ops name */ - const char * - rte_eal_mbuf_user_pool_ops(void) -@@ -266,6 +279,18 @@ rte_eal_get_configuration(void) - return &rte_config; - } - -+struct rte_config * -+rte_eal_sec_get_configuration(const int sec_idx) -+{ -+ return &sec_rte_config[sec_idx]; -+} -+ -+struct internal_config * -+rte_eal_sec_get_internal_config(const int sec_idx) -+{ -+ return &sec_internal_config[sec_idx]; -+} -+ - enum rte_iova_mode - rte_eal_iova_mode(void) - { -@@ -395,18 +420,22 @@ rte_eal_config_create(void) - - /* attach to an existing shared memory config */ - static int --rte_eal_config_attach(void) -+__rte_eal_config_attach(const int mmap_flags, int *mem_cfg_fd, -+ const char *runtime_dir, -+ const struct internal_config *internal_cfg, -+ struct rte_config *rte_cfg) - { - struct rte_mem_config *mem_config; -+ int mcfg_fd = *mem_cfg_fd; - -- const char *pathname = eal_runtime_config_path(); -+ const char *pathname = eal_sec_runtime_config_path(runtime_dir); - -- if (internal_config.no_shconf) -+ if (internal_cfg->no_shconf) - return 0; - -- if (mem_cfg_fd < 0){ -- mem_cfg_fd = open(pathname, O_RDWR); -- if (mem_cfg_fd < 0) { -+ if (mcfg_fd < 0){ -+ mcfg_fd = open(pathname, O_RDWR); -+ if (mcfg_fd < 0) { - RTE_LOG(ERR, EAL, "Cannot open '%s' for rte_mem_config\n", - pathname); - return -1; -@@ -415,20 +444,29 @@ rte_eal_config_attach(void) - - /* map it as read-only first */ - mem_config = (struct rte_mem_config *) mmap(NULL, sizeof(*mem_config), -- PROT_READ, MAP_SHARED, mem_cfg_fd, 0); -+ mmap_flags, MAP_SHARED, mcfg_fd, 0); - if (mem_config == MAP_FAILED) { -- close(mem_cfg_fd); -- mem_cfg_fd = -1; -+ close(mcfg_fd); -+ mcfg_fd = -1; - RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config! error %i (%s)\n", - errno, strerror(errno)); - return -1; - } - -- rte_config.mem_config = mem_config; -+ rte_cfg->mem_config = mem_config; -+ *mem_cfg_fd = mcfg_fd; - - return 0; - } - -+static int -+rte_eal_config_attach(void) -+{ -+ return __rte_eal_config_attach(PROT_READ, &mem_cfg_fd, -+ rte_eal_get_runtime_dir(), &internal_config, -+ rte_eal_get_configuration()); -+} -+ - /* reattach the shared config at exact memory location primary process has it */ - static int - rte_eal_config_reattach(void) --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-08-eal-add-config.patch b/0009-dpdk-support-gazelle-08-eal-add-config.patch deleted file mode 100644 index f5450d6..0000000 --- a/0009-dpdk-support-gazelle-08-eal-add-config.patch +++ /dev/null @@ -1,194 +0,0 @@ -From d3021c3a436580dfcca2156f110c7d9125798021 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 17:16:05 +0800 -Subject: [PATCH] dpdk-support-gazelle-08-eal-add-config - ---- - lib/librte_eal/linux/eal/eal.c | 92 ++++++++++++++++++++++++++++------ - 1 file changed, 76 insertions(+), 16 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c -index 735afcd..2de9914 100644 ---- a/lib/librte_eal/linux/eal/eal.c -+++ b/lib/librte_eal/linux/eal/eal.c -@@ -569,6 +569,45 @@ rte_config_init(void) - return 0; - } - -+static void -+rte_sec_config_init(const int sec_idx) -+{ -+ int mem_cfg_fd = -1; -+ int mmap_flags = PROT_READ | PROT_WRITE; -+ -+ struct rte_config *rte_cfg = rte_eal_sec_get_configuration(sec_idx); -+ struct internal_config *internal_cfg = rte_eal_sec_get_internal_config(sec_idx); -+ -+ rte_cfg->process_type = internal_cfg->process_type; -+ -+ __rte_eal_config_attach(mmap_flags, &mem_cfg_fd, -+ rte_eal_sec_get_runtime_dir(sec_idx), -+ internal_cfg, rte_cfg); -+ -+ close(mem_cfg_fd); -+} -+ -+static int -+eal_sec_config_cleanup(const int sec_idx) -+{ -+ int ret; -+ struct rte_config *lc_rte_cfg = rte_eal_sec_get_configuration(sec_idx); -+ struct internal_config *lc_internal_cfg = rte_eal_sec_get_internal_config(sec_idx); -+ char *lc_runtime_dir = rte_eal_sec_get_runtime_dir(sec_idx); -+ -+ ret = munmap(lc_rte_cfg->mem_config, sizeof(*lc_rte_cfg->mem_config)); -+ if (ret < 0) { -+ RTE_LOG(ERR, EAL, "Failed to unmap config memory!\n"); -+ return -1; -+ } -+ -+ memset(lc_rte_cfg, 0, sizeof(*lc_rte_cfg)); -+ memset(lc_internal_cfg, 0, sizeof(*lc_internal_cfg)); -+ memset(lc_runtime_dir, 0, PATH_MAX); -+ -+ return 0; -+} -+ - /* Unlocks hugepage directories that were locked by eal_hugepage_info_init */ - static void - eal_hugedirs_unlock(void) -@@ -604,6 +643,7 @@ eal_usage(const char *prgname) - " --"OPT_LEGACY_MEM" Legacy memory mode (no dynamic allocation, contiguous segments)\n" - " --"OPT_SINGLE_FILE_SEGMENTS" Put all hugepage memory in single files\n" - " --"OPT_MATCH_ALLOCATIONS" Free hugepages exactly as allocated\n" -+ " --"OPT_MAP_PERFECT" Map virtual addresses according to configured hugepage size\n" - "\n"); - /* Allow the application to print its usage message too if hook is set */ - if ( rte_application_usage_hook ) { -@@ -731,7 +771,9 @@ eal_log_level_parse(int argc, char **argv) - - /* Parse the argument given in the command line of the application */ - static int --eal_parse_args(int argc, char **argv) -+__eal_parse_args(int argc, char **argv, char *runtime_dir, const int buflen, -+ struct internal_config *internal_cfg, -+ struct rte_config *rte_cfg) - { - int opt, ret; - char **argvopt; -@@ -762,7 +804,7 @@ eal_parse_args(int argc, char **argv) - goto out; - } - -- ret = eal_parse_common_option(opt, optarg, &internal_config); -+ ret = eal_parse_common_option(opt, optarg, internal_cfg); - /* common parser is not happy */ - if (ret < 0) { - eal_usage(prgname); -@@ -785,9 +827,9 @@ eal_parse_args(int argc, char **argv) - RTE_LOG(ERR, EAL, "Could not store hugepage directory\n"); - else { - /* free old hugepage dir */ -- if (internal_config.hugepage_dir != NULL) -- free(internal_config.hugepage_dir); -- internal_config.hugepage_dir = hdir; -+ if (internal_cfg->hugepage_dir != NULL) -+ free(internal_cfg->hugepage_dir); -+ internal_cfg->hugepage_dir = hdir; - } - break; - } -@@ -798,34 +840,34 @@ eal_parse_args(int argc, char **argv) - RTE_LOG(ERR, EAL, "Could not store file prefix\n"); - else { - /* free old prefix */ -- if (internal_config.hugefile_prefix != NULL) -- free(internal_config.hugefile_prefix); -- internal_config.hugefile_prefix = prefix; -+ if (internal_cfg->hugefile_prefix != NULL) -+ free(internal_cfg->hugefile_prefix); -+ internal_cfg->hugefile_prefix = prefix; - } - break; - } - case OPT_SOCKET_MEM_NUM: - if (eal_parse_socket_arg(optarg, -- internal_config.socket_mem) < 0) { -+ internal_cfg->socket_mem) < 0) { - RTE_LOG(ERR, EAL, "invalid parameters for --" - OPT_SOCKET_MEM "\n"); - eal_usage(prgname); - ret = -1; - goto out; - } -- internal_config.force_sockets = 1; -+ internal_cfg->force_sockets = 1; - break; - - case OPT_SOCKET_LIMIT_NUM: - if (eal_parse_socket_arg(optarg, -- internal_config.socket_limit) < 0) { -+ internal_cfg->socket_limit) < 0) { - RTE_LOG(ERR, EAL, "invalid parameters for --" - OPT_SOCKET_LIMIT "\n"); - eal_usage(prgname); - ret = -1; - goto out; - } -- internal_config.force_socket_limits = 1; -+ internal_cfg->force_socket_limits = 1; - break; - - case OPT_VFIO_INTR_NUM: -@@ -839,7 +881,7 @@ eal_parse_args(int argc, char **argv) - break; - - case OPT_CREATE_UIO_DEV_NUM: -- internal_config.create_uio_dev = 1; -+ internal_cfg->create_uio_dev = 1; - break; - - case OPT_MBUF_POOL_OPS_NAME_NUM: -@@ -849,11 +891,11 @@ eal_parse_args(int argc, char **argv) - RTE_LOG(ERR, EAL, "Could not store mbuf pool ops name\n"); - else { - /* free old ops name */ -- if (internal_config.user_mbuf_pool_ops_name != -+ if (internal_cfg->user_mbuf_pool_ops_name != - NULL) -- free(internal_config.user_mbuf_pool_ops_name); -+ free(internal_cfg->user_mbuf_pool_ops_name); - -- internal_config.user_mbuf_pool_ops_name = -+ internal_cfg->user_mbuf_pool_ops_name = - ops_name; - } - break; -@@ -914,6 +956,24 @@ eal_parse_args(int argc, char **argv) - return ret; - } - -+static int -+eal_parse_args(int argc, char **argv) -+{ -+ return __eal_parse_args(argc, argv, -+ rte_eal_get_runtime_dir(), PATH_MAX, -+ &internal_config, -+ rte_eal_get_configuration()); -+} -+ -+static int -+eal_sec_parse_args(int argc, char **argv, const int sec_idx) -+{ -+ return __eal_parse_args(argc, argv, -+ rte_eal_sec_get_runtime_dir(sec_idx), PATH_MAX, -+ rte_eal_sec_get_internal_config(sec_idx), -+ rte_eal_sec_get_configuration(sec_idx)); -+} -+ - static int - check_socket(const struct rte_memseg_list *msl, void *arg) - { --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-09-eal-add-libnetapi.patch b/0009-dpdk-support-gazelle-09-eal-add-libnetapi.patch deleted file mode 100644 index 399d63e..0000000 --- a/0009-dpdk-support-gazelle-09-eal-add-libnetapi.patch +++ /dev/null @@ -1,161 +0,0 @@ -From d81c5f9a3e78ae18f78caeb8791e8e3947151273 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 17:16:50 +0800 -Subject: [PATCH] dpdk-support-gazelle-09-eal-add-libnetapi - ---- - lib/librte_eal/linux/eal/eal.c | 119 +++++++++++++++++++++++++++++++-- - 1 file changed, 112 insertions(+), 7 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c -index 2de9914..a1f2b42 100644 ---- a/lib/librte_eal/linux/eal/eal.c -+++ b/lib/librte_eal/linux/eal/eal.c -@@ -901,7 +901,11 @@ __eal_parse_args(int argc, char **argv, char *runtime_dir, const int buflen, - break; - } - case OPT_MATCH_ALLOCATIONS_NUM: -- internal_config.match_allocations = 1; -+ internal_cfg->match_allocations = 1; -+ break; -+ -+ case OPT_MAP_PERFECT_NUM: -+ internal_cfg->map_perfect = 1; - break; - - default: -@@ -924,20 +928,25 @@ __eal_parse_args(int argc, char **argv, char *runtime_dir, const int buflen, - } - - /* create runtime data directory */ -- if (internal_config.no_shconf == 0 && -- eal_create_runtime_dir() < 0) { -+ if (internal_cfg->no_shconf == 0 && -+ eal_create_runtime_dir(runtime_dir, buflen, internal_cfg) < 0) { - RTE_LOG(ERR, EAL, "Cannot create runtime directory\n"); - ret = -1; - goto out; - } - -- if (eal_adjust_config(&internal_config) != 0) { -- ret = -1; -- goto out; -+ if (!internal_cfg->pri_and_sec) { -+ ret = eal_adjust_config(internal_cfg); -+ if (ret != 0) -+ goto out; -+ } else { -+ ret = eal_sec_adjust_config(internal_cfg); -+ if (ret != 0) -+ goto out; - } - - /* sanity checks */ -- if (eal_check_common_options(&internal_config) != 0) { -+ if (eal_check_common_options(internal_cfg, rte_cfg) != 0) { - eal_usage(prgname); - ret = -1; - goto out; -@@ -1504,3 +1513,99 @@ rte_eal_check_module(const char *module_name) - /* Module has been found */ - return 1; - } -+ -+ -+/****** APIs for libnet ******/ -+int -+rte_eal_sec_attach(int argc, char **argv) -+{ -+ int ret; -+ int sec_idx = -1; -+ struct internal_config *lc_internal_cfg = NULL; -+ -+ if (sec_count >= RTE_MAX_SECONDARY) { -+ RTE_LOG(ERR, EAL, "Too many secondary processes: %d.\n", sec_count); -+ rte_errno = EINVAL; -+ return -1; -+ } -+ -+ for (int i = 0; i < RTE_MAX_SECONDARY; ++i) { -+ if (sec_internal_config[i].pri_and_sec == 0) { -+ sec_internal_config[i].pri_and_sec = 1; -+ sec_idx = i; -+ break; -+ } -+ } -+ lc_internal_cfg = rte_eal_sec_get_internal_config(sec_idx); -+ -+ eal_reset_internal_config(lc_internal_cfg); -+ -+ ret = eal_sec_parse_args(argc, argv, sec_idx); -+ if (ret < 0) { -+ if (ret == -EALREADY) { -+ RTE_LOG(ERR, EAL, "file_refix %s already called initialization.\n", -+ lc_internal_cfg->hugefile_prefix); -+ rte_errno = EALREADY; -+ } else { -+ RTE_LOG(ERR, EAL, "Invalid 'command line' arguments.\n"); -+ rte_errno = EINVAL; -+ } -+ return -1; -+ } -+ -+ rte_sec_config_init(sec_idx); -+ -+ ret = rte_eal_sec_memory_init(sec_idx); -+ if (ret < 0) { -+ RTE_LOG(ERR, EAL, "Cannot init memory\n"); -+ rte_errno = ENOMEM; -+ return -1; -+ } -+ -+ sec_count++; -+ return 0; -+} -+ -+int -+rte_eal_sec_detach(const char *file_prefix, int length) -+{ -+ int ret; -+ int sec_idx = -1; -+ -+ if (!file_prefix || length <= 0) { -+ RTE_LOG(ERR, EAL, "Invalid 'file_prefix or length' arguments.\n"); -+ rte_errno = EINVAL; -+ return -1; -+ } -+ -+ for (int i = 0; i < RTE_MAX_SECONDARY; ++i) { -+ if (sec_internal_config[i].pri_and_sec == 0) -+ continue; -+ if (!strncmp(sec_internal_config[i].hugefile_prefix, file_prefix, length)) { -+ sec_idx = i; -+ break; -+ } -+ } -+ if (sec_idx == -1) { -+ RTE_LOG(ERR, EAL, "Cannot find file_prefix %s.\n", file_prefix); -+ rte_errno = EINVAL; -+ return -1; -+ } -+ -+ ret = rte_eal_sec_memory_cleanup(sec_idx); -+ if (ret < 0) { -+ RTE_LOG(ERR, EAL, "Cannot cleanup memory\n"); -+ rte_errno = ENOMEM; -+ return -1; -+ } -+ -+ ret = eal_sec_config_cleanup(sec_idx); -+ if (ret < 0) { -+ RTE_LOG(ERR, EAL, "Cannot cleanup hugepage sharefile.\n"); -+ rte_errno = EACCES; -+ return -1; -+ } -+ -+ sec_count--; -+ return 0; -+} --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-10-eal-memory-inter-config.patch b/0009-dpdk-support-gazelle-10-eal-memory-inter-config.patch deleted file mode 100644 index ee5f31e..0000000 --- a/0009-dpdk-support-gazelle-10-eal-memory-inter-config.patch +++ /dev/null @@ -1,174 +0,0 @@ -From a0305b4a007717f7d297c3c2a61d01f688f29847 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 19:44:26 +0800 -Subject: [PATCH] dpdk-support-gazelle-10-eal-memory-inter-config - ---- - lib/librte_eal/linux/eal/eal_memory.c | 72 +++++++++++++++++++++++---- - 1 file changed, 61 insertions(+), 11 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal_memory.c b/lib/librte_eal/linux/eal/eal_memory.c -index 43e4ffc..db70ac8 100644 ---- a/lib/librte_eal/linux/eal/eal_memory.c -+++ b/lib/librte_eal/linux/eal/eal_memory.c -@@ -1055,10 +1055,10 @@ remap_needed_hugepages(struct hugepage_file *hugepages, int n_pages) - * address to lower address. Here, physical addresses are in - * descending order. - */ -- else if ((prev->physaddr - cur->physaddr) != cur->size) -+ else if (!internal_config.map_perfect && (prev->physaddr - cur->physaddr) != cur->size) - new_memseg = 1; - #else -- else if ((cur->physaddr - prev->physaddr) != cur->size) -+ else if (!internal_config.map_perfect && (cur->physaddr - prev->physaddr) != cur->size) - new_memseg = 1; - #endif - -@@ -1457,6 +1457,24 @@ eal_legacy_hugepage_init(void) - /* meanwhile, also initialize used_hp hugepage sizes in used_hp */ - used_hp[i].hugepage_sz = internal_config.hugepage_info[i].hugepage_sz; - -+ if (internal_config.map_perfect) { -+ int sys_num_pages = 0; -+ int need_num_pages = 0; -+ struct rte_memseg_list *msl; -+ -+ for (j = 0; j < RTE_MAX_NUMA_NODES; j++) { -+ sys_num_pages += internal_config.hugepage_info[i].num_pages[j]; -+ } -+ -+ for (j = 0; j < RTE_MAX_MEMSEG_LISTS; j++) { -+ msl = &mcfg->memsegs[j]; -+ if (internal_config.hugepage_info[i].hugepage_sz == msl->page_sz) -+ need_num_pages += msl->memseg_arr.len; -+ } -+ -+ internal_config.hugepage_info[i].num_pages[0] = RTE_MIN(sys_num_pages, need_num_pages); -+ } -+ - nr_hugepages += internal_config.hugepage_info[i].num_pages[0]; - } - -@@ -1537,8 +1555,13 @@ eal_legacy_hugepage_init(void) - goto fail; - } - -- qsort(&tmp_hp[hp_offset], hpi->num_pages[0], -- sizeof(struct hugepage_file), cmp_physaddr); -+ /* continuous physical memory does not bring performance improvements, -+ * so no sorting is performed for quick startup. -+ */ -+ if (!internal_config.map_perfect) { -+ qsort(&tmp_hp[hp_offset], hpi->num_pages[0], -+ sizeof(struct hugepage_file), cmp_physaddr); -+ } - - /* we have processed a num of hugepages of this size, so inc offset */ - hp_offset += hpi->num_pages[0]; -@@ -2228,11 +2251,20 @@ memseg_primary_init(void) - uint64_t max_mem, max_mem_per_type; - unsigned int max_seglists_per_type; - unsigned int n_memtypes, cur_type; -+ struct hugepage_info used_hp[MAX_HUGEPAGE_SIZES]; - - /* no-huge does not need this at all */ - if (internal_config.no_hugetlbfs) - return 0; - -+ if (internal_config.map_perfect) { -+ memset(used_hp, 0, sizeof(used_hp)); -+ ret = eal_sec_set_num_pages(&internal_config, used_hp); -+ if (ret == -1) { -+ RTE_LOG(ERR, EAL, "Cannot get num pages\n"); -+ } -+ } -+ - /* - * figuring out amount of memory we're going to have is a long and very - * involved process. the basic element we're operating with is a memory -@@ -2329,6 +2361,7 @@ memseg_primary_init(void) - struct memtype *type = &memtypes[cur_type]; - uint64_t max_mem_per_list, pagesz; - int socket_id; -+ unsigned int need_n_segs, cur_n_segs; - - pagesz = type->page_sz; - socket_id = type->socket_id; -@@ -2372,8 +2405,17 @@ memseg_primary_init(void) - "n_segs:%i socket_id:%i hugepage_sz:%" PRIu64 "\n", - n_seglists, n_segs, socket_id, pagesz); - -+ if (internal_config.map_perfect) -+ need_n_segs = eal_sec_get_num_pages(used_hp, pagesz, socket_id); -+ else -+ need_n_segs = n_segs; -+ - /* create all segment lists */ -- for (cur_seglist = 0; cur_seglist < n_seglists; cur_seglist++) { -+ for (cur_seglist = 0; cur_seglist < n_seglists && need_n_segs > 0; cur_seglist++) { -+ cur_n_segs = RTE_MIN(need_n_segs, n_segs); -+ if (internal_config.map_perfect) -+ need_n_segs -= cur_n_segs; -+ - if (msl_idx >= RTE_MAX_MEMSEG_LISTS) { - RTE_LOG(ERR, EAL, - "No more space in memseg lists, please increase %s\n", -@@ -2400,9 +2442,10 @@ memseg_primary_init(void) - } - - static int --memseg_secondary_init(void) -+memseg_secondary_init(struct rte_config *rte_cfg, -+ const int switch_pri_and_sec, const int sec_idx) - { -- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; -+ struct rte_mem_config *mcfg = rte_cfg->mem_config; - int msl_idx = 0; - struct rte_memseg_list *msl; - -@@ -2414,7 +2457,7 @@ memseg_secondary_init(void) - if (msl->memseg_arr.len == 0) - continue; - -- if (rte_fbarray_attach(&msl->memseg_arr)) { -+ if (rte_sec_fbarray_attach(&msl->memseg_arr, switch_pri_and_sec, sec_idx)) { - RTE_LOG(ERR, EAL, "Cannot attach to primary process memseg lists\n"); - return -1; - } -@@ -2430,11 +2473,18 @@ memseg_secondary_init(void) - } - - int --rte_eal_memseg_init(void) -+rte_eal_memseg_init(const int switch_pri_and_sec, const int sec_idx) - { - /* increase rlimit to maximum */ - struct rlimit lim; - -+ struct rte_config *rte_cfg = NULL; -+ if (!switch_pri_and_sec) { -+ rte_cfg = rte_eal_get_configuration(); -+ } else { -+ rte_cfg = rte_eal_sec_get_configuration(sec_idx); -+ } -+ - if (getrlimit(RLIMIT_NOFILE, &lim) == 0) { - /* set limit to maximum */ - lim.rlim_cur = lim.rlim_max; -@@ -2458,11 +2508,11 @@ rte_eal_memseg_init(void) - } - #endif - -- return rte_eal_process_type() == RTE_PROC_PRIMARY ? -+ return rte_cfg->process_type == RTE_PROC_PRIMARY ? - #ifndef RTE_ARCH_64 - memseg_primary_init_32() : - #else - memseg_primary_init() : - #endif -- memseg_secondary_init(); -+ memseg_secondary_init(rte_cfg, switch_pri_and_sec, sec_idx); - } --- -2.23.0 - diff --git a/0009-dpdk-support-gazelle-11-eal-memory-add-sec.patch b/0009-dpdk-support-gazelle-11-eal-memory-add-sec.patch deleted file mode 100644 index f0a1a0d..0000000 --- a/0009-dpdk-support-gazelle-11-eal-memory-add-sec.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 8b1f62be35c36c78793d3fd3935b9898cf957673 Mon Sep 17 00:00:00 2001 -From: wuchangsheng -Date: Tue, 30 Mar 2021 19:45:21 +0800 -Subject: [PATCH] dpdk-support-gazelle-11-eal-memory-add-sec - ---- - lib/librte_eal/linux/eal/eal_memory.c | 99 +++++++++++++++++++++++---- - 1 file changed, 87 insertions(+), 12 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal_memory.c b/lib/librte_eal/linux/eal/eal_memory.c -index db70ac8..ac81f43 100644 ---- a/lib/librte_eal/linux/eal/eal_memory.c -+++ b/lib/librte_eal/linux/eal/eal_memory.c -@@ -1880,9 +1880,9 @@ getFileSize(int fd) - * in order to form a contiguous block in the virtual memory space - */ - static int --eal_legacy_hugepage_attach(void) -+eal_legacy_hugepage_attach(const int switch_pri_and_sec, const int sec_idx) - { -- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; -+ struct rte_mem_config *mcfg = NULL; - struct hugepage_file *hp = NULL; - unsigned int num_hp = 0; - unsigned int i = 0; -@@ -1890,6 +1890,22 @@ eal_legacy_hugepage_attach(void) - off_t size = 0; - int fd, fd_hugepage = -1; - -+ struct rte_config *rte_cfg = NULL; -+ struct internal_config *internal_cfg = NULL; -+ char *runtime_dir = NULL; -+ -+ if (!switch_pri_and_sec) { -+ runtime_dir = rte_eal_get_runtime_dir(); -+ rte_cfg = rte_eal_get_configuration(); -+ internal_cfg = &internal_config; -+ } else { -+ runtime_dir = rte_eal_sec_get_runtime_dir(sec_idx); -+ rte_cfg = rte_eal_sec_get_configuration(sec_idx); -+ internal_cfg = rte_eal_sec_get_internal_config(sec_idx); -+ } -+ -+ mcfg = rte_cfg->mem_config; -+ - if (aslr_enabled() > 0) { - RTE_LOG(WARNING, EAL, "WARNING: Address Space Layout Randomization " - "(ASLR) is enabled in the kernel.\n"); -@@ -1897,10 +1913,10 @@ eal_legacy_hugepage_attach(void) - "into secondary processes\n"); - } - -- fd_hugepage = open(eal_hugepage_data_path(), O_RDONLY); -+ fd_hugepage = open(eal_sec_hugepage_data_path(runtime_dir), O_RDONLY); - if (fd_hugepage < 0) { - RTE_LOG(ERR, EAL, "Could not open %s\n", -- eal_hugepage_data_path()); -+ eal_sec_hugepage_data_path(runtime_dir)); - goto error; - } - -@@ -1908,7 +1924,7 @@ eal_legacy_hugepage_attach(void) - hp = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd_hugepage, 0); - if (hp == MAP_FAILED) { - RTE_LOG(ERR, EAL, "Could not mmap %s\n", -- eal_hugepage_data_path()); -+ eal_sec_hugepage_data_path(runtime_dir)); - goto error; - } - -@@ -1955,13 +1971,13 @@ eal_legacy_hugepage_attach(void) - } - - /* find segment data */ -- msl = rte_mem_virt2memseg_list(map_addr); -+ msl = rte_sec_mem_virt2memseg_list(map_addr, rte_cfg); - if (msl == NULL) { - RTE_LOG(DEBUG, EAL, "%s(): Cannot find memseg list\n", - __func__); - goto fd_error; - } -- ms = rte_mem_virt2memseg(map_addr, msl); -+ ms = rte_sec_mem_virt2memseg(map_addr, msl, rte_cfg); - if (ms == NULL) { - RTE_LOG(DEBUG, EAL, "%s(): Cannot find memseg\n", - __func__); -@@ -1976,8 +1992,16 @@ eal_legacy_hugepage_attach(void) - goto fd_error; - } - -+ /* No hugefile lock is required in PRI_AND_SEC mode, close it -+ * to avoid opening too much fd. -+ */ -+ if (internal_cfg->pri_and_sec) { -+ close(fd); -+ fd = -1; -+ } -+ - /* store segment fd internally */ -- if (eal_memalloc_set_seg_fd(msl_idx, ms_idx, fd) < 0) -+ if (eal_sec_memalloc_set_seg_fd(msl_idx, ms_idx, fd, switch_pri_and_sec, sec_idx) < 0) - RTE_LOG(ERR, EAL, "Could not store segment fd: %s\n", - rte_strerror(rte_errno)); - } -@@ -2026,10 +2050,17 @@ rte_eal_hugepage_init(void) - } - - int --rte_eal_hugepage_attach(void) -+rte_eal_hugepage_attach(const int switch_pri_and_sec, const int sec_idx) - { -- return internal_config.legacy_mem ? -- eal_legacy_hugepage_attach() : -+ struct internal_config *internal_cfg; -+ -+ if (!switch_pri_and_sec) -+ internal_cfg = &internal_config; -+ else -+ internal_cfg = rte_eal_sec_get_internal_config(sec_idx); -+ -+ return internal_cfg->legacy_mem ? -+ eal_legacy_hugepage_attach(switch_pri_and_sec, sec_idx) : - eal_hugepage_attach(); - } - -@@ -2238,6 +2269,50 @@ memseg_primary_init_32(void) - return 0; - } - -+static int -+eal_sec_set_num_pages(struct internal_config *internal_cfg, -+ struct hugepage_info *used_hp) -+{ -+ int ret; -+ int hp_sz_idx; -+ uint64_t memory[RTE_MAX_NUMA_NODES]; -+ -+ if (!internal_cfg || !used_hp) { -+ return -1; -+ } -+ -+ for (hp_sz_idx = 0; -+ hp_sz_idx < (int) internal_cfg->num_hugepage_sizes; -+ hp_sz_idx++) { -+ struct hugepage_info *hpi; -+ hpi = &internal_cfg->hugepage_info[hp_sz_idx]; -+ used_hp[hp_sz_idx].hugepage_sz = hpi->hugepage_sz; -+ } -+ -+ for (hp_sz_idx = 0; hp_sz_idx < RTE_MAX_NUMA_NODES; hp_sz_idx++) -+ memory[hp_sz_idx] = internal_cfg->socket_mem[hp_sz_idx]; -+ -+ ret = calc_num_pages_per_socket(memory, -+ internal_cfg->hugepage_info, used_hp, -+ internal_cfg->num_hugepage_sizes); -+ -+ return ret; -+} -+ -+static int -+eal_sec_get_num_pages(const struct hugepage_info *used_hp, -+ uint64_t hugepage_sz, int socket) -+{ -+ int hp_sz_idx; -+ -+ for (hp_sz_idx = 0; hp_sz_idx < MAX_HUGEPAGE_SIZES; hp_sz_idx++) { -+ if (used_hp[hp_sz_idx].hugepage_sz == hugepage_sz) -+ return used_hp[hp_sz_idx].num_pages[socket]; -+ } -+ -+ return 0; -+} -+ - static int __rte_unused - memseg_primary_init(void) - { -@@ -2424,7 +2499,7 @@ memseg_primary_init(void) - } - msl = &mcfg->memsegs[msl_idx++]; - -- if (alloc_memseg_list(msl, pagesz, n_segs, -+ if (alloc_memseg_list(msl, pagesz, cur_n_segs, - socket_id, cur_seglist)) - goto out; - --- -2.23.0 - diff --git a/0009-net-hns3-remove-unnecessary-memset.patch b/0009-net-hns3-remove-unnecessary-memset.patch new file mode 100644 index 0000000..bc0f347 --- /dev/null +++ b/0009-net-hns3-remove-unnecessary-memset.patch @@ -0,0 +1,37 @@ +From c06b9cd500facfb6a10057490c1ec1090408ff12 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Wed, 6 Jan 2021 11:46:32 +0800 +Subject: [PATCH 009/189] net/hns3: remove unnecessary memset + +The hns3_cmd_desc has memset when setup and the memset +for req is unnecessary. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_rss.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index e2f0468..b5df374 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -633,16 +633,11 @@ hns3_set_rss_tc_mode(struct hns3_hw *hw) + static void + hns3_rss_tuple_uninit(struct hns3_hw *hw) + { +- struct hns3_rss_input_tuple_cmd *req; + struct hns3_cmd_desc desc; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); + +- req = (struct hns3_rss_input_tuple_cmd *)desc.data; +- +- memset(req, 0, sizeof(struct hns3_rss_tuple_cfg)); +- + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { + hns3_err(hw, "RSS uninit tuple failed %d", ret); +-- +2.7.4 + diff --git a/0010-dpdk-fix-error-in-clearing-secondary-process-memseg-lists.patch b/0010-dpdk-fix-error-in-clearing-secondary-process-memseg-lists.patch deleted file mode 100644 index ddb4c02..0000000 --- a/0010-dpdk-fix-error-in-clearing-secondary-process-memseg-lists.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4bda889d737ee2b1fb2381e658bcf4f2a7ca21c8 Mon Sep 17 00:00:00 2001 -From: HuangLiming -Date: Tue, 18 Aug 2020 04:58:53 -0400 -Subject: [PATCH] fix error in clearing secondary process memseg lists - -Signed-off-by: HuangLiming ---- - lib/librte_eal/common/eal_common_fbarray.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/lib/librte_eal/common/eal_common_fbarray.c b/lib/librte_eal/common/eal_common_fbarray.c -index b611ffa..116c695 100644 ---- a/lib/librte_eal/common/eal_common_fbarray.c -+++ b/lib/librte_eal/common/eal_common_fbarray.c -@@ -1105,7 +1105,7 @@ int - rte_sec_fbarray_destroy(struct rte_fbarray *arr, - const int sec_idx) - { -- int fd, ret; -+ int fd; - size_t mmap_len; - char path[PATH_MAX]; - -@@ -1134,15 +1134,13 @@ rte_sec_fbarray_destroy(struct rte_fbarray *arr, - if (flock(fd, LOCK_EX | LOCK_NB)) { - RTE_LOG(DEBUG, EAL, "Cannot destroy fbarray - another process is using it\n"); - rte_errno = EBUSY; -- ret = -1; - } else { -- ret = 0; - unlink(path); - memset(arr, 0, sizeof(*arr)); - } - close(fd); - -- return ret; -+ return 0; - } - - void * --- -2.21.0 - diff --git a/0010-net-hns3-fix-jumbo-frame-flag-condition-for-MTU-set.patch b/0010-net-hns3-fix-jumbo-frame-flag-condition-for-MTU-set.patch new file mode 100644 index 0000000..c2267da --- /dev/null +++ b/0010-net-hns3-fix-jumbo-frame-flag-condition-for-MTU-set.patch @@ -0,0 +1,53 @@ +From 2a7fd245e7d1c752bd53df6e0e7967b1dadfe876 Mon Sep 17 00:00:00 2001 +From: Steve Yang +Date: Mon, 18 Jan 2021 07:04:12 +0000 +Subject: [PATCH 010/189] net/hns3: fix jumbo frame flag condition for MTU set + +The jumbo frame uses the 'RTE_ETHER_MAX_LEN' as boundary condition, +but the Ether overhead is larger than 18 when it supports dual VLAN tags. +That will cause the jumbo flag rx offload is wrong when MTU size is +'RTE_ETHER_MTU'. + +This fix will change the boundary condition with 'HSN3_DEFAULT_FRAME_LEN', +that perhaps impacts the cases of the jumbo frame related. + +Fixes: 1f5ca0b460cd ("net/hns3: support some device operations") +Fixes: a5475d61fa34 ("net/hns3: support VF") +Cc: stable@dpdk.org + +Signed-off-by: Steve Yang +Acked-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 2 +- + drivers/net/hns3/hns3_ethdev_vf.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 90544fe..bf633a3 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2467,7 +2467,7 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + } + + rte_spinlock_lock(&hw->lock); +- is_jumbo_frame = frame_size > RTE_ETHER_MAX_LEN ? true : false; ++ is_jumbo_frame = frame_size > HNS3_DEFAULT_FRAME_LEN ? true : false; + frame_size = RTE_MAX(frame_size, HNS3_DEFAULT_FRAME_LEN); + + /* +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index f09cabc..ef03fb1 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -928,7 +928,7 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + rte_spinlock_unlock(&hw->lock); + return ret; + } +- if (frame_size > RTE_ETHER_MAX_LEN) ++ if (mtu > RTE_ETHER_MTU) + dev->data->dev_conf.rxmode.offloads |= + DEV_RX_OFFLOAD_JUMBO_FRAME; + else +-- +2.7.4 + diff --git a/0011-dpdk-fix-coredump-when-primary-process-attach-without-shared-file.patch b/0011-dpdk-fix-coredump-when-primary-process-attach-without-shared-file.patch deleted file mode 100644 index 8696044..0000000 --- a/0011-dpdk-fix-coredump-when-primary-process-attach-without-shared-file.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 561a37288d629398f976dfa4e57854b7ea484cc7 Mon Sep 17 00:00:00 2001 -From: yuanyunkang -Date: Sat, 22 Aug 2020 14:39:16 +0800 -Subject: [PATCH] dpdk:fix coredump when primary process attach without shared - file - -Signed-off-by: yuanyunkang ---- - lib/librte_eal/linux/eal/eal.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c -index a1f2b42..ff86ff9 100644 ---- a/lib/librte_eal/linux/eal/eal.c -+++ b/lib/librte_eal/linux/eal/eal.c -@@ -569,22 +569,28 @@ rte_config_init(void) - return 0; - } - --static void -+static int - rte_sec_config_init(const int sec_idx) - { - int mem_cfg_fd = -1; - int mmap_flags = PROT_READ | PROT_WRITE; -+ int ret = -1; - - struct rte_config *rte_cfg = rte_eal_sec_get_configuration(sec_idx); - struct internal_config *internal_cfg = rte_eal_sec_get_internal_config(sec_idx); - - rte_cfg->process_type = internal_cfg->process_type; - -- __rte_eal_config_attach(mmap_flags, &mem_cfg_fd, -+ ret = __rte_eal_config_attach(mmap_flags, &mem_cfg_fd, - rte_eal_sec_get_runtime_dir(sec_idx), - internal_cfg, rte_cfg); -+ if (ret < 0) { -+ RTE_LOG(ERR, EAL, "Cannot attach shared memory\n"); -+ return -1; -+ } - - close(mem_cfg_fd); -+ return 0; - } - - static int -@@ -1553,7 +1559,11 @@ rte_eal_sec_attach(int argc, char **argv) - return -1; - } - -- rte_sec_config_init(sec_idx); -+ ret = rte_sec_config_init(sec_idx); -+ if (ret < 0) { -+ RTE_LOG(ERR, EAL, "Cannot init sec config\n"); -+ return -1; -+ } - - ret = rte_eal_sec_memory_init(sec_idx); - if (ret < 0) { --- -2.19.1 - diff --git a/0011-net-hns3-use-C11-atomics-builtins-for-resetting.patch b/0011-net-hns3-use-C11-atomics-builtins-for-resetting.patch new file mode 100644 index 0000000..46ccc2d --- /dev/null +++ b/0011-net-hns3-use-C11-atomics-builtins-for-resetting.patch @@ -0,0 +1,209 @@ +From ec2a9e9b56f0bfd4d0926c9f59183d682de9670e Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Thu, 14 Jan 2021 21:33:30 +0800 +Subject: [PATCH 011/189] net/hns3: use C11 atomics builtins for resetting + +Use C11 atomic builtins with explicit ordering instead of +rte_atomic ops with the resetting member of hns3_reset_data +structure. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_dcb.c | 5 +++-- + drivers/net/hns3/hns3_ethdev.c | 8 ++++---- + drivers/net/hns3/hns3_ethdev.h | 2 +- + drivers/net/hns3/hns3_ethdev_vf.c | 12 ++++++------ + drivers/net/hns3/hns3_intr.c | 8 ++++---- + drivers/net/hns3/hns3_rxtx.c | 2 +- + 6 files changed, 19 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index fb50179..b32d5af 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -633,7 +633,7 @@ hns3_set_rss_size(struct hns3_hw *hw, uint16_t nb_rx_q) + * and configured directly to the hardware in the RESET_STAGE_RESTORE + * stage of the reset process. + */ +- if (rte_atomic16_read(&hw->reset.resetting) == 0) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { + for (i = 0; i < HNS3_RSS_IND_TBL_SIZE; i++) + rss_cfg->rss_indirection_tbl[i] = + i % hw->alloc_rss_size; +@@ -1562,7 +1562,8 @@ hns3_dcb_configure(struct hns3_adapter *hns) + int ret; + + hns3_dcb_cfg_validate(hns, &num_tc, &map_changed); +- if (map_changed || rte_atomic16_read(&hw->reset.resetting)) { ++ if (map_changed || ++ __atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { + ret = hns3_dcb_info_update(hns, num_tc); + if (ret) { + hns3_err(hw, "dcb info update failed: %d", ret); +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index bf633a3..d0d1d3a 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -1017,7 +1017,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns) + * ensure that the hardware configuration remains unchanged before and + * after reset. + */ +- if (rte_atomic16_read(&hw->reset.resetting) == 0) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { + hw->port_base_vlan_cfg.state = HNS3_PORT_BASE_VLAN_DISABLE; + hw->port_base_vlan_cfg.pvid = HNS3_INVALID_PVID; + } +@@ -1041,7 +1041,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns) + * we will restore configurations to hardware in hns3_restore_vlan_table + * and hns3_restore_vlan_conf later. + */ +- if (rte_atomic16_read(&hw->reset.resetting) == 0) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { + ret = hns3_vlan_pvid_configure(hns, HNS3_INVALID_PVID, 0); + if (ret) { + hns3_err(hw, "pvid set fail in pf, ret =%d", ret); +@@ -4872,7 +4872,7 @@ hns3_dev_start(struct rte_eth_dev *dev) + int ret; + + PMD_INIT_FUNC_TRACE(); +- if (rte_atomic16_read(&hw->reset.resetting)) ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) + return -EBUSY; + + rte_spinlock_lock(&hw->lock); +@@ -5018,7 +5018,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) + rte_delay_ms(hw->tqps_num); + + rte_spinlock_lock(&hw->lock); +- if (rte_atomic16_read(&hw->reset.resetting) == 0) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { + hns3_stop_tqps(hw); + hns3_do_stop(hns); + hns3_unmap_rx_interrupt(dev); +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 31f78a1..0d86683 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -350,7 +350,7 @@ struct hns3_reset_data { + enum hns3_reset_stage stage; + rte_atomic16_t schedule; + /* Reset flag, covering the entire reset process */ +- rte_atomic16_t resetting; ++ uint16_t resetting; + /* Used to disable sending cmds during reset */ + rte_atomic16_t disable_cmd; + /* The reset level being processed */ +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index ef03fb1..c126384 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -898,7 +898,7 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + * 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)) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { + hns3_err(hw, "Failed to set mtu during resetting"); + return -EIO; + } +@@ -1438,7 +1438,7 @@ hns3vf_request_link_info(struct hns3_hw *hw) + uint8_t resp_msg; + int ret; + +- if (rte_atomic16_read(&hw->reset.resetting)) ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) + return; + ret = hns3_send_mbx_msg(hw, HNS3_MBX_GET_LINK_STATUS, 0, NULL, 0, false, + &resp_msg, sizeof(resp_msg)); +@@ -1471,7 +1471,7 @@ hns3vf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) + struct hns3_hw *hw = &hns->hw; + int ret; + +- if (rte_atomic16_read(&hw->reset.resetting)) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { + hns3_err(hw, + "vf set vlan id failed during resetting, vlan_id =%u", + vlan_id); +@@ -1510,7 +1510,7 @@ hns3vf_vlan_offload_set(struct rte_eth_dev *dev, int mask) + unsigned int tmp_mask; + int ret = 0; + +- if (rte_atomic16_read(&hw->reset.resetting)) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { + hns3_err(hw, "vf set vlan offload failed during resetting, " + "mask = 0x%x", mask); + return -EIO; +@@ -1957,7 +1957,7 @@ hns3vf_dev_stop(struct rte_eth_dev *dev) + rte_delay_ms(hw->tqps_num); + + rte_spinlock_lock(&hw->lock); +- if (rte_atomic16_read(&hw->reset.resetting) == 0) { ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { + hns3_stop_tqps(hw); + hns3vf_do_stop(hns); + hns3vf_unmap_rx_interrupt(dev); +@@ -2188,7 +2188,7 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + int ret; + + PMD_INIT_FUNC_TRACE(); +- if (rte_atomic16_read(&hw->reset.resetting)) ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) + return -EBUSY; + + rte_spinlock_lock(&hw->lock); +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 99c500d..51f19b4 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -1761,7 +1761,7 @@ hns3_reset_init(struct hns3_hw *hw) + hw->reset.stage = RESET_STAGE_NONE; + hw->reset.request = 0; + hw->reset.pending = 0; +- rte_atomic16_init(&hw->reset.resetting); ++ hw->reset.resetting = 0; + rte_atomic16_init(&hw->reset.disable_cmd); + hw->reset.wait_data = rte_zmalloc("wait_data", + sizeof(struct hns3_wait_data), 0); +@@ -2011,7 +2011,7 @@ hns3_reset_pre(struct hns3_adapter *hns) + int ret; + + if (hw->reset.stage == RESET_STAGE_NONE) { +- rte_atomic16_set(&hns->hw.reset.resetting, 1); ++ __atomic_store_n(&hns->hw.reset.resetting, 1, __ATOMIC_RELAXED); + hw->reset.stage = RESET_STAGE_DOWN; + ret = hw->reset.ops->stop_service(hns); + gettimeofday(&tv, NULL); +@@ -2098,7 +2098,7 @@ hns3_reset_post(struct hns3_adapter *hns) + /* IMP will wait ready flag before reset */ + hns3_notify_reset_ready(hw, false); + hns3_clear_reset_level(hw, &hw->reset.pending); +- rte_atomic16_clear(&hns->hw.reset.resetting); ++ __atomic_store_n(&hns->hw.reset.resetting, 0, __ATOMIC_RELAXED); + hw->reset.attempts = 0; + hw->reset.stats.success_cnt++; + hw->reset.stage = RESET_STAGE_NONE; +@@ -2223,7 +2223,7 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) + hw->reset.mbuf_deferred_free = false; + } + rte_spinlock_unlock(&hw->lock); +- rte_atomic16_clear(&hns->hw.reset.resetting); ++ __atomic_store_n(&hns->hw.reset.resetting, 0, __ATOMIC_RELAXED); + hw->reset.stage = RESET_STAGE_NONE; + gettimeofday(&tv, NULL); + timersub(&tv, &hw->reset.start_time, &tv_delta); +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 5ac36b3..0badfc9 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -3744,7 +3744,7 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + eth_tx_prep_t prep = NULL; + + if (hns->hw.adapter_state == HNS3_NIC_STARTED && +- rte_atomic16_read(&hns->hw.reset.resetting) == 0) { ++ __atomic_load_n(&hns->hw.reset.resetting, __ATOMIC_RELAXED) == 0) { + eth_dev->rx_pkt_burst = hns3_get_rx_function(eth_dev); + eth_dev->tx_pkt_burst = hns3_get_tx_function(eth_dev, &prep); + eth_dev->tx_pkt_prepare = prep; +-- +2.7.4 + diff --git a/0012-dpdk-fix-fbarray-memseg-destory-error-during-detach.patch b/0012-dpdk-fix-fbarray-memseg-destory-error-during-detach.patch deleted file mode 100644 index 27642e5..0000000 --- a/0012-dpdk-fix-fbarray-memseg-destory-error-during-detach.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e5cc58807c8d03554f2c3f0eee3b0b6d6f44278f Mon Sep 17 00:00:00 2001 -From: HuangLiming -Date: Sat, 22 Aug 2020 05:32:47 -0400 -Subject: [PATCH] fix fbarray memseg destory error during detach without shared - file - -Signed-off-by: HuangLiming ---- - lib/librte_eal/common/eal_common_fbarray.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/librte_eal/common/eal_common_fbarray.c b/lib/librte_eal/common/eal_common_fbarray.c -index 116c695..d1aa074 100644 ---- a/lib/librte_eal/common/eal_common_fbarray.c -+++ b/lib/librte_eal/common/eal_common_fbarray.c -@@ -1127,9 +1127,9 @@ rte_sec_fbarray_destroy(struct rte_fbarray *arr, - - fd = open(path, O_RDONLY); - if (fd < 0) { -- RTE_LOG(ERR, EAL, "Could not open fbarray file: %s\n", -- strerror(errno)); -- return -1; -+ RTE_LOG(WARNING, EAL, "Could not open %s: %s, and just skip it\n", -+ path, strerror(errno)); -+ return 0; - } - if (flock(fd, LOCK_EX | LOCK_NB)) { - RTE_LOG(DEBUG, EAL, "Cannot destroy fbarray - another process is using it\n"); --- -2.21.0 - diff --git a/0012-net-hns3-support-traffic-management.patch b/0012-net-hns3-support-traffic-management.patch new file mode 100644 index 0000000..fcd8486 --- /dev/null +++ b/0012-net-hns3-support-traffic-management.patch @@ -0,0 +1,1885 @@ +From f0523548580b29532793025e08a1b5bee8f682ff Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 14 Jan 2021 21:33:31 +0800 +Subject: [PATCH 012/189] net/hns3: support traffic management + +This patch support RTE TM ops function for PF, which could +used to: +1. config port's peak rate. +2. config TC's peak rate. + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_dcb.c | 216 ++++--- + drivers/net/hns3/hns3_dcb.h | 3 + + drivers/net/hns3/hns3_ethdev.c | 20 +- + drivers/net/hns3/hns3_ethdev.h | 14 + + drivers/net/hns3/hns3_tm.c | 1291 ++++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_tm.h | 103 ++++ + drivers/net/hns3/meson.build | 3 +- + 7 files changed, 1554 insertions(+), 96 deletions(-) + create mode 100644 drivers/net/hns3/hns3_tm.c + create mode 100644 drivers/net/hns3/hns3_tm.h + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index b32d5af..5aa374c 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -76,16 +76,13 @@ hns3_shaper_para_calc(struct hns3_hw *hw, uint32_t ir, uint8_t shaper_level, + shaper_para->ir_b = SHAPER_DEFAULT_IR_B; + } else if (ir_calc > ir) { + /* Increasing the denominator to select ir_s value */ +- do { ++ while (ir_calc >= ir && ir) { + ir_s_calc++; + ir_calc = DIVISOR_IR_B_126 / (tick * (1 << ir_s_calc)); +- } while (ir_calc > ir); ++ } + +- if (ir_calc == ir) +- shaper_para->ir_b = SHAPER_DEFAULT_IR_B; +- else +- shaper_para->ir_b = (ir * tick * (1 << ir_s_calc) + +- (DIVISOR_CLK >> 1)) / DIVISOR_CLK; ++ shaper_para->ir_b = (ir * tick * (1 << ir_s_calc) + ++ (DIVISOR_CLK >> 1)) / DIVISOR_CLK; + } else { + /* + * Increasing the numerator to select ir_u value. ir_u_calc will +@@ -320,6 +317,10 @@ hns3_dcb_get_shapping_para(uint8_t ir_b, uint8_t ir_u, uint8_t ir_s, + { + uint32_t shapping_para = 0; + ++ /* If ir_b is zero it means IR is 0Mbps, return zero of shapping_para */ ++ if (ir_b == 0) ++ return shapping_para; ++ + hns3_dcb_set_field(shapping_para, IR_B, ir_b); + hns3_dcb_set_field(shapping_para, IR_U, ir_u); + hns3_dcb_set_field(shapping_para, IR_S, ir_s); +@@ -402,14 +403,57 @@ hns3_dcb_pg_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, + return hns3_cmd_send(hw, &desc, 1); + } + +-static int +-hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) ++int ++hns3_pg_shaper_rate_cfg(struct hns3_hw *hw, uint8_t pg_id, uint32_t rate) + { +- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_shaper_parameter shaper_parameter; +- struct hns3_pf *pf = &hns->pf; + uint32_t ir_u, ir_b, ir_s; + uint32_t shaper_para; ++ int ret; ++ ++ /* Calc shaper para */ ++ ret = hns3_shaper_para_calc(hw, rate, HNS3_SHAPER_LVL_PG, ++ &shaper_parameter); ++ if (ret) { ++ hns3_err(hw, "calculate shaper parameter fail, ret = %d.", ++ ret); ++ return ret; ++ } ++ ++ shaper_para = hns3_dcb_get_shapping_para(0, 0, 0, ++ HNS3_SHAPER_BS_U_DEF, ++ HNS3_SHAPER_BS_S_DEF); ++ ++ ret = hns3_dcb_pg_shapping_cfg(hw, HNS3_DCB_SHAP_C_BUCKET, pg_id, ++ shaper_para, rate); ++ if (ret) { ++ hns3_err(hw, "config PG CIR shaper parameter fail, ret = %d.", ++ ret); ++ return ret; ++ } ++ ++ ir_b = shaper_parameter.ir_b; ++ ir_u = shaper_parameter.ir_u; ++ ir_s = shaper_parameter.ir_s; ++ shaper_para = hns3_dcb_get_shapping_para(ir_b, ir_u, ir_s, ++ HNS3_SHAPER_BS_U_DEF, ++ HNS3_SHAPER_BS_S_DEF); ++ ++ ret = hns3_dcb_pg_shapping_cfg(hw, HNS3_DCB_SHAP_P_BUCKET, pg_id, ++ shaper_para, rate); ++ if (ret) { ++ hns3_err(hw, "config PG PIR shaper parameter fail, ret = %d.", ++ ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); + uint32_t rate; + uint8_t i; + int ret; +@@ -421,44 +465,9 @@ hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) + /* Pg to pri */ + for (i = 0; i < hw->dcb_info.num_pg; i++) { + rate = hw->dcb_info.pg_info[i].bw_limit; +- +- /* Calc shaper para */ +- ret = hns3_shaper_para_calc(hw, rate, HNS3_SHAPER_LVL_PG, +- &shaper_parameter); +- if (ret) { +- hns3_err(hw, "calculate shaper parameter failed: %d", +- ret); +- return ret; +- } +- +- shaper_para = hns3_dcb_get_shapping_para(0, 0, 0, +- HNS3_SHAPER_BS_U_DEF, +- HNS3_SHAPER_BS_S_DEF); +- +- ret = hns3_dcb_pg_shapping_cfg(hw, HNS3_DCB_SHAP_C_BUCKET, i, +- shaper_para, rate); +- if (ret) { +- hns3_err(hw, +- "config PG CIR shaper parameter failed: %d", +- ret); +- return ret; +- } +- +- ir_b = shaper_parameter.ir_b; +- ir_u = shaper_parameter.ir_u; +- ir_s = shaper_parameter.ir_s; +- shaper_para = hns3_dcb_get_shapping_para(ir_b, ir_u, ir_s, +- HNS3_SHAPER_BS_U_DEF, +- HNS3_SHAPER_BS_S_DEF); +- +- ret = hns3_dcb_pg_shapping_cfg(hw, HNS3_DCB_SHAP_P_BUCKET, i, +- shaper_para, rate); +- if (ret) { +- hns3_err(hw, +- "config PG PIR shaper parameter failed: %d", +- ret); ++ ret = hns3_pg_shaper_rate_cfg(hw, i, rate); ++ if (ret) + return ret; +- } + } + + return 0; +@@ -530,74 +539,75 @@ hns3_dcb_pri_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, + return hns3_cmd_send(hw, &desc, 1); + } + +-static int +-hns3_dcb_pri_tc_base_shaper_cfg(struct hns3_hw *hw) ++int ++hns3_pri_shaper_rate_cfg(struct hns3_hw *hw, uint8_t tc_no, uint32_t rate) + { + struct hns3_shaper_parameter shaper_parameter; + uint32_t ir_u, ir_b, ir_s; + uint32_t shaper_para; +- uint32_t rate; +- int ret, i; ++ int ret; + +- for (i = 0; i < hw->dcb_info.num_tc; i++) { +- rate = hw->dcb_info.tc_info[i].bw_limit; +- ret = hns3_shaper_para_calc(hw, rate, HNS3_SHAPER_LVL_PRI, +- &shaper_parameter); +- if (ret) { +- hns3_err(hw, "calculate shaper parameter failed: %d", +- ret); +- return ret; +- } ++ ret = hns3_shaper_para_calc(hw, rate, HNS3_SHAPER_LVL_PRI, ++ &shaper_parameter); ++ if (ret) { ++ hns3_err(hw, "calculate shaper parameter failed: %d.", ++ ret); ++ return ret; ++ } + +- shaper_para = hns3_dcb_get_shapping_para(0, 0, 0, +- HNS3_SHAPER_BS_U_DEF, +- HNS3_SHAPER_BS_S_DEF); ++ shaper_para = hns3_dcb_get_shapping_para(0, 0, 0, ++ HNS3_SHAPER_BS_U_DEF, ++ HNS3_SHAPER_BS_S_DEF); + +- ret = hns3_dcb_pri_shapping_cfg(hw, HNS3_DCB_SHAP_C_BUCKET, i, +- shaper_para, rate); +- if (ret) { +- hns3_err(hw, +- "config priority CIR shaper parameter failed: %d", +- ret); +- return ret; +- } ++ ret = hns3_dcb_pri_shapping_cfg(hw, HNS3_DCB_SHAP_C_BUCKET, tc_no, ++ shaper_para, rate); ++ if (ret) { ++ hns3_err(hw, ++ "config priority CIR shaper parameter failed: %d.", ++ ret); ++ return ret; ++ } + +- ir_b = shaper_parameter.ir_b; +- ir_u = shaper_parameter.ir_u; +- ir_s = shaper_parameter.ir_s; +- shaper_para = hns3_dcb_get_shapping_para(ir_b, ir_u, ir_s, +- HNS3_SHAPER_BS_U_DEF, +- HNS3_SHAPER_BS_S_DEF); ++ ir_b = shaper_parameter.ir_b; ++ ir_u = shaper_parameter.ir_u; ++ ir_s = shaper_parameter.ir_s; ++ shaper_para = hns3_dcb_get_shapping_para(ir_b, ir_u, ir_s, ++ HNS3_SHAPER_BS_U_DEF, ++ HNS3_SHAPER_BS_S_DEF); + +- ret = hns3_dcb_pri_shapping_cfg(hw, HNS3_DCB_SHAP_P_BUCKET, i, +- shaper_para, rate); +- if (ret) { +- hns3_err(hw, +- "config priority PIR shaper parameter failed: %d", +- ret); +- return ret; +- } ++ ret = hns3_dcb_pri_shapping_cfg(hw, HNS3_DCB_SHAP_P_BUCKET, tc_no, ++ shaper_para, rate); ++ if (ret) { ++ hns3_err(hw, ++ "config priority PIR shaper parameter failed: %d.", ++ ret); ++ return ret; + } + + return 0; + } + +- + static int + hns3_dcb_pri_shaper_cfg(struct hns3_hw *hw) + { +- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +- struct hns3_pf *pf = &hns->pf; ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ uint32_t rate; ++ uint8_t i; + int ret; + + if (pf->tx_sch_mode != HNS3_FLAG_TC_BASE_SCH_MODE) + return -EINVAL; + +- ret = hns3_dcb_pri_tc_base_shaper_cfg(hw); +- if (ret) +- hns3_err(hw, "config port shaper failed: %d", ret); ++ for (i = 0; i < hw->dcb_info.num_tc; i++) { ++ rate = hw->dcb_info.tc_info[i].bw_limit; ++ ret = hns3_pri_shaper_rate_cfg(hw, i, rate); ++ if (ret) { ++ hns3_err(hw, "config pri shaper failed: %d.", ret); ++ return ret; ++ } ++ } + +- return ret; ++ return 0; + } + + static int +@@ -680,6 +690,26 @@ hns3_tc_queue_mapping_cfg(struct hns3_hw *hw, uint16_t nb_tx_q) + return 0; + } + ++uint8_t ++hns3_txq_mapped_tc_get(struct hns3_hw *hw, uint16_t txq_no) ++{ ++ struct hns3_tc_queue_info *tc_queue; ++ uint8_t i; ++ ++ for (i = 0; i < HNS3_MAX_TC_NUM; i++) { ++ tc_queue = &hw->tc_queue[i]; ++ if (!tc_queue->enable) ++ continue; ++ ++ if (txq_no >= tc_queue->tqp_offset && ++ txq_no < tc_queue->tqp_offset + tc_queue->tqp_count) ++ return i; ++ } ++ ++ /* return TC0 in default case */ ++ return 0; ++} ++ + int + hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, uint16_t nb_tx_q) + { +diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h +index fee23d9..8248434 100644 +--- a/drivers/net/hns3/hns3_dcb.h ++++ b/drivers/net/hns3/hns3_dcb.h +@@ -209,5 +209,8 @@ int hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, + + int hns3_dcb_cfg_update(struct hns3_adapter *hns); + int hns3_dcb_port_shaper_cfg(struct hns3_hw *hw); ++int hns3_pg_shaper_rate_cfg(struct hns3_hw *hw, uint8_t pg_id, uint32_t rate); ++int hns3_pri_shaper_rate_cfg(struct hns3_hw *hw, uint8_t tc_no, uint32_t rate); ++uint8_t hns3_txq_mapped_tc_get(struct hns3_hw *hw, uint16_t txq_no); + + #endif /* _HNS3_DCB_H_ */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index d0d1d3a..2bc28ef 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5,7 +5,6 @@ + #include + #include + #include +-#include + #include + + #include "hns3_ethdev.h" +@@ -2494,7 +2493,7 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + return 0; + } + +-static int ++int + hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + { + struct hns3_adapter *hns = eth_dev->data->dev_private; +@@ -4679,6 +4678,8 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + goto err_enable_intr; + } + ++ hns3_tm_conf_init(eth_dev); ++ + return 0; + + err_enable_intr: +@@ -4712,6 +4713,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) + + PMD_INIT_FUNC_TRACE(); + ++ hns3_tm_conf_uninit(eth_dev); + hns3_enable_hw_error_intr(hns, false); + hns3_rss_uninit(hns); + (void)hns3_config_gro(hw, false); +@@ -4739,6 +4741,16 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + if (ret) + return ret; + ++ /* ++ * The hns3_dcb_cfg_update may configure TM module, so ++ * hns3_tm_conf_update must called later. ++ */ ++ ret = hns3_tm_conf_update(hw); ++ if (ret) { ++ PMD_INIT_LOG(ERR, "failed to update tm conf, ret = %d.", ret); ++ return ret; ++ } ++ + ret = hns3_init_queues(hns, reset_queue); + if (ret) { + PMD_INIT_LOG(ERR, "failed to init queues, ret = %d.", ret); +@@ -4936,6 +4948,8 @@ hns3_dev_start(struct rte_eth_dev *dev) + */ + hns3_start_tqps(hw); + ++ hns3_tm_dev_start_proc(hw); ++ + hns3_info(hw, "hns3 dev start successful!"); + return 0; + } +@@ -5019,6 +5033,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) + + rte_spinlock_lock(&hw->lock); + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { ++ hns3_tm_dev_stop_proc(hw); + hns3_stop_tqps(hw); + hns3_do_stop(hns); + hns3_unmap_rx_interrupt(dev); +@@ -6089,6 +6104,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { + .fec_get_capability = hns3_fec_get_capability, + .fec_get = hns3_fec_get, + .fec_set = hns3_fec_set, ++ .tm_ops_get = hns3_tm_ops_get, + }; + + static const struct hns3_reset_ops hns3_reset_ops = { +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 0d86683..0d17170 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -7,12 +7,16 @@ + + #include + #include ++#include ++#include ++#include + + #include "hns3_cmd.h" + #include "hns3_mbx.h" + #include "hns3_rss.h" + #include "hns3_fdir.h" + #include "hns3_stats.h" ++#include "hns3_tm.h" + + /* Vendor ID */ + #define PCI_VENDOR_ID_HUAWEI 0x19e5 +@@ -727,6 +731,8 @@ struct hns3_pf { + + struct hns3_fdir_info fdir; /* flow director info */ + LIST_HEAD(counters, hns3_flow_counter) flow_counters; ++ ++ struct hns3_tm_conf tm_conf; + }; + + struct hns3_vf { +@@ -796,6 +802,12 @@ struct hns3_adapter { + #define HNS3_DEV_HW_TO_ADAPTER(hw) \ + container_of(hw, struct hns3_adapter, hw) + ++static inline struct hns3_pf *HNS3_DEV_HW_TO_PF(struct hns3_hw *hw) ++{ ++ struct hns3_adapter *adapter = HNS3_DEV_HW_TO_ADAPTER(hw); ++ return &adapter->pf; ++} ++ + #define hns3_set_field(origin, mask, shift, val) \ + do { \ + (origin) &= (~(mask)); \ +@@ -937,6 +949,8 @@ bool hns3vf_is_reset_pending(struct hns3_adapter *hns); + void hns3_update_link_status(struct hns3_hw *hw); + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr); ++int hns3_dev_infos_get(struct rte_eth_dev *eth_dev, ++ struct rte_eth_dev_info *info); + + static inline bool + is_reset_pending(struct hns3_adapter *hns) +diff --git a/drivers/net/hns3/hns3_tm.c b/drivers/net/hns3/hns3_tm.c +new file mode 100644 +index 0000000..d1639d4 +--- /dev/null ++++ b/drivers/net/hns3/hns3_tm.c +@@ -0,0 +1,1291 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2020-2020 Hisilicon Limited. ++ */ ++ ++#include ++ ++#include "hns3_ethdev.h" ++#include "hns3_dcb.h" ++#include "hns3_logs.h" ++#include "hns3_tm.h" ++ ++static inline uint32_t ++hns3_tm_max_tx_queues_get(struct rte_eth_dev *dev) ++{ ++ /* ++ * This API will called in pci device probe stage, we can't call ++ * rte_eth_dev_info_get to get max_tx_queues (due to rte_eth_devices ++ * not setup), so we call the hns3_dev_infos_get. ++ */ ++ struct rte_eth_dev_info dev_info; ++ ++ memset(&dev_info, 0, sizeof(dev_info)); ++ (void)hns3_dev_infos_get(dev, &dev_info); ++ return RTE_MIN(dev_info.max_tx_queues, RTE_MAX_QUEUES_PER_PORT); ++} ++ ++void ++hns3_tm_conf_init(struct rte_eth_dev *dev) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ uint32_t max_tx_queues = hns3_tm_max_tx_queues_get(dev); ++ ++ pf->tm_conf.nb_leaf_nodes_max = max_tx_queues; ++ pf->tm_conf.nb_nodes_max = 1 + HNS3_MAX_TC_NUM + max_tx_queues; ++ pf->tm_conf.nb_shaper_profile_max = 1 + HNS3_MAX_TC_NUM; ++ ++ TAILQ_INIT(&pf->tm_conf.shaper_profile_list); ++ pf->tm_conf.nb_shaper_profile = 0; ++ ++ pf->tm_conf.root = NULL; ++ TAILQ_INIT(&pf->tm_conf.tc_list); ++ TAILQ_INIT(&pf->tm_conf.queue_list); ++ pf->tm_conf.nb_tc_node = 0; ++ pf->tm_conf.nb_queue_node = 0; ++ ++ pf->tm_conf.committed = false; ++} ++ ++void ++hns3_tm_conf_uninit(struct rte_eth_dev *dev) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_shaper_profile *shaper_profile; ++ struct hns3_tm_node *tm_node; ++ ++ if (pf->tm_conf.nb_queue_node > 0) { ++ while ((tm_node = TAILQ_FIRST(&pf->tm_conf.queue_list))) { ++ TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node); ++ rte_free(tm_node); ++ } ++ pf->tm_conf.nb_queue_node = 0; ++ } ++ ++ if (pf->tm_conf.nb_tc_node > 0) { ++ while ((tm_node = TAILQ_FIRST(&pf->tm_conf.tc_list))) { ++ TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node); ++ rte_free(tm_node); ++ } ++ pf->tm_conf.nb_tc_node = 0; ++ } ++ ++ if (pf->tm_conf.root != NULL) { ++ rte_free(pf->tm_conf.root); ++ pf->tm_conf.root = NULL; ++ } ++ ++ if (pf->tm_conf.nb_shaper_profile > 0) { ++ while ((shaper_profile = ++ TAILQ_FIRST(&pf->tm_conf.shaper_profile_list))) { ++ TAILQ_REMOVE(&pf->tm_conf.shaper_profile_list, ++ shaper_profile, node); ++ rte_free(shaper_profile); ++ } ++ pf->tm_conf.nb_shaper_profile = 0; ++ } ++ ++ pf->tm_conf.nb_leaf_nodes_max = 0; ++ pf->tm_conf.nb_nodes_max = 0; ++ pf->tm_conf.nb_shaper_profile_max = 0; ++} ++ ++static inline uint64_t ++hns3_tm_rate_convert_firmware2tm(uint32_t firmware_rate) ++{ ++#define FIRMWARE_TO_TM_RATE_SCALE 125000 ++ /* tm rate unit is Bps, firmware rate is Mbps */ ++ return ((uint64_t)firmware_rate) * FIRMWARE_TO_TM_RATE_SCALE; ++} ++ ++static inline uint32_t ++hns3_tm_rate_convert_tm2firmware(uint64_t tm_rate) ++{ ++#define TM_TO_FIRMWARE_RATE_SCALE 125000 ++ /* tm rate unit is Bps, firmware rate is Mbps */ ++ return (uint32_t)(tm_rate / TM_TO_FIRMWARE_RATE_SCALE); ++} ++ ++static int ++hns3_tm_capabilities_get(struct rte_eth_dev *dev, ++ struct rte_tm_capabilities *cap, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ uint32_t max_tx_queues = hns3_tm_max_tx_queues_get(dev); ++ ++ if (cap == NULL || error == NULL) ++ return -EINVAL; ++ ++ error->type = RTE_TM_ERROR_TYPE_NONE; ++ ++ memset(cap, 0, sizeof(struct rte_tm_capabilities)); ++ ++ cap->n_nodes_max = 1 + HNS3_MAX_TC_NUM + max_tx_queues; ++ cap->n_levels_max = HNS3_TM_NODE_LEVEL_MAX; ++ cap->non_leaf_nodes_identical = 1; ++ cap->leaf_nodes_identical = 1; ++ cap->shaper_n_max = 1 + HNS3_MAX_TC_NUM; ++ cap->shaper_private_n_max = 1 + HNS3_MAX_TC_NUM; ++ cap->shaper_private_dual_rate_n_max = 0; ++ cap->shaper_private_rate_min = 0; ++ cap->shaper_private_rate_max = ++ hns3_tm_rate_convert_firmware2tm(hw->max_tm_rate); ++ cap->shaper_shared_n_max = 0; ++ cap->shaper_shared_n_nodes_per_shaper_max = 0; ++ cap->shaper_shared_n_shapers_per_node_max = 0; ++ cap->shaper_shared_dual_rate_n_max = 0; ++ cap->shaper_shared_rate_min = 0; ++ cap->shaper_shared_rate_max = 0; ++ ++ cap->sched_n_children_max = max_tx_queues; ++ cap->sched_sp_n_priorities_max = 1; ++ cap->sched_wfq_n_children_per_group_max = 0; ++ cap->sched_wfq_n_groups_max = 0; ++ cap->sched_wfq_weight_max = 1; ++ ++ cap->cman_head_drop_supported = 0; ++ cap->dynamic_update_mask = 0; ++ cap->shaper_pkt_length_adjust_min = RTE_TM_ETH_FRAMING_OVERHEAD; ++ cap->shaper_pkt_length_adjust_max = RTE_TM_ETH_FRAMING_OVERHEAD_FCS; ++ cap->cman_wred_context_n_max = 0; ++ cap->cman_wred_context_private_n_max = 0; ++ cap->cman_wred_context_shared_n_max = 0; ++ cap->cman_wred_context_shared_n_nodes_per_context_max = 0; ++ cap->cman_wred_context_shared_n_contexts_per_node_max = 0; ++ cap->stats_mask = 0; ++ ++ return 0; ++} ++ ++static struct hns3_tm_shaper_profile * ++hns3_tm_shaper_profile_search(struct rte_eth_dev *dev, ++ uint32_t shaper_profile_id) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_shaper_profile_list *shaper_profile_list = ++ &pf->tm_conf.shaper_profile_list; ++ struct hns3_tm_shaper_profile *shaper_profile; ++ ++ TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) { ++ if (shaper_profile_id == shaper_profile->shaper_profile_id) ++ return shaper_profile; ++ } ++ ++ return NULL; ++} ++ ++static int ++hns3_tm_shaper_profile_param_check(struct rte_eth_dev *dev, ++ struct rte_tm_shaper_params *profile, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ ++ if (profile->committed.rate) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_RATE; ++ error->message = "committed rate not supported"; ++ return -EINVAL; ++ } ++ ++ if (profile->committed.size) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_COMMITTED_SIZE; ++ error->message = "committed bucket size not supported"; ++ return -EINVAL; ++ } ++ ++ if (profile->peak.rate > ++ hns3_tm_rate_convert_firmware2tm(hw->max_tm_rate)) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE; ++ error->message = "peak rate too large"; ++ return -EINVAL; ++ } ++ ++ if (profile->peak.size) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE; ++ error->message = "peak bucket size not supported"; ++ return -EINVAL; ++ } ++ ++ if (profile->pkt_length_adjust) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PKT_ADJUST_LEN; ++ error->message = "packet length adjustment not supported"; ++ return -EINVAL; ++ } ++ ++ if (profile->packet_mode) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE; ++ error->message = "packet mode not supported"; ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_tm_shaper_profile_add(struct rte_eth_dev *dev, ++ uint32_t shaper_profile_id, ++ struct rte_tm_shaper_params *profile, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_shaper_profile *shaper_profile; ++ int ret; ++ ++ if (profile == NULL || error == NULL) ++ return -EINVAL; ++ ++ if (pf->tm_conf.nb_shaper_profile >= ++ pf->tm_conf.nb_shaper_profile_max) { ++ error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED; ++ error->message = "too much profiles"; ++ return -EINVAL; ++ } ++ ++ ret = hns3_tm_shaper_profile_param_check(dev, profile, error); ++ if (ret) ++ return ret; ++ ++ shaper_profile = hns3_tm_shaper_profile_search(dev, shaper_profile_id); ++ if (shaper_profile) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID; ++ error->message = "profile ID exist"; ++ return -EINVAL; ++ } ++ ++ shaper_profile = rte_zmalloc("hns3_tm_shaper_profile", ++ sizeof(struct hns3_tm_shaper_profile), ++ 0); ++ if (shaper_profile == NULL) ++ return -ENOMEM; ++ ++ shaper_profile->shaper_profile_id = shaper_profile_id; ++ memcpy(&shaper_profile->profile, profile, ++ sizeof(struct rte_tm_shaper_params)); ++ TAILQ_INSERT_TAIL(&pf->tm_conf.shaper_profile_list, ++ shaper_profile, node); ++ pf->tm_conf.nb_shaper_profile++; ++ ++ return 0; ++} ++ ++static int ++hns3_tm_shaper_profile_del(struct rte_eth_dev *dev, ++ uint32_t shaper_profile_id, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_shaper_profile *shaper_profile; ++ ++ if (error == NULL) ++ return -EINVAL; ++ ++ shaper_profile = hns3_tm_shaper_profile_search(dev, shaper_profile_id); ++ if (shaper_profile == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID; ++ error->message = "profile ID not exist"; ++ return -EINVAL; ++ } ++ ++ if (shaper_profile->reference_count) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE; ++ error->message = "profile in use"; ++ return -EINVAL; ++ } ++ ++ TAILQ_REMOVE(&pf->tm_conf.shaper_profile_list, shaper_profile, node); ++ rte_free(shaper_profile); ++ pf->tm_conf.nb_shaper_profile--; ++ ++ return 0; ++} ++ ++static struct hns3_tm_node * ++hns3_tm_node_search(struct rte_eth_dev *dev, ++ uint32_t node_id, ++ enum hns3_tm_node_type *node_type) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_node_list *queue_list = &pf->tm_conf.queue_list; ++ struct hns3_tm_node_list *tc_list = &pf->tm_conf.tc_list; ++ struct hns3_tm_node *tm_node; ++ ++ if (pf->tm_conf.root && pf->tm_conf.root->id == node_id) { ++ *node_type = HNS3_TM_NODE_TYPE_PORT; ++ return pf->tm_conf.root; ++ } ++ ++ TAILQ_FOREACH(tm_node, tc_list, node) { ++ if (tm_node->id == node_id) { ++ *node_type = HNS3_TM_NODE_TYPE_TC; ++ return tm_node; ++ } ++ } ++ ++ TAILQ_FOREACH(tm_node, queue_list, node) { ++ if (tm_node->id == node_id) { ++ *node_type = HNS3_TM_NODE_TYPE_QUEUE; ++ return tm_node; ++ } ++ } ++ ++ return NULL; ++} ++ ++static int ++hns3_tm_nonleaf_node_param_check(struct rte_eth_dev *dev, ++ struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++{ ++ struct hns3_tm_shaper_profile *shaper_profile; ++ ++ if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) { ++ shaper_profile = hns3_tm_shaper_profile_search(dev, ++ params->shaper_profile_id); ++ if (shaper_profile == NULL) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID; ++ error->message = "shaper profile not exist"; ++ return -EINVAL; ++ } ++ } ++ ++ if (params->nonleaf.wfq_weight_mode) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_WFQ_WEIGHT_MODE; ++ error->message = "WFQ not supported"; ++ return -EINVAL; ++ } ++ ++ if (params->nonleaf.n_sp_priorities != 1) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SP_PRIORITIES; ++ error->message = "SP priority not supported"; ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_tm_leaf_node_param_check(struct rte_eth_dev *dev __rte_unused, ++ struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++ ++{ ++ if (params->shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_SHAPER_PROFILE_ID; ++ error->message = "shaper not supported"; ++ return -EINVAL; ++ } ++ ++ if (params->leaf.cman) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN; ++ error->message = "congestion management not supported"; ++ return -EINVAL; ++ } ++ ++ if (params->leaf.wred.wred_profile_id != RTE_TM_WRED_PROFILE_ID_NONE) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_WRED_PROFILE_ID; ++ error->message = "WRED not supported"; ++ return -EINVAL; ++ } ++ ++ if (params->leaf.wred.shared_wred_context_id) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_WRED_CONTEXT_ID; ++ error->message = "WRED not supported"; ++ return -EINVAL; ++ } ++ ++ if (params->leaf.wred.n_shared_wred_contexts) { ++ error->type = ++ RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_WRED_CONTEXTS; ++ error->message = "WRED not supported"; ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_tm_node_param_check(struct rte_eth_dev *dev, uint32_t node_id, ++ uint32_t priority, uint32_t weight, ++ struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ enum hns3_tm_node_type node_type = HNS3_TM_NODE_TYPE_MAX; ++ ++ if (node_id == RTE_TM_NODE_ID_NULL) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "invalid node id"; ++ return -EINVAL; ++ } ++ ++ if (hns3_tm_node_search(dev, node_id, &node_type)) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "node id already used"; ++ return -EINVAL; ++ } ++ ++ if (priority) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PRIORITY; ++ error->message = "priority should be 0"; ++ return -EINVAL; ++ } ++ ++ if (weight != 1) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_WEIGHT; ++ error->message = "weight must be 1"; ++ return -EINVAL; ++ } ++ ++ if (params->shared_shaper_id) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_SHARED_SHAPER_ID; ++ error->message = "shared shaper not supported"; ++ return -EINVAL; ++ } ++ if (params->n_shared_shapers) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_N_SHARED_SHAPERS; ++ error->message = "shared shaper not supported"; ++ return -EINVAL; ++ } ++ ++ if (node_id >= pf->tm_conf.nb_leaf_nodes_max) ++ return hns3_tm_nonleaf_node_param_check(dev, params, error); ++ else ++ return hns3_tm_leaf_node_param_check(dev, params, error); ++} ++ ++static int ++hns3_tm_port_node_add(struct rte_eth_dev *dev, uint32_t node_id, ++ uint32_t level_id, struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_node *tm_node; ++ ++ if (level_id != RTE_TM_NODE_LEVEL_ID_ANY && ++ level_id != HNS3_TM_NODE_LEVEL_PORT) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS; ++ error->message = "wrong level"; ++ return -EINVAL; ++ } ++ ++ if (node_id != pf->tm_conf.nb_nodes_max - 1) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "invalid port node ID"; ++ return -EINVAL; ++ } ++ ++ if (pf->tm_conf.root) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; ++ error->message = "already have a root"; ++ return -EINVAL; ++ } ++ ++ tm_node = rte_zmalloc("hns3_tm_node", sizeof(struct hns3_tm_node), 0); ++ if (tm_node == NULL) ++ return -ENOMEM; ++ ++ tm_node->id = node_id; ++ tm_node->reference_count = 0; ++ tm_node->parent = NULL; ++ tm_node->shaper_profile = hns3_tm_shaper_profile_search(dev, ++ params->shaper_profile_id); ++ memcpy(&tm_node->params, params, sizeof(struct rte_tm_node_params)); ++ pf->tm_conf.root = tm_node; ++ ++ if (tm_node->shaper_profile) ++ tm_node->shaper_profile->reference_count++; ++ ++ return 0; ++} ++ ++static int ++hns3_tm_tc_node_add(struct rte_eth_dev *dev, uint32_t node_id, ++ uint32_t level_id, struct hns3_tm_node *parent_node, ++ struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_node *tm_node; ++ ++ if (level_id != RTE_TM_NODE_LEVEL_ID_ANY && ++ level_id != HNS3_TM_NODE_LEVEL_TC) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS; ++ error->message = "wrong level"; ++ return -EINVAL; ++ } ++ ++ if (node_id >= pf->tm_conf.nb_nodes_max - 1 || ++ node_id < pf->tm_conf.nb_leaf_nodes_max || ++ hns3_tm_calc_node_tc_no(&pf->tm_conf, node_id) >= hw->num_tc) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "invalid tc node ID"; ++ return -EINVAL; ++ } ++ ++ if (pf->tm_conf.nb_tc_node >= hw->num_tc) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "too many TCs"; ++ return -EINVAL; ++ } ++ ++ tm_node = rte_zmalloc("hns3_tm_node", sizeof(struct hns3_tm_node), 0); ++ if (tm_node == NULL) ++ return -ENOMEM; ++ ++ tm_node->id = node_id; ++ tm_node->reference_count = 0; ++ tm_node->parent = parent_node; ++ tm_node->shaper_profile = hns3_tm_shaper_profile_search(dev, ++ params->shaper_profile_id); ++ memcpy(&tm_node->params, params, sizeof(struct rte_tm_node_params)); ++ TAILQ_INSERT_TAIL(&pf->tm_conf.tc_list, tm_node, node); ++ pf->tm_conf.nb_tc_node++; ++ tm_node->parent->reference_count++; ++ ++ if (tm_node->shaper_profile) ++ tm_node->shaper_profile->reference_count++; ++ ++ return 0; ++} ++ ++static int ++hns3_tm_queue_node_add(struct rte_eth_dev *dev, uint32_t node_id, ++ uint32_t level_id, struct hns3_tm_node *parent_node, ++ struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_tm_node *tm_node; ++ ++ if (level_id != RTE_TM_NODE_LEVEL_ID_ANY && ++ level_id != HNS3_TM_NODE_LEVEL_QUEUE) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS; ++ error->message = "wrong level"; ++ return -EINVAL; ++ } ++ ++ /* note: dev->data->nb_tx_queues <= max_tx_queues */ ++ if (node_id >= dev->data->nb_tx_queues) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "invalid queue node ID"; ++ return -EINVAL; ++ } ++ ++ if (hns3_txq_mapped_tc_get(hw, node_id) != ++ hns3_tm_calc_node_tc_no(&pf->tm_conf, parent_node->id)) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "queue's TC not match parent's TC"; ++ return -EINVAL; ++ } ++ ++ tm_node = rte_zmalloc("hns3_tm_node", sizeof(struct hns3_tm_node), 0); ++ if (tm_node == NULL) ++ return -ENOMEM; ++ ++ tm_node->id = node_id; ++ tm_node->reference_count = 0; ++ tm_node->parent = parent_node; ++ memcpy(&tm_node->params, params, sizeof(struct rte_tm_node_params)); ++ TAILQ_INSERT_TAIL(&pf->tm_conf.queue_list, tm_node, node); ++ pf->tm_conf.nb_queue_node++; ++ tm_node->parent->reference_count++; ++ ++ return 0; ++} ++ ++static int ++hns3_tm_node_add(struct rte_eth_dev *dev, uint32_t node_id, ++ uint32_t parent_node_id, uint32_t priority, ++ uint32_t weight, uint32_t level_id, ++ struct rte_tm_node_params *params, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ enum hns3_tm_node_type parent_node_type = HNS3_TM_NODE_TYPE_MAX; ++ struct hns3_tm_node *parent_node; ++ int ret; ++ ++ if (params == NULL || error == NULL) ++ return -EINVAL; ++ ++ if (pf->tm_conf.committed) { ++ error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED; ++ error->message = "already committed"; ++ return -EINVAL; ++ } ++ ++ ret = hns3_tm_node_param_check(dev, node_id, priority, weight, ++ params, error); ++ if (ret) ++ return ret; ++ ++ /* root node who don't have a parent */ ++ if (parent_node_id == RTE_TM_NODE_ID_NULL) ++ return hns3_tm_port_node_add(dev, node_id, level_id, ++ params, error); ++ ++ parent_node = hns3_tm_node_search(dev, parent_node_id, ++ &parent_node_type); ++ if (parent_node == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; ++ error->message = "parent not exist"; ++ return -EINVAL; ++ } ++ ++ if (parent_node_type != HNS3_TM_NODE_TYPE_PORT && ++ parent_node_type != HNS3_TM_NODE_TYPE_TC) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARENT_NODE_ID; ++ error->message = "parent is not port or TC"; ++ return -EINVAL; ++ } ++ ++ if (parent_node_type == HNS3_TM_NODE_TYPE_PORT) ++ return hns3_tm_tc_node_add(dev, node_id, level_id, ++ parent_node, params, error); ++ else ++ return hns3_tm_queue_node_add(dev, node_id, level_id, ++ parent_node, params, error); ++} ++ ++static void ++hns3_tm_node_do_delete(struct hns3_pf *pf, ++ enum hns3_tm_node_type node_type, ++ struct hns3_tm_node *tm_node) ++{ ++ if (node_type == HNS3_TM_NODE_TYPE_PORT) { ++ if (tm_node->shaper_profile) ++ tm_node->shaper_profile->reference_count--; ++ rte_free(tm_node); ++ pf->tm_conf.root = NULL; ++ return; ++ } ++ ++ if (tm_node->shaper_profile) ++ tm_node->shaper_profile->reference_count--; ++ tm_node->parent->reference_count--; ++ if (node_type == HNS3_TM_NODE_TYPE_TC) { ++ TAILQ_REMOVE(&pf->tm_conf.tc_list, tm_node, node); ++ pf->tm_conf.nb_tc_node--; ++ } else { ++ TAILQ_REMOVE(&pf->tm_conf.queue_list, tm_node, node); ++ pf->tm_conf.nb_queue_node--; ++ } ++ rte_free(tm_node); ++} ++ ++static int ++hns3_tm_node_delete(struct rte_eth_dev *dev, ++ uint32_t node_id, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ enum hns3_tm_node_type node_type = HNS3_TM_NODE_TYPE_MAX; ++ struct hns3_tm_node *tm_node; ++ ++ if (error == NULL) ++ return -EINVAL; ++ ++ if (pf->tm_conf.committed) { ++ error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED; ++ error->message = "already committed"; ++ return -EINVAL; ++ } ++ ++ tm_node = hns3_tm_node_search(dev, node_id, &node_type); ++ if (tm_node == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "no such node"; ++ return -EINVAL; ++ } ++ ++ if (tm_node->reference_count) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "cannot delete a node which has children"; ++ return -EINVAL; ++ } ++ ++ hns3_tm_node_do_delete(pf, node_type, tm_node); ++ ++ return 0; ++} ++ ++static int ++hns3_tm_node_type_get(struct rte_eth_dev *dev, uint32_t node_id, ++ int *is_leaf, struct rte_tm_error *error) ++{ ++ enum hns3_tm_node_type node_type = HNS3_TM_NODE_TYPE_MAX; ++ struct hns3_tm_node *tm_node; ++ ++ if (is_leaf == NULL || error == NULL) ++ return -EINVAL; ++ ++ tm_node = hns3_tm_node_search(dev, node_id, &node_type); ++ if (tm_node == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "no such node"; ++ return -EINVAL; ++ } ++ ++ if (node_type == HNS3_TM_NODE_TYPE_QUEUE) ++ *is_leaf = true; ++ else ++ *is_leaf = false; ++ ++ return 0; ++} ++ ++static void ++hns3_tm_nonleaf_level_capsbilities_get(struct rte_eth_dev *dev, ++ uint32_t level_id, ++ struct rte_tm_level_capabilities *cap) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ uint32_t max_tx_queues = hns3_tm_max_tx_queues_get(dev); ++ ++ if (level_id == HNS3_TM_NODE_LEVEL_PORT) { ++ cap->n_nodes_max = 1; ++ cap->n_nodes_nonleaf_max = 1; ++ cap->n_nodes_leaf_max = 0; ++ } else { ++ cap->n_nodes_max = HNS3_MAX_TC_NUM; ++ cap->n_nodes_nonleaf_max = HNS3_MAX_TC_NUM; ++ cap->n_nodes_leaf_max = 0; ++ } ++ ++ cap->non_leaf_nodes_identical = 1; ++ cap->leaf_nodes_identical = 1; ++ ++ cap->nonleaf.shaper_private_supported = true; ++ cap->nonleaf.shaper_private_dual_rate_supported = false; ++ cap->nonleaf.shaper_private_rate_min = 0; ++ cap->nonleaf.shaper_private_rate_max = ++ hns3_tm_rate_convert_firmware2tm(hw->max_tm_rate); ++ cap->nonleaf.shaper_shared_n_max = 0; ++ if (level_id == HNS3_TM_NODE_LEVEL_PORT) ++ cap->nonleaf.sched_n_children_max = HNS3_MAX_TC_NUM; ++ else ++ cap->nonleaf.sched_n_children_max = max_tx_queues; ++ cap->nonleaf.sched_sp_n_priorities_max = 1; ++ cap->nonleaf.sched_wfq_n_children_per_group_max = 0; ++ cap->nonleaf.sched_wfq_n_groups_max = 0; ++ cap->nonleaf.sched_wfq_weight_max = 1; ++ cap->nonleaf.stats_mask = 0; ++} ++ ++static void ++hns3_tm_leaf_level_capabilities_get(struct rte_eth_dev *dev, ++ struct rte_tm_level_capabilities *cap) ++{ ++ uint32_t max_tx_queues = hns3_tm_max_tx_queues_get(dev); ++ ++ cap->n_nodes_max = max_tx_queues; ++ cap->n_nodes_nonleaf_max = 0; ++ cap->n_nodes_leaf_max = max_tx_queues; ++ ++ cap->non_leaf_nodes_identical = 1; ++ cap->leaf_nodes_identical = 1; ++ ++ cap->leaf.shaper_private_supported = false; ++ cap->leaf.shaper_private_dual_rate_supported = false; ++ cap->leaf.shaper_private_rate_min = 0; ++ cap->leaf.shaper_private_rate_max = 0; ++ cap->leaf.shaper_shared_n_max = 0; ++ cap->leaf.cman_head_drop_supported = false; ++ cap->leaf.cman_wred_context_private_supported = false; ++ cap->leaf.cman_wred_context_shared_n_max = 0; ++ cap->leaf.stats_mask = 0; ++} ++ ++static int ++hns3_tm_level_capabilities_get(struct rte_eth_dev *dev, ++ uint32_t level_id, ++ struct rte_tm_level_capabilities *cap, ++ struct rte_tm_error *error) ++{ ++ if (cap == NULL || error == NULL) ++ return -EINVAL; ++ ++ if (level_id >= HNS3_TM_NODE_LEVEL_MAX) { ++ error->type = RTE_TM_ERROR_TYPE_LEVEL_ID; ++ error->message = "too deep level"; ++ return -EINVAL; ++ } ++ ++ memset(cap, 0, sizeof(struct rte_tm_level_capabilities)); ++ ++ if (level_id != HNS3_TM_NODE_LEVEL_QUEUE) ++ hns3_tm_nonleaf_level_capsbilities_get(dev, level_id, cap); ++ else ++ hns3_tm_leaf_level_capabilities_get(dev, cap); ++ ++ return 0; ++} ++ ++static void ++hns3_tm_nonleaf_node_capabilities_get(struct rte_eth_dev *dev, ++ enum hns3_tm_node_type node_type, ++ struct rte_tm_node_capabilities *cap) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ uint32_t max_tx_queues = hns3_tm_max_tx_queues_get(dev); ++ ++ cap->shaper_private_supported = true; ++ cap->shaper_private_dual_rate_supported = false; ++ cap->shaper_private_rate_min = 0; ++ cap->shaper_private_rate_max = ++ hns3_tm_rate_convert_firmware2tm(hw->max_tm_rate); ++ cap->shaper_shared_n_max = 0; ++ ++ if (node_type == HNS3_TM_NODE_TYPE_PORT) ++ cap->nonleaf.sched_n_children_max = HNS3_MAX_TC_NUM; ++ else ++ cap->nonleaf.sched_n_children_max = max_tx_queues; ++ cap->nonleaf.sched_sp_n_priorities_max = 1; ++ cap->nonleaf.sched_wfq_n_children_per_group_max = 0; ++ cap->nonleaf.sched_wfq_n_groups_max = 0; ++ cap->nonleaf.sched_wfq_weight_max = 1; ++ ++ cap->stats_mask = 0; ++} ++ ++static void ++hns3_tm_leaf_node_capabilities_get(struct rte_eth_dev *dev __rte_unused, ++ struct rte_tm_node_capabilities *cap) ++{ ++ cap->shaper_private_supported = false; ++ cap->shaper_private_dual_rate_supported = false; ++ cap->shaper_private_rate_min = 0; ++ cap->shaper_private_rate_max = 0; ++ cap->shaper_shared_n_max = 0; ++ ++ cap->leaf.cman_head_drop_supported = false; ++ cap->leaf.cman_wred_context_private_supported = false; ++ cap->leaf.cman_wred_context_shared_n_max = 0; ++ ++ cap->stats_mask = 0; ++} ++ ++static int ++hns3_tm_node_capabilities_get(struct rte_eth_dev *dev, ++ uint32_t node_id, ++ struct rte_tm_node_capabilities *cap, ++ struct rte_tm_error *error) ++{ ++ enum hns3_tm_node_type node_type; ++ struct hns3_tm_node *tm_node; ++ ++ if (cap == NULL || error == NULL) ++ return -EINVAL; ++ ++ tm_node = hns3_tm_node_search(dev, node_id, &node_type); ++ if (tm_node == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "no such node"; ++ return -EINVAL; ++ } ++ ++ memset(cap, 0, sizeof(struct rte_tm_node_capabilities)); ++ ++ if (node_type != HNS3_TM_NODE_TYPE_QUEUE) ++ hns3_tm_nonleaf_node_capabilities_get(dev, node_type, cap); ++ else ++ hns3_tm_leaf_node_capabilities_get(dev, cap); ++ ++ return 0; ++} ++ ++static int ++hns3_tm_config_port_rate(struct hns3_hw *hw, ++ struct hns3_tm_shaper_profile *shaper_profile) ++{ ++ uint32_t firmware_rate; ++ uint64_t rate; ++ ++ if (shaper_profile) { ++ rate = shaper_profile->profile.peak.rate; ++ firmware_rate = hns3_tm_rate_convert_tm2firmware(rate); ++ } else { ++ firmware_rate = hw->dcb_info.pg_info[0].bw_limit; ++ } ++ ++ /* ++ * The TM shaper topology after device inited: ++ * pri0 shaper --->| ++ * pri1 shaper --->| ++ * ... |----> pg0 shaper ----> port shaper ++ * ... | ++ * priX shaper --->| ++ * ++ * Because port shaper rate maybe changed by firmware, to avoid ++ * concurrent configure, driver use pg0 shaper to achieve the rate limit ++ * of port. ++ * ++ * The finally port rate = MIN(pg0 shaper rate, port shaper rate) ++ */ ++ return hns3_pg_shaper_rate_cfg(hw, 0, firmware_rate); ++} ++ ++static int ++hns3_tm_config_tc_rate(struct hns3_hw *hw, ++ uint8_t tc_no, ++ struct hns3_tm_shaper_profile *shaper_profile) ++{ ++ uint32_t firmware_rate; ++ uint64_t rate; ++ ++ if (shaper_profile) { ++ rate = shaper_profile->profile.peak.rate; ++ firmware_rate = hns3_tm_rate_convert_tm2firmware(rate); ++ } else { ++ firmware_rate = hw->dcb_info.tc_info[tc_no].bw_limit; ++ } ++ ++ return hns3_pri_shaper_rate_cfg(hw, tc_no, firmware_rate); ++} ++ ++static bool ++hns3_tm_configure_check(struct hns3_hw *hw, struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ struct hns3_tm_conf *tm_conf = &pf->tm_conf; ++ struct hns3_tm_node_list *tc_list = &tm_conf->tc_list; ++ struct hns3_tm_node_list *queue_list = &tm_conf->queue_list; ++ struct hns3_tm_node *tm_node; ++ ++ /* TC */ ++ TAILQ_FOREACH(tm_node, tc_list, node) { ++ if (!tm_node->reference_count) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS; ++ error->message = "TC without queue assigned"; ++ return false; ++ } ++ ++ if (hns3_tm_calc_node_tc_no(tm_conf, tm_node->id) >= ++ hw->num_tc) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "node's TC not exist"; ++ return false; ++ } ++ } ++ ++ /* Queue */ ++ TAILQ_FOREACH(tm_node, queue_list, node) { ++ if (tm_node->id >= hw->data->nb_tx_queues) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "node's queue invalid"; ++ return false; ++ } ++ ++ if (hns3_txq_mapped_tc_get(hw, tm_node->id) != ++ hns3_tm_calc_node_tc_no(tm_conf, tm_node->parent->id)) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "queue's TC not match parent's TC"; ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static int ++hns3_tm_hierarchy_do_commit(struct hns3_hw *hw, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ struct hns3_tm_node_list *tc_list = &pf->tm_conf.tc_list; ++ struct hns3_tm_node *tm_node; ++ uint8_t tc_no; ++ int ret; ++ ++ /* port */ ++ tm_node = pf->tm_conf.root; ++ if (tm_node->shaper_profile) { ++ ret = hns3_tm_config_port_rate(hw, tm_node->shaper_profile); ++ if (ret) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE; ++ error->message = "fail to set port peak rate"; ++ return -EIO; ++ } ++ } ++ ++ /* TC */ ++ TAILQ_FOREACH(tm_node, tc_list, node) { ++ if (tm_node->shaper_profile == NULL) ++ continue; ++ ++ tc_no = hns3_tm_calc_node_tc_no(&pf->tm_conf, tm_node->id); ++ ret = hns3_tm_config_tc_rate(hw, tc_no, ++ tm_node->shaper_profile); ++ if (ret) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS; ++ error->message = "fail to set TC peak rate"; ++ return -EIO; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_tm_hierarchy_commit(struct rte_eth_dev *dev, ++ int clear_on_fail, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ int ret; ++ ++ if (error == NULL) ++ return -EINVAL; ++ ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { ++ error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED; ++ error->message = "device is resetting"; ++ /* don't goto fail_clear, user may try later */ ++ return -EBUSY; ++ } ++ ++ if (pf->tm_conf.root == NULL) ++ goto done; ++ ++ /* check configure before commit make sure key configure not violated */ ++ if (!hns3_tm_configure_check(hw, error)) ++ goto fail_clear; ++ ++ ret = hns3_tm_hierarchy_do_commit(hw, error); ++ if (ret) ++ goto fail_clear; ++ ++done: ++ pf->tm_conf.committed = true; ++ return 0; ++ ++fail_clear: ++ if (clear_on_fail) { ++ hns3_tm_conf_uninit(dev); ++ hns3_tm_conf_init(dev); ++ } ++ return -EINVAL; ++} ++ ++static int ++hns3_tm_hierarchy_commit_wrap(struct rte_eth_dev *dev, ++ int clear_on_fail, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ rte_spinlock_lock(&hw->lock); ++ ret = hns3_tm_hierarchy_commit(dev, clear_on_fail, error); ++ rte_spinlock_unlock(&hw->lock); ++ ++ return ret; ++} ++ ++static int ++hns3_tm_node_shaper_do_update(struct hns3_hw *hw, ++ uint32_t node_id, ++ enum hns3_tm_node_type node_type, ++ struct hns3_tm_shaper_profile *shaper_profile, ++ struct rte_tm_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ uint8_t tc_no; ++ int ret; ++ ++ if (node_type == HNS3_TM_NODE_TYPE_QUEUE) { ++ if (shaper_profile != NULL) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID; ++ error->message = "queue node shaper not supported"; ++ return -EINVAL; ++ } ++ return 0; ++ } ++ ++ if (!pf->tm_conf.committed) ++ return 0; ++ ++ if (node_type == HNS3_TM_NODE_TYPE_PORT) { ++ ret = hns3_tm_config_port_rate(hw, shaper_profile); ++ if (ret) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE; ++ error->message = "fail to update port peak rate"; ++ } ++ ++ return ret; ++ } ++ ++ /* ++ * update TC's shaper ++ */ ++ tc_no = hns3_tm_calc_node_tc_no(&pf->tm_conf, node_id); ++ ret = hns3_tm_config_tc_rate(hw, tc_no, shaper_profile); ++ if (ret) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE; ++ error->message = "fail to update TC peak rate"; ++ } ++ ++ return ret; ++} ++ ++static int ++hns3_tm_node_shaper_update(struct rte_eth_dev *dev, ++ uint32_t node_id, ++ uint32_t shaper_profile_id, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ enum hns3_tm_node_type node_type = HNS3_TM_NODE_TYPE_MAX; ++ struct hns3_tm_shaper_profile *profile = NULL; ++ struct hns3_tm_node *tm_node; ++ ++ if (error == NULL) ++ return -EINVAL; ++ ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { ++ error->type = RTE_TM_ERROR_TYPE_UNSPECIFIED; ++ error->message = "device is resetting"; ++ return -EBUSY; ++ } ++ ++ tm_node = hns3_tm_node_search(dev, node_id, &node_type); ++ if (tm_node == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_NODE_ID; ++ error->message = "no such node"; ++ return -EINVAL; ++ } ++ ++ if (shaper_profile_id == tm_node->params.shaper_profile_id) ++ return 0; ++ ++ if (shaper_profile_id != RTE_TM_SHAPER_PROFILE_ID_NONE) { ++ profile = hns3_tm_shaper_profile_search(dev, shaper_profile_id); ++ if (profile == NULL) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_ID; ++ error->message = "profile ID not exist"; ++ return -EINVAL; ++ } ++ } ++ ++ if (hns3_tm_node_shaper_do_update(hw, node_id, node_type, ++ profile, error)) ++ return -EINVAL; ++ ++ if (tm_node->shaper_profile) ++ tm_node->shaper_profile->reference_count--; ++ tm_node->shaper_profile = profile; ++ tm_node->params.shaper_profile_id = shaper_profile_id; ++ if (profile != NULL) ++ profile->reference_count++; ++ ++ return 0; ++} ++ ++static int ++hns3_tm_node_shaper_update_wrap(struct rte_eth_dev *dev, ++ uint32_t node_id, ++ uint32_t shaper_profile_id, ++ struct rte_tm_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ rte_spinlock_lock(&hw->lock); ++ ret = hns3_tm_node_shaper_update(dev, node_id, ++ shaper_profile_id, error); ++ rte_spinlock_unlock(&hw->lock); ++ ++ return ret; ++} ++ ++static const struct rte_tm_ops hns3_tm_ops = { ++ .capabilities_get = hns3_tm_capabilities_get, ++ .shaper_profile_add = hns3_tm_shaper_profile_add, ++ .shaper_profile_delete = hns3_tm_shaper_profile_del, ++ .node_add = hns3_tm_node_add, ++ .node_delete = hns3_tm_node_delete, ++ .node_type_get = hns3_tm_node_type_get, ++ .level_capabilities_get = hns3_tm_level_capabilities_get, ++ .node_capabilities_get = hns3_tm_node_capabilities_get, ++ .hierarchy_commit = hns3_tm_hierarchy_commit_wrap, ++ .node_shaper_update = hns3_tm_node_shaper_update_wrap, ++}; ++ ++int ++hns3_tm_ops_get(struct rte_eth_dev *dev __rte_unused, ++ void *arg) ++{ ++ if (arg == NULL) ++ return -EINVAL; ++ ++ *(const void **)arg = &hns3_tm_ops; ++ ++ return 0; ++} ++ ++void ++hns3_tm_dev_start_proc(struct hns3_hw *hw) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ ++ if (pf->tm_conf.root && !pf->tm_conf.committed) ++ hns3_warn(hw, ++ "please call hierarchy_commit() before starting the port."); ++} ++ ++/* ++ * We need clear tm_conf committed flag when device stop so that user can modify ++ * tm configuration (e.g. add or delete node). ++ * ++ * If user don't call hierarchy commit when device start later, the Port/TC's ++ * shaper rate still the same as previous committed. ++ * ++ * To avoid the above problem, we need recover Port/TC shaper rate when device ++ * stop. ++ */ ++void ++hns3_tm_dev_stop_proc(struct hns3_hw *hw) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ struct hns3_tm_node_list *tc_list = &pf->tm_conf.tc_list; ++ struct hns3_tm_node *tm_node; ++ uint8_t tc_no; ++ ++ if (!pf->tm_conf.committed) ++ return; ++ ++ tm_node = pf->tm_conf.root; ++ if (tm_node != NULL && tm_node->shaper_profile) ++ (void)hns3_tm_config_port_rate(hw, NULL); ++ ++ TAILQ_FOREACH(tm_node, tc_list, node) { ++ if (tm_node->shaper_profile == NULL) ++ continue; ++ tc_no = hns3_tm_calc_node_tc_no(&pf->tm_conf, tm_node->id); ++ (void)hns3_tm_config_tc_rate(hw, tc_no, NULL); ++ } ++ ++ pf->tm_conf.committed = false; ++} ++ ++int ++hns3_tm_conf_update(struct hns3_hw *hw) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ struct rte_tm_error error; ++ ++ if (pf->tm_conf.root == NULL || !pf->tm_conf.committed) ++ return 0; ++ ++ memset(&error, 0, sizeof(struct rte_tm_error)); ++ return hns3_tm_hierarchy_do_commit(hw, &error); ++} +diff --git a/drivers/net/hns3/hns3_tm.h b/drivers/net/hns3/hns3_tm.h +new file mode 100644 +index 0000000..d8de3e4 +--- /dev/null ++++ b/drivers/net/hns3/hns3_tm.h +@@ -0,0 +1,103 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2020-2020 Hisilicon Limited. ++ */ ++ ++#ifndef _HNS3_TM_H_ ++#define _HNS3_TM_H_ ++ ++#include ++#include ++#include ++ ++enum hns3_tm_node_type { ++ HNS3_TM_NODE_TYPE_PORT, ++ HNS3_TM_NODE_TYPE_TC, ++ HNS3_TM_NODE_TYPE_QUEUE, ++ HNS3_TM_NODE_TYPE_MAX, ++}; ++ ++enum hns3_tm_node_level { ++ HNS3_TM_NODE_LEVEL_PORT, ++ HNS3_TM_NODE_LEVEL_TC, ++ HNS3_TM_NODE_LEVEL_QUEUE, ++ HNS3_TM_NODE_LEVEL_MAX, ++}; ++ ++struct hns3_tm_shaper_profile { ++ TAILQ_ENTRY(hns3_tm_shaper_profile) node; ++ uint32_t shaper_profile_id; ++ uint32_t reference_count; ++ struct rte_tm_shaper_params profile; ++}; ++ ++TAILQ_HEAD(hns3_shaper_profile_list, hns3_tm_shaper_profile); ++ ++struct hns3_tm_node { ++ TAILQ_ENTRY(hns3_tm_node) node; ++ uint32_t id; ++ uint32_t reference_count; ++ struct hns3_tm_node *parent; ++ struct hns3_tm_shaper_profile *shaper_profile; ++ struct rte_tm_node_params params; ++}; ++ ++TAILQ_HEAD(hns3_tm_node_list, hns3_tm_node); ++ ++struct hns3_tm_conf { ++ uint32_t nb_leaf_nodes_max; /* max numbers of leaf nodes */ ++ uint32_t nb_nodes_max; /* max numbers of nodes */ ++ uint32_t nb_shaper_profile_max; /* max numbers of shaper profile */ ++ ++ struct hns3_shaper_profile_list shaper_profile_list; ++ uint32_t nb_shaper_profile; /* number of shaper profile */ ++ ++ struct hns3_tm_node *root; ++ struct hns3_tm_node_list tc_list; ++ struct hns3_tm_node_list queue_list; ++ uint32_t nb_tc_node; /* number of added TC nodes */ ++ uint32_t nb_queue_node; /* number of added queue nodes */ ++ ++ /* ++ * This flag is used to check if APP can change the TM node ++ * configuration. ++ * When it's true, means the configuration is applied to HW, ++ * APP should not add/delete the TM node configuration. ++ * When starting the port, APP should call the hierarchy_commit API to ++ * set this flag to true. When stopping the port, this flag should be ++ * set to false. ++ */ ++ bool committed; ++}; ++ ++/* ++ * This API used to calc node TC no. User must make sure the node id is in the ++ * TC node id range. ++ * ++ * User could call rte_eth_dev_info_get API to get port's max_tx_queues, The TM ++ * id's assignment should following the below rules: ++ * [0, max_tx_queues-1]: correspond queues's node id ++ * max_tx_queues + 0 : correspond TC0's node id ++ * max_tx_queues + 1 : correspond TC1's node id ++ * ... ++ * max_tx_queues + 7 : correspond TC7's node id ++ * max_tx_queues + 8 : correspond port's node id ++ * ++ */ ++static inline uint8_t ++hns3_tm_calc_node_tc_no(struct hns3_tm_conf *conf, uint32_t node_id) ++{ ++ if (node_id >= conf->nb_leaf_nodes_max && ++ node_id < conf->nb_nodes_max - 1) ++ return node_id - conf->nb_leaf_nodes_max; ++ else ++ return 0; ++} ++ ++void hns3_tm_conf_init(struct rte_eth_dev *dev); ++void hns3_tm_conf_uninit(struct rte_eth_dev *dev); ++int hns3_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg); ++void hns3_tm_dev_start_proc(struct hns3_hw *hw); ++void hns3_tm_dev_stop_proc(struct hns3_hw *hw); ++int hns3_tm_conf_update(struct hns3_hw *hw); ++ ++#endif /* _HNS3_TM_H */ +diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build +index 5674d98..f6aac69 100644 +--- a/drivers/net/hns3/meson.build ++++ b/drivers/net/hns3/meson.build +@@ -25,7 +25,8 @@ sources = files('hns3_cmd.c', + 'hns3_rss.c', + 'hns3_rxtx.c', + 'hns3_stats.c', +- 'hns3_mp.c') ++ 'hns3_mp.c', ++ 'hns3_tm.c') + + deps += ['hash'] + +-- +2.7.4 + diff --git a/0013-dpdk-optimize-the-efficiency-of-compiling-dpdk.patch b/0013-dpdk-optimize-the-efficiency-of-compiling-dpdk.patch deleted file mode 100644 index 3a23de0..0000000 --- a/0013-dpdk-optimize-the-efficiency-of-compiling-dpdk.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 5e554c15982617a89b85aeb71592c20bfa7bdecd Mon Sep 17 00:00:00 2001 -From: Renmingshuai -Date: Tue, 13 Apr 2021 16:25:43 +0800 -Subject: [PATCH] optimize the efficiency of compiling dpdk - ---- - config/common_base | 5 +++ - mk/rte.combinedlib.mk | 10 +++++ - mk/rte.lib.mk | 102 +++++++++++++++++++++++++++++++++++++++--- - 3 files changed, 110 insertions(+), 7 deletions(-) - -diff --git a/config/common_base b/config/common_base -index 57b1349..392e6c3 100644 ---- a/config/common_base -+++ b/config/common_base -@@ -59,6 +59,11 @@ CONFIG_RTE_ENABLE_LTO=n - # - CONFIG_RTE_BUILD_SHARED_LIB=n - -+# -+# Compile to both static library and share library -+# -+CONFIG_RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS=n -+ - # - # Use newest code breaking previous ABI - # -diff --git a/mk/rte.combinedlib.mk b/mk/rte.combinedlib.mk -index 9d0f935..1088543 100644 ---- a/mk/rte.combinedlib.mk -+++ b/mk/rte.combinedlib.mk -@@ -15,9 +15,16 @@ RTE_LIBNAME := dpdk - COMBINEDLIB := lib$(RTE_LIBNAME)$(EXT) - - LIBS := $(filter-out $(COMBINEDLIB), $(sort $(notdir $(wildcard $(RTE_OUTPUT)/lib/*$(EXT))))) -+ifeq ($(CONFIG_RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS),y) -+COMBINEDLIB_SO := lib$(RTE_LIBNAME).so -+LIBS_SO := $(filter-out $(COMBINEDLIB_SO), $(sort $(notdir $(wildcard $(RTE_OUTPUT)/lib/*.so)))) -+endif - - all: FORCE - $(Q)echo "GROUP ( $(LIBS) )" > $(RTE_OUTPUT)/lib/$(COMBINEDLIB) -+ifeq ($(CONFIG_RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS),y) -+ $(Q)echo "GROUP ( $(LIBS_SO) )" > $(RTE_OUTPUT)/lib/$(COMBINEDLIB_SO) -+endif - - # - # Clean all generated files -@@ -25,6 +32,9 @@ all: FORCE - .PHONY: clean - clean: - $(Q)rm -f $(RTE_OUTPUT)/lib/$(COMBINEDLIB) -+ifeq ($(CONFIG_RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS),y) -+ $(Q)rm -f $(RTE_OUTPUT)/lib/$(COMBINEDLIB_SO) -+endif - - .PHONY: FORCE - FORCE: -diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk -index 4516d1c..78f3c27 100644 ---- a/mk/rte.lib.mk -+++ b/mk/rte.lib.mk -@@ -19,13 +19,6 @@ else ifeq ($(LIBABIVER),) - LIBABIVER := 0.$(shell cat $(RTE_SRCDIR)/ABI_VERSION | tr -d '.') - endif - --ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y) --LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB)) --ifeq ($(EXTLIB_BUILD),n) --CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP) --endif --endif -- - - _BUILD = $(LIB) - PREINSTALL = $(SYMLINK-FILES-y) -@@ -34,6 +27,16 @@ _CLEAN = doclean - - LDLIBS += $(EXECENV_LDLIBS-y) - -+ifeq ($(CONFIG_RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS),y) -+LIB_SO = $(LIB) -+LIB_SO := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB_SO)) -+ifeq ($(EXTLIB_BUILD),n) -+CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP) -+endif -+_BUILD += $(LIB_SO) -+_INSTALL += $(INSTALL-FILES-y) $(RTE_OUTPUT)/lib/$(LIB_SO) -+endif -+ - .PHONY: all - all: install - -@@ -74,6 +77,89 @@ ifneq ($(CC_SUPPORTS_Z),false) - NO_UNDEFINED := -z defs - endif - -+ifeq ($(CONFIG_RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS),y) -+O_TO_S = $(LD) -L$(RTE_SDK_BIN)/lib $(_CPU_LDFLAGS) $(EXTRA_LDFLAGS) \ -+ -shared $(OBJS-y) $(NO_UNDEFINED) $(LDLIBS) -Wl,-soname,$(LIB_SO) -o $(LIB_SO) -+O_TO_S_STR = $(subst ','\'',$(O_TO_S)) #'# fix syntax highlight -+O_TO_S_DISP = $(if $(V),"$(O_TO_S_STR)"," LD $(@)") -+O_TO_S_DO = @set -e; \ -+ echo $(O_TO_S_DISP); \ -+ $(O_TO_S) && \ -+ echo $(O_TO_S_CMD) > $(call exe2cmd,$(@)) -+ -+-include .$(LIB_SO).cmd -+ -+# -+# Archive objects in .a file if needed -+# -+$(LIB): $(OBJS-y) $(DEP_$(LIB)) FORCE -+ @[ -d $(dir $@) ] || mkdir -p $(dir $@) -+ $(if $(D),\ -+ @echo -n "$< -> $@ " ; \ -+ echo -n "file_missing=$(call boolean,$(file_missing)) " ; \ -+ echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(O_TO_A_STR))) " ; \ -+ echo -n "depfile_missing=$(call boolean,$(depfile_missing)) " ; \ -+ echo "depfile_newer=$(call boolean,$(depfile_newer)) ") -+ $(if $(or \ -+ $(file_missing),\ -+ $(call cmdline_changed,$(O_TO_A_STR)),\ -+ $(depfile_missing),\ -+ $(depfile_newer)),\ -+ $(O_TO_A_DO)) -+ -+$(LIB_SO): $(OBJS-y) $(DEP_$(LIB_SO)) FORCE -+ifeq ($(LIBABIVER),) -+ @echo "Must Specify a $(LIB_SO) ABI version" -+ @false -+endif -+ @[ -d $(dir $@) ] || mkdir -p $(dir $@) -+ $(if $(D),\ -+ @echo -n "$< -> $@ " ; \ -+ echo -n "file_missing=$(call boolean,$(file_missing)) " ; \ -+ echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(O_TO_S_STR))) " ; \ -+ echo -n "depfile_missing=$(call boolean,$(depfile_missing)) " ; \ -+ echo "depfile_newer=$(call boolean,$(depfile_newer)) ") -+ $(if $(or \ -+ $(file_missing),\ -+ $(call cmdline_changed,$(O_TO_S_STR)),\ -+ $(depfile_missing),\ -+ $(depfile_newer)),\ -+ $(O_TO_S_DO)) -+ -+# -+# install lib in $(RTE_OUTPUT)/lib -+# -+$(RTE_OUTPUT)/lib/$(LIB): $(LIB) -+ @echo " INSTALL-LIB $(LIB)" -+ @[ -d $(RTE_OUTPUT)/lib ] || mkdir -p $(RTE_OUTPUT)/lib -+ cp -f $(LIB) $(RTE_OUTPUT)/lib -+ -+$(RTE_OUTPUT)/lib/$(LIB_SO): $(LIB_SO) -+ @echo " INSTALL-LIB $(LIB_SO)" -+ @[ -d $(RTE_OUTPUT)/lib ] || mkdir -p $(RTE_OUTPUT)/lib -+ cp -f $(LIB_SO) $(RTE_OUTPUT)/lib -+ ln -s -f $< $(shell echo $@ | sed 's/\.so.*/.so/') -+ -+# -+# Clean all generated files -+# -+.PHONY: clean -+clean: _postclean -+ -+.PHONY: doclean -+doclean: -+ $(Q)rm -rf $(LIB) $(LIB_SO) $(OBJS-all) $(DEPS-all) $(DEPSTMP-all) \ -+ $(CMDS-all) .$(LIB).cmd $(INSTALL-FILES-all) *.pmd.c *.pmd.o -+ $(Q)rm -f $(_BUILD_TARGETS) $(_INSTALL_TARGETS) $(_CLEAN_TARGETS) -+ -+else -+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y) -+LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB)) -+ifeq ($(EXTLIB_BUILD),n) -+CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP) -+endif -+endif -+ - O_TO_S = $(LD) -L$(RTE_SDK_BIN)/lib $(_CPU_LDFLAGS) $(EXTRA_LDFLAGS) \ - -shared $(OBJS-y) $(NO_UNDEFINED) $(LDLIBS) -Wl,-soname,$(LIB) -o $(LIB) - O_TO_S_STR = $(subst ','\'',$(O_TO_S)) #'# fix syntax highlight -@@ -148,6 +234,8 @@ doclean: - $(CMDS-all) .$(LIB).cmd $(INSTALL-FILES-all) *.pmd.c *.pmd.o - $(Q)rm -f $(_BUILD_TARGETS) $(_INSTALL_TARGETS) $(_CLEAN_TARGETS) - -+endif -+ - include $(RTE_SDK)/mk/internal/rte.compile-post.mk - include $(RTE_SDK)/mk/internal/rte.install-post.mk - include $(RTE_SDK)/mk/internal/rte.clean-post.mk --- -2.19.1 - diff --git a/0013-net-hns3-fix-VF-query-link-status-in-dev-init.patch b/0013-net-hns3-fix-VF-query-link-status-in-dev-init.patch new file mode 100644 index 0000000..93878c2 --- /dev/null +++ b/0013-net-hns3-fix-VF-query-link-status-in-dev-init.patch @@ -0,0 +1,45 @@ +From 92f474b6b5f954d20b81576549a25ce8b7bc2a2b Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 14 Jan 2021 21:33:32 +0800 +Subject: [PATCH 013/189] net/hns3: fix VF query link status in dev init + +Current hns3vf queried link status in dev init stage, but the link +status should be maintained in dev start stage, this patch fix this. + +Also, in the dev start stage, we use quick query instead of delayed +query to make sure update the link status soon. + +Fixes: a5475d61fa34 ("net/hns3: support VF") +Fixes: 958edf6627d5 ("net/hns3: fix VF link status") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev_vf.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index c126384..ee89505 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1749,7 +1749,6 @@ hns3vf_init_hardware(struct hns3_adapter *hns) + goto err_init_hardware; + } + +- hns3vf_request_link_info(hw); + return 0; + + err_init_hardware: +@@ -2238,7 +2237,7 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + hns3_rx_scattered_calc(dev); + hns3_set_rxtx_function(dev); + hns3_mp_req_start_rxtx(dev); +- rte_eal_alarm_set(HNS3VF_SERVICE_INTERVAL, hns3vf_service_handler, dev); ++ hns3vf_service_handler(dev); + + hns3vf_restore_filter(dev); + +-- +2.7.4 + diff --git a/0014-net-hns3-use-new-opcode-for-clearing-hardware-resour.patch b/0014-net-hns3-use-new-opcode-for-clearing-hardware-resour.patch new file mode 100644 index 0000000..c524d96 --- /dev/null +++ b/0014-net-hns3-use-new-opcode-for-clearing-hardware-resour.patch @@ -0,0 +1,34 @@ +From 1f68430b13d5aed1851c97761163b44b38d4f37d Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Thu, 14 Jan 2021 21:33:33 +0800 +Subject: [PATCH 014/189] net/hns3: use new opcode for clearing hardware + resource + +The original command opcode '0x700A' may cause firmware error, +so '0x700A' is deserted, now use '0x700B' to replace it. + +Fixes: 223d9eceaeee ("net/hns3: clear residual hardware configurations on init") +Cc: stable@dpdk.org + +Signed-off-by: Hongbo Zheng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 194c3a7..e40293b 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -203,7 +203,7 @@ enum hns3_opcode_type { + HNS3_OPC_FD_COUNTER_OP = 0x1205, + + /* Clear hardware state command */ +- HNS3_OPC_CLEAR_HW_STATE = 0x700A, ++ HNS3_OPC_CLEAR_HW_STATE = 0x700B, + + /* SFP command */ + HNS3_OPC_SFP_GET_SPEED = 0x7104, +-- +2.7.4 + diff --git a/0015-net-hns3-fix-register-length-when-dumping-registers.patch b/0015-net-hns3-fix-register-length-when-dumping-registers.patch new file mode 100644 index 0000000..28bba41 --- /dev/null +++ b/0015-net-hns3-fix-register-length-when-dumping-registers.patch @@ -0,0 +1,59 @@ +From 7fab993aa57ba5f2e4bce07949de602e1a40daf1 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 14 Jan 2021 21:33:34 +0800 +Subject: [PATCH 015/189] net/hns3: fix register length when dumping registers + +Currently, the reg length return by HNS3 is the total length of all the +registers. But for upper layer user, the total register length is the +length multiplied by width. This can lead to a waste of memory and print +some invalid information. + +This patch corrects the length and width of the register. + +Fixes: 936eda25e8da ("net/hns3: support dump register") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_regs.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index b2cc599..32597fe 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -104,6 +104,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines; + uint32_t regs_num_32_bit, regs_num_64_bit; ++ uint32_t dfx_reg_lines; + uint32_t len; + int ret; + +@@ -117,7 +118,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1; + + len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num + +- tqp_intr_lines * hw->num_msi) * REG_LEN_PER_LINE; ++ tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE; + + if (!hns->is_vf) { + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +@@ -126,8 +127,11 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + ret); + return -ENOTSUP; + } +- len += regs_num_32_bit * sizeof(uint32_t) + +- regs_num_64_bit * sizeof(uint64_t); ++ dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) / ++ REG_LEN_PER_LINE + 1; ++ dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) / ++ REG_LEN_PER_LINE + 1; ++ len += dfx_reg_lines * REG_NUM_PER_LINE; + } + + *length = len; +-- +2.7.4 + diff --git a/0016-net-hns3-fix-data-overwriting-during-register-dump.patch b/0016-net-hns3-fix-data-overwriting-during-register-dump.patch new file mode 100644 index 0000000..7923fbf --- /dev/null +++ b/0016-net-hns3-fix-data-overwriting-during-register-dump.patch @@ -0,0 +1,152 @@ +From 3c4b289d438451fa8e3c520bef4b1a32d68f4bea Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 14 Jan 2021 21:33:35 +0800 +Subject: [PATCH 016/189] net/hns3: fix data overwriting during register dump + +The data pointer has not moved after BAR register dumped. This causes +the later register to overwrite the previous data. + +This patch fix the overwriting by move the pointer after every dump +function. And the missing separator between 32-bit register and the +64-bit register is also added to avoid a parsing error. + +Fixes: 936eda25e8da ("net/hns3: support dump register") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_regs.c | 70 +++++++++++++++++++++++++------------------- + 1 file changed, 40 insertions(+), 30 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 32597fe..775e096 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -252,63 +252,68 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + return 0; + } + +-static void ++static int ++hns3_insert_reg_separator(int reg_num, uint32_t *data) ++{ ++ int separator_num; ++ int i; ++ ++ separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE; ++ for (i = 0; i < separator_num; i++) ++ *data++ = SEPARATOR_VALUE; ++ return separator_num; ++} ++ ++static int + hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ uint32_t *origin_data_ptr = data; + uint32_t reg_offset; +- int separator_num; +- int reg_um; ++ int reg_num; + int i, j; + + /* fetching per-PF registers values from PF PCIe register space */ +- reg_um = sizeof(cmdq_reg_addrs) / sizeof(uint32_t); +- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; +- for (i = 0; i < reg_um; i++) ++ reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t); ++ for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]); +- for (i = 0; i < separator_num; i++) +- *data++ = SEPARATOR_VALUE; ++ data += hns3_insert_reg_separator(reg_num, data); + + if (hns->is_vf) +- reg_um = sizeof(common_vf_reg_addrs) / sizeof(uint32_t); ++ reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t); + else +- reg_um = sizeof(common_reg_addrs) / sizeof(uint32_t); +- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; +- for (i = 0; i < reg_um; i++) ++ reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t); ++ for (i = 0; i < reg_num; i++) + if (hns->is_vf) + *data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]); + else + *data++ = hns3_read_dev(hw, common_reg_addrs[i]); +- for (i = 0; i < separator_num; i++) +- *data++ = SEPARATOR_VALUE; ++ data += hns3_insert_reg_separator(reg_num, data); + +- reg_um = sizeof(ring_reg_addrs) / sizeof(uint32_t); +- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; ++ reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t); + for (j = 0; j < hw->tqps_num; j++) { + reg_offset = hns3_get_tqp_reg_offset(j); +- for (i = 0; i < reg_um; i++) ++ for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, + ring_reg_addrs[i] + reg_offset); +- for (i = 0; i < separator_num; i++) +- *data++ = SEPARATOR_VALUE; ++ data += hns3_insert_reg_separator(reg_num, data); + } + +- reg_um = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t); +- separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; ++ reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t); + for (j = 0; j < hw->num_msi; j++) { + reg_offset = HNS3_TQP_INTR_REG_SIZE * j; +- for (i = 0; i < reg_um; i++) +- *data++ = hns3_read_dev(hw, +- tqp_intr_reg_addrs[i] + ++ for (i = 0; i < reg_num; i++) ++ *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] + + reg_offset); +- for (i = 0; i < separator_num; i++) +- *data++ = SEPARATOR_VALUE; ++ data += hns3_insert_reg_separator(reg_num, data); + } ++ return data - origin_data_ptr; + } + + int + hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + { ++#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t)) + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + uint32_t regs_num_32_bit; +@@ -338,7 +343,7 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + return -ENOTSUP; + + /* fetching per-PF registers values from PF PCIe register space */ +- hns3_direct_access_regs(hw, data); ++ data += hns3_direct_access_regs(hw, data); + + if (hns->is_vf) + return 0; +@@ -355,11 +360,16 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); + return ret; + } +- + data += regs_num_32_bit; ++ data += hns3_insert_reg_separator(regs_num_32_bit, data); ++ + ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data); +- if (ret) ++ if (ret) { + hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); +- ++ return ret; ++ } ++ data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE; ++ data += hns3_insert_reg_separator(regs_num_64_bit * ++ HNS3_64_BIT_REG_SIZE, data); + return ret; + } +-- +2.7.4 + diff --git a/0017-net-hns3-fix-dump-register-out-of-range.patch b/0017-net-hns3-fix-dump-register-out-of-range.patch new file mode 100644 index 0000000..7175809 --- /dev/null +++ b/0017-net-hns3-fix-dump-register-out-of-range.patch @@ -0,0 +1,38 @@ +From a69abf12f46295044e4e59b60e49e73bc66afe10 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 14 Jan 2021 21:33:36 +0800 +Subject: [PATCH 017/189] net/hns3: fix dump register out of range + +Currently, when dump the queue interrupt registers, the number of +registers that should be dumped is calculated from num_msi. But the +value of num_msi includes the number of misc interrupts. So, for some +hardware version, like kupeng930, it will lead to an illegal access. + +This patch replace num_msi with intr_tqps_num which indicate the +number of interrupts used by the tqps. + +Fixes: 936eda25e8da ("net/hns3: support dump register") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_regs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 775e096..f2cb465 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -300,7 +300,7 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + } + + reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t); +- for (j = 0; j < hw->num_msi; j++) { ++ for (j = 0; j < hw->intr_tqps_num; j++) { + reg_offset = HNS3_TQP_INTR_REG_SIZE * j; + for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] + +-- +2.7.4 + diff --git a/0018-net-hns3-remove-unused-assignment-for-RSS-key.patch b/0018-net-hns3-remove-unused-assignment-for-RSS-key.patch new file mode 100644 index 0000000..c2fd704 --- /dev/null +++ b/0018-net-hns3-remove-unused-assignment-for-RSS-key.patch @@ -0,0 +1,74 @@ +From 3405d3daec40b258341eeccc5e07c0a9cfd29e6e Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Thu, 14 Jan 2021 21:33:37 +0800 +Subject: [PATCH 018/189] net/hns3: remove unused assignment for RSS key + +The default RSS key does not need to be configured repeatedly +when call hns3_dev_configure function with the NULL RSS key +because the default RSS key has been configured when the PMD +driver run hns3_do_start function with starting device. + +Besides, it will not overwrite the initialized key if +rte_eth_dev_configure API will be called directly and RSS key is NULL +after init PMD driver. + +Therefore, the assignment for RSS key in hns3_dev_configure +function is unnecessary. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 6 ------ + drivers/net/hns3/hns3_ethdev_vf.c | 6 ------ + 2 files changed, 12 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 2bc28ef..449d967 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2316,7 +2316,6 @@ hns3_dev_configure(struct rte_eth_dev *dev) + struct rte_eth_conf *conf = &dev->data->dev_conf; + enum rte_eth_rx_mq_mode mq_mode = conf->rxmode.mq_mode; + struct hns3_hw *hw = &hns->hw; +- struct hns3_rss_conf *rss_cfg = &hw->rss_info; + uint16_t nb_rx_q = dev->data->nb_rx_queues; + uint16_t nb_tx_q = dev->data->nb_tx_queues; + struct rte_eth_rss_conf rss_conf; +@@ -2363,11 +2362,6 @@ hns3_dev_configure(struct rte_eth_dev *dev) + conf->rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; + rss_conf = conf->rx_adv_conf.rss_conf; + hw->rss_dis_flag = false; +- if (rss_conf.rss_key == NULL) { +- rss_conf.rss_key = rss_cfg->key; +- rss_conf.rss_key_len = HNS3_RSS_KEY_SIZE; +- } +- + ret = hns3_dev_rss_hash_update(dev, &rss_conf); + if (ret) + goto cfg_err; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index ee89505..bb4ec6b 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -773,7 +773,6 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- struct hns3_rss_conf *rss_cfg = &hw->rss_info; + struct rte_eth_conf *conf = &dev->data->dev_conf; + enum rte_eth_rx_mq_mode mq_mode = conf->rxmode.mq_mode; + uint16_t nb_rx_q = dev->data->nb_rx_queues; +@@ -816,11 +815,6 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) + conf->rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; + hw->rss_dis_flag = false; + rss_conf = conf->rx_adv_conf.rss_conf; +- if (rss_conf.rss_key == NULL) { +- rss_conf.rss_key = rss_cfg->key; +- rss_conf.rss_key_len = HNS3_RSS_KEY_SIZE; +- } +- + ret = hns3_dev_rss_hash_update(dev, &rss_conf); + if (ret) + goto cfg_err; +-- +2.7.4 + diff --git a/0019-net-hns3-encapsulate-DFX-stats-in-datapath.patch b/0019-net-hns3-encapsulate-DFX-stats-in-datapath.patch new file mode 100644 index 0000000..0cbec6e --- /dev/null +++ b/0019-net-hns3-encapsulate-DFX-stats-in-datapath.patch @@ -0,0 +1,704 @@ +From e5d1fe93d832492bd12a0a01c37d2e326d2701f4 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 22 Jan 2021 18:18:39 +0800 +Subject: [PATCH 019/189] net/hns3: encapsulate DFX stats in datapath + +pkt_len_errors and l2_errors in Rx datapath indicate that driver +needs to discard received packets. And driver does not discard +packets for l3/l4/ol3/ol4_csum_errors in Rx datapath and others +stats in Tx datapath. Therefore, it is necessary for improving +code readability and maintainability to encapsulate error stats +and dfx stats. + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_rxtx.c | 30 ++--- + drivers/net/hns3/hns3_rxtx.h | 134 ++++++++++--------- + drivers/net/hns3/hns3_rxtx_vec_neon.h | 2 +- + drivers/net/hns3/hns3_stats.c | 243 ++++++++++++++++++++++------------ + drivers/net/hns3/hns3_stats.h | 9 +- + 5 files changed, 251 insertions(+), 167 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 0badfc9..3d5f74f 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -1792,12 +1792,8 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + rxq->io_head_reg = (volatile void *)((char *)rxq->io_base + + HNS3_RING_RX_HEAD_REG); + rxq->rx_buf_len = rx_buf_size; +- rxq->l2_errors = 0; +- rxq->pkt_len_errors = 0; +- rxq->l3_csum_errors = 0; +- rxq->l4_csum_errors = 0; +- rxq->ol3_csum_errors = 0; +- rxq->ol4_csum_errors = 0; ++ memset(&rxq->err_stats, 0, sizeof(struct hns3_rx_bd_errors_stats)); ++ memset(&rxq->dfx_stats, 0, sizeof(struct hns3_rx_dfx_stats)); + + /* CRC len set here is used for amending packet length */ + if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC) +@@ -2622,12 +2618,8 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + HNS3_RING_TX_TAIL_REG); + txq->min_tx_pkt_len = hw->min_tx_pkt_len; + txq->tso_mode = hw->tso_mode; +- 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(&txq->dfx_stats, 0, sizeof(struct hns3_tx_dfx_stats)); ++ + rte_spinlock_lock(&hw->lock); + dev->data->tx_queues[idx] = txq; + rte_spinlock_unlock(&hw->lock); +@@ -3350,7 +3342,7 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id, + if (m->ol_flags & HNS3_TX_CKSUM_OFFLOAD_MASK) { + /* Fill in tunneling parameters if necessary */ + if (hns3_parse_tunneling_params(txq, m, tx_desc_id)) { +- txq->unsupported_tunnel_pkt_cnt++; ++ txq->dfx_stats.unsupported_tunnel_pkt_cnt++; + return -EINVAL; + } + +@@ -3380,17 +3372,17 @@ hns3_check_non_tso_pkt(uint16_t nb_buf, struct rte_mbuf **m_seg, + * driver support, the packet will be ignored. + */ + if (unlikely(rte_pktmbuf_pkt_len(tx_pkt) > HNS3_MAX_FRAME_LEN)) { +- txq->over_length_pkt_cnt++; ++ txq->dfx_stats.over_length_pkt_cnt++; + return -EINVAL; + } + + max_non_tso_bd_num = txq->max_non_tso_bd_num; + if (unlikely(nb_buf > max_non_tso_bd_num)) { +- txq->exceed_limit_bd_pkt_cnt++; ++ txq->dfx_stats.exceed_limit_bd_pkt_cnt++; + ret = hns3_reassemble_tx_pkts(tx_pkt, &new_pkt, + max_non_tso_bd_num); + if (ret) { +- txq->exceed_limit_bd_reassem_fail++; ++ txq->dfx_stats.exceed_limit_bd_reassem_fail++; + return ret; + } + *m_seg = new_pkt; +@@ -3528,7 +3520,7 @@ hns3_xmit_pkts_simple(void *tx_queue, + nb_pkts = RTE_MIN(txq->tx_bd_ready, nb_pkts); + if (unlikely(nb_pkts == 0)) { + if (txq->tx_bd_ready == 0) +- txq->queue_full_cnt++; ++ txq->dfx_stats.queue_full_cnt++; + return 0; + } + +@@ -3580,7 +3572,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++; ++ txq->dfx_stats.queue_full_cnt++; + if (nb_tx == 0) + return 0; + +@@ -3601,7 +3593,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) + rte_pktmbuf_pkt_len(tx_pkt); + appended = rte_pktmbuf_append(tx_pkt, add_len); + if (appended == NULL) { +- txq->pkt_padding_fail_cnt++; ++ txq->dfx_stats.pkt_padding_fail_cnt++; + break; + } + +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 6538848..8a0c981 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -266,6 +266,18 @@ struct hns3_entry { + struct rte_mbuf *mbuf; + }; + ++struct hns3_rx_dfx_stats { ++ uint64_t l3_csum_errors; ++ uint64_t l4_csum_errors; ++ uint64_t ol3_csum_errors; ++ uint64_t ol4_csum_errors; ++}; ++ ++struct hns3_rx_bd_errors_stats { ++ uint64_t l2_errors; ++ uint64_t pkt_len_errors; ++}; ++ + struct hns3_rx_queue { + void *io_base; + volatile void *io_head_reg; +@@ -312,12 +324,10 @@ struct hns3_rx_queue { + bool pvid_sw_discard_en; + bool enabled; /* indicate if Rx queue has been enabled */ + +- uint64_t l2_errors; +- uint64_t pkt_len_errors; +- uint64_t l3_csum_errors; +- uint64_t l4_csum_errors; +- uint64_t ol3_csum_errors; +- uint64_t ol4_csum_errors; ++ /* DFX statistics that driver does not need to discard packets */ ++ struct hns3_rx_dfx_stats dfx_stats; ++ /* Error statistics that driver needs to discard packets */ ++ struct hns3_rx_bd_errors_stats err_stats; + + struct rte_mbuf *bulk_mbuf[HNS3_BULK_ALLOC_MBUF_NUM]; + uint16_t bulk_mbuf_num; +@@ -328,6 +338,57 @@ struct hns3_rx_queue { + struct rte_mbuf fake_mbuf; /* fake mbuf used with vector rx */ + }; + ++/* ++ * 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 ++ * length(struct hns3_tx_queue::min_tx_pkt_len) supported by ++ * hardware in Tx direction and fail to be appended with 0. ++ */ ++struct hns3_tx_dfx_stats { ++ 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_tx_queue { + void *io_base; + volatile void *io_tail_reg; +@@ -411,54 +472,7 @@ struct hns3_tx_queue { + bool pvid_sw_shift_en; + bool enabled; /* indicate if Tx queue has been enabled */ + +- /* +- * 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 +- * length(struct hns3_tx_queue::min_tx_pkt_len) supported by +- * hardware in Tx direction 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_tx_dfx_stats dfx_stats; + }; + + #define HNS3_GET_TX_QUEUE_PEND_BD_NUM(txq) \ +@@ -511,9 +525,9 @@ hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm, + + if (unlikely((l234_info & L2E_TRUNC_ERR_FLAG) || rxm->pkt_len == 0)) { + if (l234_info & BIT(HNS3_RXD_L2E_B)) +- rxq->l2_errors++; ++ rxq->err_stats.l2_errors++; + else +- rxq->pkt_len_errors++; ++ rxq->err_stats.pkt_len_errors++; + return -EINVAL; + } + +@@ -525,24 +539,24 @@ hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm, + + if (unlikely(l234_info & BIT(HNS3_RXD_L3E_B))) { + rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD; +- rxq->l3_csum_errors++; ++ rxq->dfx_stats.l3_csum_errors++; + tmp |= HNS3_L3_CKSUM_ERR; + } + + if (unlikely(l234_info & BIT(HNS3_RXD_L4E_B))) { + rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD; +- rxq->l4_csum_errors++; ++ rxq->dfx_stats.l4_csum_errors++; + tmp |= HNS3_L4_CKSUM_ERR; + } + + if (unlikely(l234_info & BIT(HNS3_RXD_OL3E_B))) { +- rxq->ol3_csum_errors++; ++ rxq->dfx_stats.ol3_csum_errors++; + tmp |= HNS3_OUTER_L3_CKSUM_ERR; + } + + if (unlikely(l234_info & BIT(HNS3_RXD_OL4E_B))) { + rxm->ol_flags |= PKT_RX_OUTER_L4_CKSUM_BAD; +- rxq->ol4_csum_errors++; ++ rxq->dfx_stats.ol4_csum_errors++; + tmp |= HNS3_OUTER_L4_CKSUM_ERR; + } + } +diff --git a/drivers/net/hns3/hns3_rxtx_vec_neon.h b/drivers/net/hns3/hns3_rxtx_vec_neon.h +index 54addbf..a693b4b 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_neon.h ++++ b/drivers/net/hns3/hns3_rxtx_vec_neon.h +@@ -42,7 +42,7 @@ hns3_xmit_fixed_burst_vec(void *__restrict tx_queue, + + nb_commit = RTE_MIN(txq->tx_bd_ready, nb_pkts); + if (unlikely(nb_commit == 0)) { +- txq->queue_full_cnt++; ++ txq->dfx_stats.queue_full_cnt++; + return 0; + } + nb_tx = nb_commit; +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 62a712b..419d7e2 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -262,34 +262,38 @@ static const struct hns3_xstats_name_offset hns3_reset_stats_strings[] = { + + /* The statistic of errors in Rx BD */ + static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = { +- {"RX_PKT_LEN_ERRORS", ++ {"PKT_LEN_ERRORS", + HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(pkt_len_errors)}, +- {"L2_RX_ERRORS", +- HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l2_errors)}, +- {"RX_L3_CHECKSUM_ERRORS", +- HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l3_csum_errors)}, +- {"RX_L4_CHECKSUM_ERRORS", +- HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l4_csum_errors)}, +- {"RX_OL3_CHECKSUM_ERRORS", +- HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(ol3_csum_errors)}, +- {"RX_OL4_CHECKSUM_ERRORS", +- HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(ol4_csum_errors)} ++ {"L2_ERRORS", ++ HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(l2_errors)} + }; + +-/* 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 dfx statistic in Rx datapath */ ++static const struct hns3_xstats_name_offset hns3_rxq_dfx_stats_strings[] = { ++ {"L3_CHECKSUM_ERRORS", ++ HNS3_RXQ_DFX_STATS_FIELD_OFFSET(l3_csum_errors)}, ++ {"L4_CHECKSUM_ERRORS", ++ HNS3_RXQ_DFX_STATS_FIELD_OFFSET(l4_csum_errors)}, ++ {"OL3_CHECKSUM_ERRORS", ++ HNS3_RXQ_DFX_STATS_FIELD_OFFSET(ol3_csum_errors)}, ++ {"OL4_CHECKSUM_ERRORS", ++ HNS3_RXQ_DFX_STATS_FIELD_OFFSET(ol4_csum_errors)} ++}; ++ ++/* The dfx statistic in Tx datapath */ ++static const struct hns3_xstats_name_offset hns3_txq_dfx_stats_strings[] = { ++ {"OVER_LENGTH_PKT_CNT", ++ HNS3_TXQ_DFX_STATS_FIELD_OFFSET(over_length_pkt_cnt)}, ++ {"EXCEED_LIMITED_BD_PKT_CNT", ++ HNS3_TXQ_DFX_STATS_FIELD_OFFSET(exceed_limit_bd_pkt_cnt)}, ++ {"EXCEED_LIMITED_BD_PKT_REASSEMBLE_FAIL_CNT", ++ HNS3_TXQ_DFX_STATS_FIELD_OFFSET(exceed_limit_bd_reassem_fail)}, ++ {"UNSUPPORTED_TUNNEL_PKT_CNT", ++ HNS3_TXQ_DFX_STATS_FIELD_OFFSET(unsupported_tunnel_pkt_cnt)}, ++ {"QUEUE_FULL_CNT", ++ HNS3_TXQ_DFX_STATS_FIELD_OFFSET(queue_full_cnt)}, ++ {"SHORT_PKT_PAD_FAIL_CNT", ++ HNS3_TXQ_DFX_STATS_FIELD_OFFSET(pkt_padding_fail_cnt)} + }; + + /* The statistic of rx queue */ +@@ -314,8 +318,11 @@ 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_RXQ_DFX_XSTATS (sizeof(hns3_rxq_dfx_stats_strings) / \ ++ sizeof(hns3_rxq_dfx_stats_strings[0])) ++ ++#define HNS3_NUM_TXQ_DFX_XSTATS (sizeof(hns3_txq_dfx_stats_strings) / \ ++ sizeof(hns3_txq_dfx_stats_strings[0])) + + #define HNS3_NUM_RX_QUEUE_STATS (sizeof(hns3_rx_queue_strings) / \ + sizeof(hns3_rx_queue_strings[0])) +@@ -519,7 +526,8 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + for (i = 0; i != num; ++i) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq) { +- cnt = rxq->l2_errors + rxq->pkt_len_errors; ++ cnt = rxq->err_stats.l2_errors + ++ rxq->err_stats.pkt_len_errors; + rte_stats->q_errors[i] = cnt; + rte_stats->q_ipackets[i] = + stats->rcb_rx_ring_pktnum[i] - cnt; +@@ -584,11 +592,11 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + * Clear soft stats of rx error packet which will be dropped + * in driver. + */ +- for (i = 0; i < eth_dev->data->nb_rx_queues; ++i) { ++ for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq) { +- rxq->pkt_len_errors = 0; +- rxq->l2_errors = 0; ++ rxq->err_stats.pkt_len_errors = 0; ++ rxq->err_stats.l2_errors = 0; + } + } + +@@ -621,21 +629,24 @@ 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 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; ++ uint16_t nb_rx_q = dev->data->nb_rx_queues; ++ uint16_t nb_tx_q = dev->data->nb_tx_queues; ++ int bderr_stats = nb_rx_q * HNS3_NUM_RX_BD_ERROR_XSTATS; ++ int rx_dfx_stats = nb_rx_q * HNS3_NUM_RXQ_DFX_XSTATS; ++ int tx_dfx_stats = nb_tx_q * HNS3_NUM_TXQ_DFX_XSTATS; ++ int rx_queue_stats = nb_rx_q * HNS3_NUM_RX_QUEUE_STATS; ++ int tx_queue_stats = nb_tx_q * HNS3_NUM_TX_QUEUE_STATS; + + if (hns->is_vf) +- return bderr_stats + tx_err_stats + rx_queue_stats + +- tx_queue_stats + HNS3_NUM_RESET_XSTATS; ++ return bderr_stats + rx_dfx_stats + tx_dfx_stats + ++ rx_queue_stats + tx_queue_stats + HNS3_NUM_RESET_XSTATS; + else +- return bderr_stats + tx_err_stats + rx_queue_stats + +- tx_queue_stats + HNS3_FIX_NUM_STATS; ++ return bderr_stats + rx_dfx_stats + tx_dfx_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, ++hns3_queue_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + int *count) + { + struct hns3_adapter *hns = dev->data->dev_private; +@@ -683,6 +694,63 @@ hns3_error_int_stats_add(struct hns3_adapter *hns, const char *err) + } + } + ++static void ++hns3_rxq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, ++ int *count) ++{ ++ struct hns3_rx_dfx_stats *dfx_stats; ++ struct hns3_rx_queue *rxq; ++ uint16_t i, j; ++ char *val; ++ ++ for (i = 0; i < dev->data->nb_rx_queues; i++) { ++ rxq = (struct hns3_rx_queue *)dev->data->rx_queues[i]; ++ if (rxq == NULL) ++ continue; ++ ++ dfx_stats = &rxq->dfx_stats; ++ for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) { ++ val = (char *)dfx_stats + ++ hns3_rxq_dfx_stats_strings[j].offset; ++ xstats[*count].value = *(uint64_t *)val; ++ xstats[*count].id = *count; ++ (*count)++; ++ } ++ } ++} ++ ++static void ++hns3_txq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, ++ int *count) ++{ ++ struct hns3_tx_dfx_stats *dfx_stats; ++ struct hns3_tx_queue *txq; ++ uint16_t i, j; ++ char *val; ++ ++ for (i = 0; i < dev->data->nb_tx_queues; i++) { ++ txq = (struct hns3_tx_queue *)dev->data->tx_queues[i]; ++ if (txq == NULL) ++ continue; ++ ++ dfx_stats = &txq->dfx_stats; ++ for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) { ++ val = (char *)dfx_stats + ++ hns3_txq_dfx_stats_strings[j].offset; ++ xstats[*count].value = *(uint64_t *)val; ++ xstats[*count].id = *count; ++ (*count)++; ++ } ++ } ++} ++ ++static void ++hns3_tqp_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, ++ int *count) ++{ ++ hns3_rxq_dfx_stats_get(dev, xstats, count); ++ hns3_txq_dfx_stats_get(dev, xstats, count); ++} + /* + * Retrieve extended(tqp | Mac) statistics of an Ethernet device. + * @param dev +@@ -705,8 +773,8 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + 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_bd_errors_stats *rx_err_stats; + struct hns3_rx_queue *rxq; +- struct hns3_tx_queue *txq; + uint16_t i, j; + char *addr; + int count; +@@ -758,26 +826,49 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + 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; +- xstats[count].value = *(uint64_t *)addr; +- xstats[count].id = count; +- count++; ++ if (rxq) { ++ rx_err_stats = &rxq->err_stats; ++ addr = (char *)rx_err_stats + ++ hns3_rx_bd_error_strings[i].offset; ++ xstats[count].value = *(uint64_t *)addr; ++ xstats[count].id = count; ++ count++; ++ } + } + } + +- /* Get the Tx errors stats */ +- for (j = 0; j < dev->data->nb_tx_queues; j++) { +- 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_tqp_dfx_stats_get(dev, xstats, &count); ++ hns3_queue_stats_get(dev, xstats, &count); ++ ++ return count; ++} ++ ++static void ++hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev, ++ struct rte_eth_xstat_name *xstats_names, ++ uint32_t *count) ++{ ++ uint16_t i, j; ++ ++ for (j = 0; j < dev->data->nb_rx_queues; j++) { ++ for (i = 0; i < HNS3_NUM_RXQ_DFX_XSTATS; i++) { ++ snprintf(xstats_names[*count].name, ++ sizeof(xstats_names[*count].name), ++ "rx_q%u_%s", j, ++ hns3_rxq_dfx_stats_strings[i].name); ++ (*count)++; + } + } + +- hns3_get_queue_stats(dev, xstats, &count); +- return count; ++ for (j = 0; j < dev->data->nb_tx_queues; j++) { ++ for (i = 0; i < HNS3_NUM_TXQ_DFX_XSTATS; i++) { ++ snprintf(xstats_names[*count].name, ++ sizeof(xstats_names[*count].name), ++ "tx_q%u_%s", j, ++ hns3_txq_dfx_stats_strings[i].name); ++ (*count)++; ++ } ++ } + } + + /* +@@ -845,27 +936,19 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev, + for (i = 0; i < HNS3_NUM_RX_BD_ERROR_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), +- "rx_q%u%s", j, ++ "rx_q%u_%s", j, + hns3_rx_bd_error_strings[i].name); + count++; + } + } + +- 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++; +- } +- } ++ hns3_tqp_dfx_stats_name_get(dev, xstats_names, &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, + sizeof(xstats_names[count].name), +- "rx_q%u%s", j, hns3_rx_queue_strings[i].name); ++ "rx_q%u_%s", j, hns3_rx_queue_strings[i].name); + count++; + } + } +@@ -874,7 +957,7 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev, + 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); ++ "tx_q%u_%s", j, hns3_tx_queue_strings[i].name); + count++; + } + } +@@ -1043,30 +1126,22 @@ hns3_tqp_dfx_stats_clear(struct rte_eth_dev *dev) + { + struct hns3_rx_queue *rxq; + struct hns3_tx_queue *txq; +- int i; ++ uint16_t i; + + /* Clear Rx dfx stats */ +- for (i = 0; i < dev->data->nb_rx_queues; ++i) { ++ for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq = dev->data->rx_queues[i]; +- if (rxq) { +- rxq->l3_csum_errors = 0; +- rxq->l4_csum_errors = 0; +- rxq->ol3_csum_errors = 0; +- rxq->ol4_csum_errors = 0; +- } ++ if (rxq) ++ memset(&rxq->dfx_stats, 0, ++ sizeof(struct hns3_rx_dfx_stats)); + } + + /* Clear Tx dfx stats */ +- for (i = 0; i < dev->data->nb_tx_queues; ++i) { ++ for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = 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; +- } ++ if (txq) ++ memset(&txq->dfx_stats, 0, ++ sizeof(struct hns3_tx_dfx_stats)); + } + } + +diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h +index 9fcd5f9..12842cd 100644 +--- a/drivers/net/hns3/hns3_stats.h ++++ b/drivers/net/hns3/hns3_stats.h +@@ -127,10 +127,13 @@ struct hns3_reset_stats; + (offsetof(struct hns3_reset_stats, f)) + + #define HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(f) \ +- (offsetof(struct hns3_rx_queue, f)) ++ (offsetof(struct hns3_rx_bd_errors_stats, f)) + +-#define HNS3_TX_ERROR_STATS_FIELD_OFFSET(f) \ +- (offsetof(struct hns3_tx_queue, f)) ++#define HNS3_RXQ_DFX_STATS_FIELD_OFFSET(f) \ ++ (offsetof(struct hns3_rx_dfx_stats, f)) ++ ++#define HNS3_TXQ_DFX_STATS_FIELD_OFFSET(f) \ ++ (offsetof(struct hns3_tx_dfx_stats, f)) + + 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, +-- +2.7.4 + diff --git a/0020-net-hns3-move-queue-stats-to-xstats.patch b/0020-net-hns3-move-queue-stats-to-xstats.patch new file mode 100644 index 0000000..0f24454 --- /dev/null +++ b/0020-net-hns3-move-queue-stats-to-xstats.patch @@ -0,0 +1,505 @@ +From e658ac6ea47f304cb8b0c9e8e100dd1016bcac0b Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Fri, 22 Jan 2021 18:18:40 +0800 +Subject: [PATCH 020/189] net/hns3: move queue stats to xstats + +One of the hot discussions in community recently was moving queue stats +to xstats. In this solution, a temporary +'RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS' device flag is created to implement +the smooth switch. And the first half of this work has been completed in +the ethdev framework. Now driver needs to remove the flag from the +driver initialization process and does the rest of work. + +For better readability and reasonability, per-queue stats also should be +cleared when rte_eth_stats is cleared. Otherwise, the sum of one item in +per-queue stats may be greater than corresponding item in rte_eth_stats. + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 2 - + drivers/net/hns3/hns3_ethdev_vf.c | 2 - + drivers/net/hns3/hns3_rxtx.c | 2 + + drivers/net/hns3/hns3_rxtx.h | 13 ++ + drivers/net/hns3/hns3_stats.c | 241 +++++++++++++++++++++++++++++++------- + drivers/net/hns3/hns3_stats.h | 6 + + 6 files changed, 221 insertions(+), 45 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 449d967..7c51e83 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6148,8 +6148,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + return 0; + } + +- eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; +- + ret = hns3_mp_init_primary(); + if (ret) { + PMD_INIT_LOG(ERR, +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index bb4ec6b..37135d7 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2746,8 +2746,6 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) + return 0; + } + +- eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; +- + ret = hns3_mp_init_primary(); + if (ret) { + PMD_INIT_LOG(ERR, +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 3d5f74f..30f1e06 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -1792,6 +1792,7 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + rxq->io_head_reg = (volatile void *)((char *)rxq->io_base + + HNS3_RING_RX_HEAD_REG); + rxq->rx_buf_len = rx_buf_size; ++ memset(&rxq->basic_stats, 0, sizeof(struct hns3_rx_basic_stats)); + memset(&rxq->err_stats, 0, sizeof(struct hns3_rx_bd_errors_stats)); + memset(&rxq->dfx_stats, 0, sizeof(struct hns3_rx_dfx_stats)); + +@@ -2618,6 +2619,7 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + HNS3_RING_TX_TAIL_REG); + txq->min_tx_pkt_len = hw->min_tx_pkt_len; + txq->tso_mode = hw->tso_mode; ++ memset(&txq->basic_stats, 0, sizeof(struct hns3_tx_basic_stats)); + memset(&txq->dfx_stats, 0, sizeof(struct hns3_tx_dfx_stats)); + + rte_spinlock_lock(&hw->lock); +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 8a0c981..331b507 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -266,6 +266,12 @@ struct hns3_entry { + struct rte_mbuf *mbuf; + }; + ++struct hns3_rx_basic_stats { ++ uint64_t packets; ++ uint64_t bytes; ++ uint64_t errors; ++}; ++ + struct hns3_rx_dfx_stats { + uint64_t l3_csum_errors; + uint64_t l4_csum_errors; +@@ -324,6 +330,7 @@ struct hns3_rx_queue { + bool pvid_sw_discard_en; + bool enabled; /* indicate if Rx queue has been enabled */ + ++ struct hns3_rx_basic_stats basic_stats; + /* DFX statistics that driver does not need to discard packets */ + struct hns3_rx_dfx_stats dfx_stats; + /* Error statistics that driver needs to discard packets */ +@@ -338,6 +345,11 @@ struct hns3_rx_queue { + struct rte_mbuf fake_mbuf; /* fake mbuf used with vector rx */ + }; + ++struct hns3_tx_basic_stats { ++ uint64_t packets; ++ uint64_t bytes; ++}; ++ + /* + * The following items are used for the abnormal errors statistics in + * the Tx datapath. When upper level application calls the +@@ -472,6 +484,7 @@ struct hns3_tx_queue { + bool pvid_sw_shift_en; + bool enabled; /* indicate if Tx queue has been enabled */ + ++ struct hns3_tx_basic_stats basic_stats; + struct hns3_tx_dfx_stats dfx_stats; + }; + +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 419d7e2..3ba09e2 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -11,6 +11,24 @@ + #include "hns3_logs.h" + #include "hns3_regs.h" + ++/* The statistics of the per-rxq basic stats */ ++static const struct hns3_xstats_name_offset hns3_rxq_basic_stats_strings[] = { ++ {"packets", ++ HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(packets)}, ++ {"bytes", ++ HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(bytes)}, ++ {"errors", ++ HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(errors)} ++}; ++ ++/* The statistics of the per-txq basic stats */ ++static const struct hns3_xstats_name_offset hns3_txq_basic_stats_strings[] = { ++ {"packets", ++ HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(packets)}, ++ {"bytes", ++ HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(bytes)} ++}; ++ + /* MAC statistics */ + static const struct hns3_xstats_name_offset hns3_mac_strings[] = { + {"mac_tx_mac_pause_num", +@@ -330,6 +348,12 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = { + #define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \ + sizeof(hns3_tx_queue_strings[0])) + ++#define HNS3_NUM_RXQ_BASIC_STATS (sizeof(hns3_rxq_basic_stats_strings) / \ ++ sizeof(hns3_rxq_basic_stats_strings[0])) ++ ++#define HNS3_NUM_TXQ_BASIC_STATS (sizeof(hns3_txq_basic_stats_strings) / \ ++ sizeof(hns3_txq_basic_stats_strings[0])) ++ + #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \ + HNS3_NUM_RESET_XSTATS) + +@@ -508,9 +532,7 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + struct hns3_hw *hw = &hns->hw; + struct hns3_tqp_stats *stats = &hw->tqp_stats; + struct hns3_rx_queue *rxq; +- struct hns3_tx_queue *txq; + uint64_t cnt; +- uint64_t num; + uint16_t i; + int ret; + +@@ -522,25 +544,14 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + } + + /* Get the error stats of received packets */ +- num = RTE_MIN(RTE_ETHDEV_QUEUE_STAT_CNTRS, eth_dev->data->nb_rx_queues); +- for (i = 0; i != num; ++i) { ++ for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq) { + cnt = rxq->err_stats.l2_errors + + rxq->err_stats.pkt_len_errors; +- rte_stats->q_errors[i] = cnt; +- rte_stats->q_ipackets[i] = +- stats->rcb_rx_ring_pktnum[i] - cnt; + rte_stats->ierrors += cnt; + } + } +- /* Get the error stats of transmitted packets */ +- num = RTE_MIN(RTE_ETHDEV_QUEUE_STAT_CNTRS, eth_dev->data->nb_tx_queues); +- for (i = 0; i < num; i++) { +- txq = eth_dev->data->tx_queues[i]; +- if (txq) +- rte_stats->q_opackets[i] = stats->rcb_tx_ring_pktnum[i]; +- } + + rte_stats->oerrors = 0; + rte_stats->ipackets = stats->rcb_rx_ring_pktnum_rcd - +@@ -600,6 +611,11 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + } + } + ++ /* ++ * 'packets' in hns3_tx_basic_stats and hns3_rx_basic_stats come ++ * from hw->tqp_stats. And clearing tqp stats is like clearing ++ * their source. ++ */ + hns3_tqp_stats_clear(hw); + + return 0; +@@ -628,21 +644,26 @@ hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev) + static int + hns3_xstats_calc_num(struct rte_eth_dev *dev) + { ++#define HNS3_PF_VF_RX_COMM_STATS_NUM (HNS3_NUM_RX_BD_ERROR_XSTATS + \ ++ HNS3_NUM_RXQ_DFX_XSTATS + \ ++ HNS3_NUM_RX_QUEUE_STATS + \ ++ HNS3_NUM_RXQ_BASIC_STATS) ++#define HNS3_PF_VF_TX_COMM_STATS_NUM (HNS3_NUM_TXQ_DFX_XSTATS + \ ++ HNS3_NUM_TX_QUEUE_STATS + \ ++ HNS3_NUM_TXQ_BASIC_STATS) ++ + struct hns3_adapter *hns = dev->data->dev_private; + uint16_t nb_rx_q = dev->data->nb_rx_queues; + uint16_t nb_tx_q = dev->data->nb_tx_queues; +- int bderr_stats = nb_rx_q * HNS3_NUM_RX_BD_ERROR_XSTATS; +- int rx_dfx_stats = nb_rx_q * HNS3_NUM_RXQ_DFX_XSTATS; +- int tx_dfx_stats = nb_tx_q * HNS3_NUM_TXQ_DFX_XSTATS; +- int rx_queue_stats = nb_rx_q * HNS3_NUM_RX_QUEUE_STATS; +- int tx_queue_stats = nb_tx_q * HNS3_NUM_TX_QUEUE_STATS; ++ int rx_comm_stats_num = nb_rx_q * HNS3_PF_VF_RX_COMM_STATS_NUM; ++ int tx_comm_stats_num = nb_tx_q * HNS3_PF_VF_TX_COMM_STATS_NUM; + + if (hns->is_vf) +- return bderr_stats + rx_dfx_stats + tx_dfx_stats + +- rx_queue_stats + tx_queue_stats + HNS3_NUM_RESET_XSTATS; ++ return rx_comm_stats_num + tx_comm_stats_num + ++ HNS3_NUM_RESET_XSTATS; + else +- return bderr_stats + rx_dfx_stats + tx_dfx_stats + +- rx_queue_stats + tx_queue_stats + HNS3_FIX_NUM_STATS; ++ return rx_comm_stats_num + tx_comm_stats_num + ++ HNS3_FIX_NUM_STATS; + } + + static void +@@ -751,6 +772,118 @@ hns3_tqp_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + hns3_rxq_dfx_stats_get(dev, xstats, count); + hns3_txq_dfx_stats_get(dev, xstats, count); + } ++ ++static void ++hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, ++ int *count) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_tqp_stats *stats = &hw->tqp_stats; ++ struct hns3_rx_basic_stats *rxq_stats; ++ struct hns3_rx_queue *rxq; ++ uint16_t i, j; ++ char *val; ++ ++ for (i = 0; i < dev->data->nb_rx_queues; i++) { ++ rxq = dev->data->rx_queues[i]; ++ if (rxq == NULL) ++ continue; ++ ++ rxq_stats = &rxq->basic_stats; ++ rxq_stats->errors = rxq->err_stats.l2_errors + ++ rxq->err_stats.pkt_len_errors; ++ rxq_stats->packets = stats->rcb_rx_ring_pktnum[i] - ++ rxq_stats->errors; ++ rxq_stats->bytes = 0; ++ for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) { ++ val = (char *)rxq_stats + ++ hns3_rxq_basic_stats_strings[j].offset; ++ xstats[*count].value = *(uint64_t *)val; ++ xstats[*count].id = *count; ++ (*count)++; ++ } ++ } ++} ++ ++static void ++hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, ++ int *count) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_tqp_stats *stats = &hw->tqp_stats; ++ struct hns3_tx_basic_stats *txq_stats; ++ struct hns3_tx_queue *txq; ++ uint16_t i, j; ++ char *val; ++ ++ for (i = 0; i < dev->data->nb_tx_queues; i++) { ++ txq = dev->data->tx_queues[i]; ++ if (txq == NULL) ++ continue; ++ ++ txq_stats = &txq->basic_stats; ++ txq_stats->packets = stats->rcb_tx_ring_pktnum[i]; ++ txq_stats->bytes = 0; ++ for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) { ++ val = (char *)txq_stats + ++ hns3_txq_basic_stats_strings[j].offset; ++ xstats[*count].value = *(uint64_t *)val; ++ xstats[*count].id = *count; ++ (*count)++; ++ } ++ } ++} ++ ++static int ++hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, ++ int *count) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ /* Update tqp stats by read register */ ++ ret = hns3_update_tqp_stats(hw); ++ if (ret) { ++ hns3_err(hw, "Update tqp stats fail, ret = %d.", ret); ++ return ret; ++ } ++ ++ hns3_rxq_basic_stats_get(dev, xstats, count); ++ hns3_txq_basic_stats_get(dev, xstats, count); ++ ++ return 0; ++} ++ ++/* ++ * The function is only called by hns3_dev_xstats_reset to clear ++ * basic stats of per-queue. TQP stats are all cleared in hns3_stats_reset ++ * which is called before this function. ++ * ++ * @param dev ++ * Pointer to Ethernet device. ++ */ ++static void ++hns3_tqp_basic_stats_clear(struct rte_eth_dev *dev) ++{ ++ struct hns3_tx_queue *txq; ++ struct hns3_rx_queue *rxq; ++ uint16_t i; ++ ++ for (i = 0; i < dev->data->nb_rx_queues; i++) { ++ rxq = dev->data->rx_queues[i]; ++ if (rxq) ++ memset(&rxq->basic_stats, 0, ++ sizeof(struct hns3_rx_basic_stats)); ++ } ++ ++ for (i = 0; i < dev->data->nb_tx_queues; i++) { ++ txq = dev->data->tx_queues[i]; ++ if (txq) ++ memset(&txq->basic_stats, 0, ++ sizeof(struct hns3_tx_basic_stats)); ++ } ++} ++ + /* + * Retrieve extended(tqp | Mac) statistics of an Ethernet device. + * @param dev +@@ -789,6 +922,10 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + + count = 0; + ++ ret = hns3_tqp_basic_stats_get(dev, xstats, &count); ++ if (ret < 0) ++ return ret; ++ + if (!hns->is_vf) { + /* Update Mac stats */ + ret = hns3_query_update_mac_stats(dev); +@@ -844,28 +981,55 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + } + + static void ++hns3_tqp_basic_stats_name_get(struct rte_eth_dev *dev, ++ struct rte_eth_xstat_name *xstats_names, ++ uint32_t *count) ++{ ++ uint16_t i, j; ++ ++ for (i = 0; i < dev->data->nb_rx_queues; i++) { ++ for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) { ++ snprintf(xstats_names[*count].name, ++ sizeof(xstats_names[*count].name), ++ "rx_q%u_%s", i, ++ hns3_rxq_basic_stats_strings[j].name); ++ (*count)++; ++ } ++ } ++ for (i = 0; i < dev->data->nb_tx_queues; i++) { ++ for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) { ++ snprintf(xstats_names[*count].name, ++ sizeof(xstats_names[*count].name), ++ "tx_q%u_%s", i, ++ hns3_txq_basic_stats_strings[j].name); ++ (*count)++; ++ } ++ } ++} ++ ++static void + hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + uint32_t *count) + { + uint16_t i, j; + +- for (j = 0; j < dev->data->nb_rx_queues; j++) { +- for (i = 0; i < HNS3_NUM_RXQ_DFX_XSTATS; i++) { ++ for (i = 0; i < dev->data->nb_rx_queues; i++) { ++ for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) { + snprintf(xstats_names[*count].name, + sizeof(xstats_names[*count].name), +- "rx_q%u_%s", j, +- hns3_rxq_dfx_stats_strings[i].name); ++ "rx_q%u_%s", i, ++ hns3_rxq_dfx_stats_strings[j].name); + (*count)++; + } + } + +- for (j = 0; j < dev->data->nb_tx_queues; j++) { +- for (i = 0; i < HNS3_NUM_TXQ_DFX_XSTATS; i++) { ++ for (i = 0; i < dev->data->nb_tx_queues; i++) { ++ for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) { + snprintf(xstats_names[*count].name, + sizeof(xstats_names[*count].name), +- "tx_q%u_%s", j, +- hns3_txq_dfx_stats_strings[i].name); ++ "tx_q%u_%s", i, ++ hns3_txq_dfx_stats_strings[j].name); + (*count)++; + } + } +@@ -908,6 +1072,8 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev, + if (xstats_names == NULL) + return cnt_stats; + ++ hns3_tqp_basic_stats_name_get(dev, xstats_names, &count); ++ + /* Note: size limited checked in rte_eth_xstats_get_names() */ + if (!hns->is_vf) { + /* Get MAC name from hw->hw_xstats.mac_stats struct */ +@@ -999,7 +1165,6 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + uint32_t count_value; + uint64_t len; + uint32_t i; +- int ret; + + if (ids == NULL && values == NULL) + return cnt_stats; +@@ -1008,13 +1173,6 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + if (size < cnt_stats) + return cnt_stats; + +- /* Update tqp stats by read register */ +- ret = hns3_update_tqp_stats(hw); +- if (ret) { +- hns3_err(hw, "Update tqp stats fail : %d", ret); +- return ret; +- } +- + len = cnt_stats * sizeof(struct rte_eth_xstat); + values_copy = rte_zmalloc("hns3_xstats_values", len, 0); + if (values_copy == NULL) { +@@ -1157,11 +1315,12 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) + if (ret) + return ret; + ++ hns3_tqp_basic_stats_clear(dev); ++ hns3_tqp_dfx_stats_clear(dev); ++ + /* Clear reset stats */ + memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats)); + +- hns3_tqp_dfx_stats_clear(dev); +- + if (hns->is_vf) + return 0; + +diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h +index 12842cd..d213be5 100644 +--- a/drivers/net/hns3/hns3_stats.h ++++ b/drivers/net/hns3/hns3_stats.h +@@ -135,6 +135,12 @@ struct hns3_reset_stats; + #define HNS3_TXQ_DFX_STATS_FIELD_OFFSET(f) \ + (offsetof(struct hns3_tx_dfx_stats, f)) + ++#define HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(f) \ ++ (offsetof(struct hns3_rx_basic_stats, f)) ++ ++#define HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(f) \ ++ (offsetof(struct hns3_tx_basic_stats, f)) ++ + 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); +-- +2.7.4 + diff --git a/0021-net-hns3-refactor-converting-descriptor-error.patch b/0021-net-hns3-refactor-converting-descriptor-error.patch new file mode 100644 index 0000000..f5693b4 --- /dev/null +++ b/0021-net-hns3-refactor-converting-descriptor-error.patch @@ -0,0 +1,97 @@ +From 17327e444434b1062063a03060d6cc5a1876aa3f Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:41 +0800 +Subject: [PATCH 021/189] net/hns3: refactor converting descriptor error + +Use errno array instead of switch-case for refactor +the hns3_cmd_convert_err_code function. + +Besides, we add a type for ROH(RDMA Over HCCS) check +cmdq return error in Kunpeng930 NIC hardware. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.c | 54 ++++++++++++++++++++++----------------------- + drivers/net/hns3/hns3_cmd.h | 1 + + 2 files changed, 27 insertions(+), 28 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index f58f4f7..4c301cb 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -247,34 +247,32 @@ hns3_is_special_opcode(uint16_t opcode) + static int + hns3_cmd_convert_err_code(uint16_t desc_ret) + { +- switch (desc_ret) { +- case HNS3_CMD_EXEC_SUCCESS: +- return 0; +- case HNS3_CMD_NO_AUTH: +- return -EPERM; +- case HNS3_CMD_NOT_SUPPORTED: +- return -EOPNOTSUPP; +- case HNS3_CMD_QUEUE_FULL: +- return -EXFULL; +- case HNS3_CMD_NEXT_ERR: +- return -ENOSR; +- case HNS3_CMD_UNEXE_ERR: +- return -ENOTBLK; +- case HNS3_CMD_PARA_ERR: +- return -EINVAL; +- case HNS3_CMD_RESULT_ERR: +- return -ERANGE; +- case HNS3_CMD_TIMEOUT: +- return -ETIME; +- case HNS3_CMD_HILINK_ERR: +- return -ENOLINK; +- case HNS3_CMD_QUEUE_ILLEGAL: +- return -ENXIO; +- case HNS3_CMD_INVALID: +- return -EBADR; +- default: +- return -EREMOTEIO; +- } ++ static const struct { ++ uint16_t imp_errcode; ++ int linux_errcode; ++ } hns3_cmdq_status[] = { ++ {HNS3_CMD_EXEC_SUCCESS, 0}, ++ {HNS3_CMD_NO_AUTH, -EPERM}, ++ {HNS3_CMD_NOT_SUPPORTED, -EOPNOTSUPP}, ++ {HNS3_CMD_QUEUE_FULL, -EXFULL}, ++ {HNS3_CMD_NEXT_ERR, -ENOSR}, ++ {HNS3_CMD_UNEXE_ERR, -ENOTBLK}, ++ {HNS3_CMD_PARA_ERR, -EINVAL}, ++ {HNS3_CMD_RESULT_ERR, -ERANGE}, ++ {HNS3_CMD_TIMEOUT, -ETIME}, ++ {HNS3_CMD_HILINK_ERR, -ENOLINK}, ++ {HNS3_CMD_QUEUE_ILLEGAL, -ENXIO}, ++ {HNS3_CMD_INVALID, -EBADR}, ++ {HNS3_CMD_ROH_CHECK_FAIL, -EINVAL} ++ }; ++ ++ uint32_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(hns3_cmdq_status); i++) ++ if (hns3_cmdq_status[i].imp_errcode == desc_ret) ++ return hns3_cmdq_status[i].linux_errcode; ++ ++ return -EREMOTEIO; + } + + static int +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index e40293b..6152f6e 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -52,6 +52,7 @@ enum hns3_cmd_return_status { + HNS3_CMD_HILINK_ERR = 9, + HNS3_CMD_QUEUE_ILLEGAL = 10, + HNS3_CMD_INVALID = 11, ++ HNS3_CMD_ROH_CHECK_FAIL = 12 + }; + + enum hns3_cmd_status { +-- +2.7.4 + diff --git a/0022-net-hns3-refactor-flow-checks-into-own-functions.patch b/0022-net-hns3-refactor-flow-checks-into-own-functions.patch new file mode 100644 index 0000000..7b041c6 --- /dev/null +++ b/0022-net-hns3-refactor-flow-checks-into-own-functions.patch @@ -0,0 +1,134 @@ +From 2d64078bc27c055bfeb486230ea64eebe1cb65cb Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:42 +0800 +Subject: [PATCH 022/189] net/hns3: refactor flow checks into own functions + +Here moves some judgement conditions to a separated function +for parsing IPv4 hdr and TCP hdr in hns3_parse_normal function. +Also, move the check of the selected input tuple of RSS to a +separated functions named hns3_rss_input_tuple_supported +in order to enhance scalability and complexity. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 69 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 48 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index f303df4..889fa2f 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -525,6 +525,17 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + return 0; + } + ++static bool ++hns3_check_ipv4_mask_supported(const struct rte_flow_item_ipv4 *ipv4_mask) ++{ ++ if (ipv4_mask->hdr.total_length || ipv4_mask->hdr.packet_id || ++ ipv4_mask->hdr.fragment_offset || ipv4_mask->hdr.time_to_live || ++ ipv4_mask->hdr.hdr_checksum) ++ return false; ++ ++ return true; ++} ++ + static int + hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + struct rte_flow_error *error) +@@ -546,11 +557,7 @@ hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + + if (item->mask) { + ipv4_mask = item->mask; +- if (ipv4_mask->hdr.total_length || +- ipv4_mask->hdr.packet_id || +- ipv4_mask->hdr.fragment_offset || +- ipv4_mask->hdr.time_to_live || +- ipv4_mask->hdr.hdr_checksum) { ++ if (!hns3_check_ipv4_mask_supported(ipv4_mask)) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, + item, +@@ -648,6 +655,18 @@ hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + return 0; + } + ++static bool ++hns3_check_tcp_mask_supported(const struct rte_flow_item_tcp *tcp_mask) ++{ ++ if (tcp_mask->hdr.sent_seq || tcp_mask->hdr.recv_ack || ++ tcp_mask->hdr.data_off || tcp_mask->hdr.tcp_flags || ++ tcp_mask->hdr.rx_win || tcp_mask->hdr.cksum || ++ tcp_mask->hdr.tcp_urp) ++ return false; ++ ++ return true; ++} ++ + static int + hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + struct rte_flow_error *error) +@@ -670,10 +689,7 @@ hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + + if (item->mask) { + tcp_mask = item->mask; +- if (tcp_mask->hdr.sent_seq || tcp_mask->hdr.recv_ack || +- tcp_mask->hdr.data_off || tcp_mask->hdr.tcp_flags || +- tcp_mask->hdr.rx_win || tcp_mask->hdr.cksum || +- tcp_mask->hdr.tcp_urp) { ++ if (!hns3_check_tcp_mask_supported(tcp_mask)) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, + item, +@@ -1328,6 +1344,28 @@ hns3_rss_conf_copy(struct hns3_rss_conf *out, + return 0; + } + ++static bool ++hns3_rss_input_tuple_supported(struct hns3_hw *hw, ++ const struct rte_flow_action_rss *rss) ++{ ++ /* ++ * For IP packet, it is not supported to use src/dst port fields to RSS ++ * hash for the following packet types. ++ * - IPV4 FRAG | IPV4 NONFRAG | IPV6 FRAG | IPV6 NONFRAG ++ * Besides, for Kunpeng920, the NIC HW is not supported to use src/dst ++ * port fields to RSS hash for IPV6 SCTP packet type. However, the ++ * Kunpeng930 and future kunpeng series support to use src/dst port ++ * fields to RSS hash for IPv6 SCTP packet type. ++ */ ++ if (rss->types & (ETH_RSS_L4_DST_ONLY | ETH_RSS_L4_SRC_ONLY) && ++ (rss->types & ETH_RSS_IP || ++ (!hw->rss_info.ipv6_sctp_offload_supported && ++ rss->types & ETH_RSS_NONFRAG_IPV6_SCTP))) ++ return false; ++ ++ return true; ++} ++ + /* + * This function is used to parse rss action validatation. + */ +@@ -1386,18 +1424,7 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, + "RSS hash key must be exactly 40 bytes"); + +- /* +- * For Kunpeng920 and Kunpeng930 NIC hardware, it is not supported to +- * use dst port/src port fields to RSS hash for the following packet +- * types. +- * - IPV4 FRAG | IPV4 NONFRAG | IPV6 FRAG | IPV6 NONFRAG +- * Besides, for Kunpeng920, The NIC hardware is not supported to use +- * src/dst port fields to RSS hash for IPV6 SCTP packet type. +- */ +- if (rss->types & (ETH_RSS_L4_DST_ONLY | ETH_RSS_L4_SRC_ONLY) && +- (rss->types & ETH_RSS_IP || +- (!hw->rss_info.ipv6_sctp_offload_supported && +- rss->types & ETH_RSS_NONFRAG_IPV6_SCTP))) ++ if (!hns3_rss_input_tuple_supported(hw, rss)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + &rss->types, +-- +2.7.4 + diff --git a/0023-net-hns3-reconstruct-Rx-interrupt-map.patch b/0023-net-hns3-reconstruct-Rx-interrupt-map.patch new file mode 100644 index 0000000..e7850d9 --- /dev/null +++ b/0023-net-hns3-reconstruct-Rx-interrupt-map.patch @@ -0,0 +1,190 @@ +From badcc5f38dcf223578f870574653fdd20e00c6f8 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Fri, 22 Jan 2021 18:18:43 +0800 +Subject: [PATCH 023/189] net/hns3: reconstruct Rx interrupt map + +This patch reconstruct the Rx interrupt map to reduce the cyclic +complexity and improve readability and maintainability. + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 59 +++++++++++++++++++-------------------- + drivers/net/hns3/hns3_ethdev_vf.c | 55 ++++++++++++++++++------------------ + 2 files changed, 56 insertions(+), 58 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7c51e83..f3ce639 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4782,27 +4782,28 @@ hns3_map_rx_interrupt(struct rte_eth_dev *dev) + uint16_t q_id; + int ret; + +- if (dev->data->dev_conf.intr_conf.rxq == 0) ++ /* ++ * hns3 needs a separate interrupt to be used as event interrupt which ++ * could not be shared with task queue pair, so KERNEL drivers need ++ * support multiple interrupt vectors. ++ */ ++ if (dev->data->dev_conf.intr_conf.rxq == 0 || ++ !rte_intr_cap_multiple(intr_handle)) + return 0; + +- /* disable uio/vfio intr/eventfd mapping */ + rte_intr_disable(intr_handle); ++ intr_vector = hw->used_rx_queues; ++ /* creates event fd for each intr vector when MSIX is used */ ++ if (rte_intr_efd_enable(intr_handle, intr_vector)) ++ return -EINVAL; + +- /* check and configure queue intr-vector mapping */ +- if (rte_intr_cap_multiple(intr_handle) || +- !RTE_ETH_DEV_SRIOV(dev).active) { +- intr_vector = hw->used_rx_queues; +- /* creates event fd for each intr vector when MSIX is used */ +- if (rte_intr_efd_enable(intr_handle, intr_vector)) +- return -EINVAL; +- } +- if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { ++ if (intr_handle->intr_vec == NULL) { + intr_handle->intr_vec = + rte_zmalloc("intr_vec", + hw->used_rx_queues * sizeof(int), 0); + if (intr_handle->intr_vec == NULL) { +- hns3_err(hw, "Failed to allocate %u rx_queues" +- " intr_vec", hw->used_rx_queues); ++ hns3_err(hw, "failed to allocate %u rx_queues intr_vec", ++ hw->used_rx_queues); + ret = -ENOMEM; + goto alloc_intr_vec_error; + } +@@ -4812,28 +4813,26 @@ hns3_map_rx_interrupt(struct rte_eth_dev *dev) + vec = RTE_INTR_VEC_RXTX_OFFSET; + base = RTE_INTR_VEC_RXTX_OFFSET; + } +- if (rte_intr_dp_is_en(intr_handle)) { +- for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { +- ret = hns3_bind_ring_with_vector(hw, vec, true, +- HNS3_RING_TYPE_RX, +- q_id); +- if (ret) +- goto bind_vector_error; +- intr_handle->intr_vec[q_id] = vec; +- if (vec < base + intr_handle->nb_efd - 1) +- vec++; +- } ++ ++ for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { ++ ret = hns3_bind_ring_with_vector(hw, vec, true, ++ HNS3_RING_TYPE_RX, q_id); ++ if (ret) ++ goto bind_vector_error; ++ intr_handle->intr_vec[q_id] = vec; ++ /* ++ * If there are not enough efds (e.g. not enough interrupt), ++ * remaining queues will be bond to the last interrupt. ++ */ ++ if (vec < base + intr_handle->nb_efd - 1) ++ vec++; + } + rte_intr_enable(intr_handle); + return 0; + + bind_vector_error: +- rte_intr_efd_disable(intr_handle); +- if (intr_handle->intr_vec) { +- free(intr_handle->intr_vec); +- intr_handle->intr_vec = NULL; +- } +- return ret; ++ rte_free(intr_handle->intr_vec); ++ intr_handle->intr_vec = NULL; + alloc_intr_vec_error: + rte_intr_efd_disable(intr_handle); + return ret; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 37135d7..3a1d4cb 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2085,21 +2085,22 @@ hns3vf_map_rx_interrupt(struct rte_eth_dev *dev) + uint16_t q_id; + int ret; + +- if (dev->data->dev_conf.intr_conf.rxq == 0) ++ /* ++ * hns3 needs a separate interrupt to be used as event interrupt which ++ * could not be shared with task queue pair, so KERNEL drivers need ++ * support multiple interrupt vectors. ++ */ ++ if (dev->data->dev_conf.intr_conf.rxq == 0 || ++ !rte_intr_cap_multiple(intr_handle)) + return 0; + +- /* disable uio/vfio intr/eventfd mapping */ + rte_intr_disable(intr_handle); ++ intr_vector = hw->used_rx_queues; ++ /* It creates event fd for each intr vector when MSIX is used */ ++ if (rte_intr_efd_enable(intr_handle, intr_vector)) ++ return -EINVAL; + +- /* check and configure queue intr-vector mapping */ +- if (rte_intr_cap_multiple(intr_handle) || +- !RTE_ETH_DEV_SRIOV(dev).active) { +- intr_vector = hw->used_rx_queues; +- /* It creates event fd for each intr vector when MSIX is used */ +- if (rte_intr_efd_enable(intr_handle, intr_vector)) +- return -EINVAL; +- } +- if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { ++ if (intr_handle->intr_vec == NULL) { + intr_handle->intr_vec = + rte_zmalloc("intr_vec", + hw->used_rx_queues * sizeof(int), 0); +@@ -2115,28 +2116,26 @@ hns3vf_map_rx_interrupt(struct rte_eth_dev *dev) + vec = RTE_INTR_VEC_RXTX_OFFSET; + base = RTE_INTR_VEC_RXTX_OFFSET; + } +- if (rte_intr_dp_is_en(intr_handle)) { +- for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { +- ret = hns3vf_bind_ring_with_vector(hw, vec, true, +- HNS3_RING_TYPE_RX, +- q_id); +- if (ret) +- goto vf_bind_vector_error; +- intr_handle->intr_vec[q_id] = vec; +- if (vec < base + intr_handle->nb_efd - 1) +- vec++; +- } ++ ++ for (q_id = 0; q_id < hw->used_rx_queues; q_id++) { ++ ret = hns3vf_bind_ring_with_vector(hw, vec, true, ++ HNS3_RING_TYPE_RX, q_id); ++ if (ret) ++ goto vf_bind_vector_error; ++ intr_handle->intr_vec[q_id] = vec; ++ /* ++ * If there are not enough efds (e.g. not enough interrupt), ++ * remaining queues will be bond to the last interrupt. ++ */ ++ if (vec < base + intr_handle->nb_efd - 1) ++ vec++; + } + rte_intr_enable(intr_handle); + return 0; + + vf_bind_vector_error: +- rte_intr_efd_disable(intr_handle); +- if (intr_handle->intr_vec) { +- free(intr_handle->intr_vec); +- intr_handle->intr_vec = NULL; +- } +- return ret; ++ free(intr_handle->intr_vec); ++ intr_handle->intr_vec = NULL; + vf_alloc_intr_vec_error: + rte_intr_efd_disable(intr_handle); + return ret; +-- +2.7.4 + diff --git a/0024-net-hns3-extract-common-checks-for-flow-director.patch b/0024-net-hns3-extract-common-checks-for-flow-director.patch new file mode 100644 index 0000000..df9ed91 --- /dev/null +++ b/0024-net-hns3-extract-common-checks-for-flow-director.patch @@ -0,0 +1,197 @@ +From ea7fb351ca32444916ea099c644d1f29295ffdeb Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:44 +0800 +Subject: [PATCH 024/189] net/hns3: extract common checks for flow director + +When parse flow director with all types, it needs to judge the spec +of item and mask of item for all packet types. The judgement is the +same for all types. Therefore, we move it into the concentrated +location. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 84 +++++++++++--------------------------------- + 1 file changed, 20 insertions(+), 64 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 889fa2f..9b161f4 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -433,17 +433,12 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) + } + + static int +-hns3_parse_eth(const struct rte_flow_item *item, +- struct hns3_fdir_rule *rule, struct rte_flow_error *error) ++hns3_parse_eth(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, ++ struct rte_flow_error *error __rte_unused) + { + const struct rte_flow_item_eth *eth_spec; + const struct rte_flow_item_eth *eth_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + /* Only used to describe the protocol stack. */ + if (item->spec == NULL && item->mask == NULL) + return 0; +@@ -483,11 +478,6 @@ hns3_parse_vlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_vlan *vlan_spec; + const struct rte_flow_item_vlan *vlan_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + rule->key_conf.vlan_num++; + if (rule->key_conf.vlan_num > VLAN_TAG_NUM_MAX) + return rte_flow_error_set(error, EINVAL, +@@ -543,14 +533,10 @@ hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_ipv4 *ipv4_spec; + const struct rte_flow_item_ipv4 *ipv4_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1); + rule->key_conf.spec.ether_type = RTE_ETHER_TYPE_IPV4; + rule->key_conf.mask.ether_type = ETHER_TYPE_MASK; ++ + /* Only used to describe the protocol stack. */ + if (item->spec == NULL && item->mask == NULL) + return 0; +@@ -606,11 +592,6 @@ hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_ipv6 *ipv6_spec; + const struct rte_flow_item_ipv6 *ipv6_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + hns3_set_bit(rule->input_set, INNER_ETH_TYPE, 1); + rule->key_conf.spec.ether_type = RTE_ETHER_TYPE_IPV6; + rule->key_conf.mask.ether_type = ETHER_TYPE_MASK; +@@ -674,11 +655,6 @@ hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_tcp *tcp_spec; + const struct rte_flow_item_tcp *tcp_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); + rule->key_conf.spec.ip_proto = IPPROTO_TCP; + rule->key_conf.mask.ip_proto = IPPROTO_MASK; +@@ -722,11 +698,6 @@ hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_udp *udp_spec; + const struct rte_flow_item_udp *udp_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); + rule->key_conf.spec.ip_proto = IPPROTO_UDP; + rule->key_conf.mask.ip_proto = IPPROTO_MASK; +@@ -768,11 +739,6 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_sctp *sctp_spec; + const struct rte_flow_item_sctp *sctp_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- + hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); + rule->key_conf.spec.ip_proto = IPPROTO_SCTP; + rule->key_conf.mask.ip_proto = IPPROTO_MASK; +@@ -904,15 +870,6 @@ hns3_parse_vxlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_vxlan *vxlan_spec; + const struct rte_flow_item_vxlan *vxlan_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- else if (item->spec && (item->mask == NULL)) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Tunnel packets must configure with mask"); +- + hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1); + rule->key_conf.mask.tunnel_type = TUNNEL_TYPE_MASK; + if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) +@@ -955,15 +912,6 @@ hns3_parse_nvgre(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_nvgre *nvgre_spec; + const struct rte_flow_item_nvgre *nvgre_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- else if (item->spec && (item->mask == NULL)) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Tunnel packets must configure with mask"); +- + hns3_set_bit(rule->input_set, OUTER_IP_PROTO, 1); + rule->key_conf.spec.outer_proto = IPPROTO_GRE; + rule->key_conf.mask.outer_proto = IPPROTO_MASK; +@@ -1013,15 +961,6 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + const struct rte_flow_item_geneve *geneve_spec; + const struct rte_flow_item_geneve *geneve_mask; + +- if (item->spec == NULL && item->mask) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Can't configure FDIR with mask but without spec"); +- else if (item->spec && (item->mask == NULL)) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, item, +- "Tunnel packets must configure with mask"); +- + hns3_set_bit(rule->input_set, OUTER_DST_PORT, 1); + rule->key_conf.spec.tunnel_type = HNS3_TUNNEL_TYPE_GENEVE; + rule->key_conf.mask.tunnel_type = TUNNEL_TYPE_MASK; +@@ -1058,6 +997,17 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + { + int ret; + ++ if (item->spec == NULL && item->mask) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, item, ++ "Can't configure FDIR with mask " ++ "but without spec"); ++ else if (item->spec && (item->mask == NULL)) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, item, ++ "Tunnel packets must configure " ++ "with mask"); ++ + switch (item->type) { + case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: +@@ -1086,6 +1036,12 @@ hns3_parse_normal(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + { + int ret; + ++ if (item->spec == NULL && item->mask) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, item, ++ "Can't configure FDIR with mask " ++ "but without spec"); ++ + switch (item->type) { + case RTE_FLOW_ITEM_TYPE_ETH: + ret = hns3_parse_eth(item, rule, error); +-- +2.7.4 + diff --git a/0025-net-hns3-refactor-reset-event-report-function.patch b/0025-net-hns3-refactor-reset-event-report-function.patch new file mode 100644 index 0000000..f9478da --- /dev/null +++ b/0025-net-hns3-refactor-reset-event-report-function.patch @@ -0,0 +1,122 @@ +From 2e88b488d2b8f3086b7d94179722066b9915a7b9 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:45 +0800 +Subject: [PATCH 025/189] net/hns3: refactor reset event report function + +Here encapsulate the process code of the imp reset report and +global reset report into function in order to reduce the +complexity of the hns3_check_event_cause function. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 69 +++++++++++++++++++++++++++--------------- + 1 file changed, 45 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index f3ce639..817d1dc 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -123,6 +123,47 @@ hns3_pf_enable_irq0(struct hns3_hw *hw) + } + + static enum hns3_evt_cause ++hns3_proc_imp_reset_event(struct hns3_adapter *hns, bool is_delay, ++ uint32_t *vec_val) ++{ ++ struct hns3_hw *hw = &hns->hw; ++ ++ rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending); ++ *vec_val = BIT(HNS3_VECTOR0_IMPRESET_INT_B); ++ if (!is_delay) { ++ hw->reset.stats.imp_cnt++; ++ hns3_warn(hw, "IMP reset detected, clear reset status"); ++ } else { ++ hns3_schedule_delayed_reset(hns); ++ hns3_warn(hw, "IMP reset detected, don't clear reset status"); ++ } ++ ++ return HNS3_VECTOR0_EVENT_RST; ++} ++ ++static enum hns3_evt_cause ++hns3_proc_global_reset_event(struct hns3_adapter *hns, bool is_delay, ++ uint32_t *vec_val) ++{ ++ struct hns3_hw *hw = &hns->hw; ++ ++ rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ hns3_atomic_set_bit(HNS3_GLOBAL_RESET, &hw->reset.pending); ++ *vec_val = BIT(HNS3_VECTOR0_GLOBALRESET_INT_B); ++ if (!is_delay) { ++ hw->reset.stats.global_cnt++; ++ hns3_warn(hw, "Global reset detected, clear reset status"); ++ } else { ++ hns3_schedule_delayed_reset(hns); ++ hns3_warn(hw, ++ "Global reset detected, don't clear reset status"); ++ } ++ ++ return HNS3_VECTOR0_EVENT_RST; ++} ++ ++static enum hns3_evt_cause + hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + { + struct hns3_hw *hw = &hns->hw; +@@ -131,12 +172,14 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + uint32_t hw_err_src_reg; + uint32_t val; + enum hns3_evt_cause ret; ++ bool is_delay; + + /* fetch the events from their corresponding regs */ + vector0_int_stats = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG); + cmdq_src_val = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG); + hw_err_src_reg = hns3_read_dev(hw, HNS3_RAS_PF_OTHER_INT_STS_REG); + ++ is_delay = clearval == NULL ? true : false; + /* + * Assumption: If by any chance reset and mailbox events are reported + * together then we will only process reset event and defer the +@@ -145,35 +188,13 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + * from H/W just for the mailbox. + */ + if (BIT(HNS3_VECTOR0_IMPRESET_INT_B) & vector0_int_stats) { /* IMP */ +- rte_atomic16_set(&hw->reset.disable_cmd, 1); +- hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending); +- val = BIT(HNS3_VECTOR0_IMPRESET_INT_B); +- if (clearval) { +- hw->reset.stats.imp_cnt++; +- hns3_warn(hw, "IMP reset detected, clear reset status"); +- } else { +- hns3_schedule_delayed_reset(hns); +- hns3_warn(hw, "IMP reset detected, don't clear reset status"); +- } +- +- ret = HNS3_VECTOR0_EVENT_RST; ++ ret = hns3_proc_imp_reset_event(hns, is_delay, &val); + goto out; + } + + /* Global reset */ + if (BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) & vector0_int_stats) { +- rte_atomic16_set(&hw->reset.disable_cmd, 1); +- hns3_atomic_set_bit(HNS3_GLOBAL_RESET, &hw->reset.pending); +- val = BIT(HNS3_VECTOR0_GLOBALRESET_INT_B); +- if (clearval) { +- hw->reset.stats.global_cnt++; +- hns3_warn(hw, "Global reset detected, clear reset status"); +- } else { +- hns3_schedule_delayed_reset(hns); +- hns3_warn(hw, "Global reset detected, don't clear reset status"); +- } +- +- ret = HNS3_VECTOR0_EVENT_RST; ++ ret = hns3_proc_global_reset_event(hns, is_delay, &val); + goto out; + } + +-- +2.7.4 + diff --git a/0026-net-hns3-fix-memory-leak-on-secondary-process-exit.patch b/0026-net-hns3-fix-memory-leak-on-secondary-process-exit.patch new file mode 100644 index 0000000..21402ee --- /dev/null +++ b/0026-net-hns3-fix-memory-leak-on-secondary-process-exit.patch @@ -0,0 +1,70 @@ +From 64c98e007bf57084bab1be0256d5d8cabf8e5b29 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:46 +0800 +Subject: [PATCH 026/189] net/hns3: fix memory leak on secondary process exit + +The secondary process is applied a memory for the process_private +during initialization. Therefore, the memory needs to be released +when exiting. + +Fixes: c203571b3602 ("net/hns3: register and add log interface") +Cc: stable@dpdk.org + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 7 +++++-- + drivers/net/hns3/hns3_ethdev_vf.c | 12 +++++++++--- + 2 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 817d1dc..2a5689c 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6263,8 +6263,11 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev) + + PMD_INIT_FUNC_TRACE(); + +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) +- return -EPERM; ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ rte_free(eth_dev->process_private); ++ eth_dev->process_private = NULL; ++ return 0; ++ } + + if (hw->adapter_state < HNS3_NIC_CLOSING) + hns3_dev_close(eth_dev); +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 3a1d4cb..948d914 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1971,8 +1971,11 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev) + struct hns3_hw *hw = &hns->hw; + int ret = 0; + +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ rte_free(eth_dev->process_private); ++ eth_dev->process_private = NULL; + return 0; ++ } + + if (hw->adapter_state == HNS3_NIC_STARTED) + ret = hns3vf_dev_stop(eth_dev); +@@ -2839,8 +2842,11 @@ hns3vf_dev_uninit(struct rte_eth_dev *eth_dev) + + PMD_INIT_FUNC_TRACE(); + +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) +- return -EPERM; ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ rte_free(eth_dev->process_private); ++ eth_dev->process_private = NULL; ++ return 0; ++ } + + if (hw->adapter_state < HNS3_NIC_CLOSING) + hns3vf_dev_close(eth_dev); +-- +2.7.4 + diff --git a/0027-net-hns3-fix-interrupt-resources-in-Rx-interrupt-mod.patch b/0027-net-hns3-fix-interrupt-resources-in-Rx-interrupt-mod.patch new file mode 100644 index 0000000..f37c77d --- /dev/null +++ b/0027-net-hns3-fix-interrupt-resources-in-Rx-interrupt-mod.patch @@ -0,0 +1,244 @@ +From 30c133006d7929fafad11a379fc18f3d23dc0178 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Fri, 22 Jan 2021 18:18:47 +0800 +Subject: [PATCH 027/189] net/hns3: fix interrupt resources in Rx interrupt + mode + +For Kunpeng930, the NIC engine support 1280 tqps being taken over by +a PF. In this case, a maximum of 1281 interrupt resources are also +supported in this PF. To support the maximum number of queues, several +patches are made. But the interrupt related modification are missing. +So, in RX interrupt mode, a large number of queues will be aggregated +into one interrupt due to insufficient interrupts. It will lead to +waste of interrupt resources and reduces usability. + +To utilize all these interrupt resources, related IMP command has been +extended. And, the I/O address of the extended interrupt resources are +different from the existing ones. So, a function used for calculating +the address offset has been added. + +Fixes: 76d794566d43 ("net/hns3: maximize queue number") +Fixes: 27911a6e62e5 ("net/hns3: add Rx interrupts compatibility") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +--- + drivers/net/hns3/hns3_cmd.h | 8 ++++++-- + drivers/net/hns3/hns3_ethdev.c | 17 +++++++++-------- + drivers/net/hns3/hns3_regs.c | 2 +- + drivers/net/hns3/hns3_regs.h | 24 +++++++++++++++--------- + drivers/net/hns3/hns3_rxtx.c | 28 +++++++++++++++++++++++----- + drivers/net/hns3/hns3_rxtx.h | 1 + + 6 files changed, 55 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 6152f6e..dc97a1a 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -776,12 +776,16 @@ enum hns3_int_gl_idx { + #define HNS3_TQP_ID_M GENMASK(12, 2) + #define HNS3_INT_GL_IDX_S 13 + #define HNS3_INT_GL_IDX_M GENMASK(14, 13) ++#define HNS3_TQP_INT_ID_L_S 0 ++#define HNS3_TQP_INT_ID_L_M GENMASK(7, 0) ++#define HNS3_TQP_INT_ID_H_S 8 ++#define HNS3_TQP_INT_ID_H_M GENMASK(15, 8) + struct hns3_ctrl_vector_chain_cmd { +- uint8_t int_vector_id; ++ uint8_t int_vector_id; /* the low order of the interrupt id */ + uint8_t int_cause_num; + uint16_t tqp_type_and_id[HNS3_VECTOR_ELEMENTS_PER_CMD]; + uint8_t vfid; +- uint8_t rsv; ++ uint8_t int_vector_id_h; /* the high order of the interrupt id */ + }; + + struct hns3_config_max_frm_size_cmd { +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 2a5689c..4356860 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2232,7 +2232,7 @@ hns3_check_dcb_cfg(struct rte_eth_dev *dev) + } + + static int +-hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap, ++hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, + enum hns3_ring_type queue_type, uint16_t queue_id) + { + struct hns3_cmd_desc desc; +@@ -2241,13 +2241,15 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap, + enum hns3_cmd_status status; + enum hns3_opcode_type op; + uint16_t tqp_type_and_id = 0; +- const char *op_str; + uint16_t type; + uint16_t gl; + +- op = mmap ? HNS3_OPC_ADD_RING_TO_VECTOR : HNS3_OPC_DEL_RING_TO_VECTOR; ++ op = en ? HNS3_OPC_ADD_RING_TO_VECTOR : HNS3_OPC_DEL_RING_TO_VECTOR; + hns3_cmd_setup_basic_desc(&desc, op, false); +- req->int_vector_id = vector_id; ++ req->int_vector_id = hns3_get_field(vector_id, HNS3_TQP_INT_ID_L_M, ++ HNS3_TQP_INT_ID_L_S); ++ req->int_vector_id_h = hns3_get_field(vector_id, HNS3_TQP_INT_ID_H_M, ++ HNS3_TQP_INT_ID_H_S); + + if (queue_type == HNS3_RING_TYPE_RX) + gl = HNS3_RING_GL_RX; +@@ -2263,11 +2265,10 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap, + gl); + req->tqp_type_and_id[0] = rte_cpu_to_le_16(tqp_type_and_id); + req->int_cause_num = 1; +- op_str = mmap ? "Map" : "Unmap"; + status = hns3_cmd_send(hw, &desc, 1); + if (status) { + hns3_err(hw, "%s TQP %u fail, vector_id is %u, status is %d.", +- op_str, queue_id, req->int_vector_id, status); ++ en ? "Map" : "Unmap", queue_id, vector_id, status); + return status; + } + +@@ -4797,8 +4798,8 @@ hns3_map_rx_interrupt(struct rte_eth_dev *dev) + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- uint8_t base = RTE_INTR_VEC_ZERO_OFFSET; +- uint8_t vec = RTE_INTR_VEC_ZERO_OFFSET; ++ uint16_t base = RTE_INTR_VEC_ZERO_OFFSET; ++ uint16_t vec = RTE_INTR_VEC_ZERO_OFFSET; + uint32_t intr_vector; + uint16_t q_id; + int ret; +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index f2cb465..8afe132 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -301,7 +301,7 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + + reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t); + for (j = 0; j < hw->intr_tqps_num; j++) { +- reg_offset = HNS3_TQP_INTR_REG_SIZE * j; ++ reg_offset = hns3_get_tqp_intr_reg_offset(j); + for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] + + reg_offset); +diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h +index 81a0af5..39fc5d1 100644 +--- a/drivers/net/hns3/hns3_regs.h ++++ b/drivers/net/hns3/hns3_regs.h +@@ -95,15 +95,21 @@ + #define HNS3_MIN_EXTEND_QUEUE_ID 1024 + + /* bar registers for tqp interrupt */ +-#define HNS3_TQP_INTR_CTRL_REG 0x20000 +-#define HNS3_TQP_INTR_GL0_REG 0x20100 +-#define HNS3_TQP_INTR_GL1_REG 0x20200 +-#define HNS3_TQP_INTR_GL2_REG 0x20300 +-#define HNS3_TQP_INTR_RL_REG 0x20900 +-#define HNS3_TQP_INTR_TX_QL_REG 0x20e00 +-#define HNS3_TQP_INTR_RX_QL_REG 0x20f00 +- +-#define HNS3_TQP_INTR_REG_SIZE 4 ++#define HNS3_TQP_INTR_REG_BASE 0x20000 ++#define HNS3_TQP_INTR_EXT_REG_BASE 0x30000 ++#define HNS3_TQP_INTR_CTRL_REG 0 ++#define HNS3_TQP_INTR_GL0_REG 0x100 ++#define HNS3_TQP_INTR_GL1_REG 0x200 ++#define HNS3_TQP_INTR_GL2_REG 0x300 ++#define HNS3_TQP_INTR_RL_REG 0x900 ++#define HNS3_TQP_INTR_TX_QL_REG 0xe00 ++#define HNS3_TQP_INTR_RX_QL_REG 0xf00 ++#define HNS3_TQP_INTR_RL_EN_B 6 ++ ++#define HNS3_MIN_EXT_TQP_INTR_ID 64 ++#define HNS3_TQP_INTR_LOW_ORDER_OFFSET 0x4 ++#define HNS3_TQP_INTR_HIGH_ORDER_OFFSET 0x1000 ++ + #define HNS3_TQP_INTR_GL_MAX 0x1FE0 + #define HNS3_TQP_INTR_GL_DEFAULT 20 + #define HNS3_TQP_INTR_GL_UNIT_1US BIT(31) +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 30f1e06..1991b4e 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -834,6 +834,24 @@ hns3_reset_queue(struct hns3_hw *hw, uint16_t queue_id, + return ret; + } + ++uint32_t ++hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id) ++{ ++ uint32_t reg_offset; ++ ++ /* Need an extend offset to config queues > 64 */ ++ if (tqp_intr_id < HNS3_MIN_EXT_TQP_INTR_ID) ++ reg_offset = HNS3_TQP_INTR_REG_BASE + ++ tqp_intr_id * HNS3_TQP_INTR_LOW_ORDER_OFFSET; ++ else ++ reg_offset = HNS3_TQP_INTR_EXT_REG_BASE + ++ tqp_intr_id / HNS3_MIN_EXT_TQP_INTR_ID * ++ HNS3_TQP_INTR_HIGH_ORDER_OFFSET + ++ tqp_intr_id % HNS3_MIN_EXT_TQP_INTR_ID * ++ HNS3_TQP_INTR_LOW_ORDER_OFFSET; ++ ++ return reg_offset; ++} + + void + hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id, +@@ -847,7 +865,7 @@ hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id, + if (gl_idx >= RTE_DIM(offset) || gl_value > HNS3_TQP_INTR_GL_MAX) + return; + +- addr = offset[gl_idx] + queue_id * HNS3_TQP_INTR_REG_SIZE; ++ addr = offset[gl_idx] + hns3_get_tqp_intr_reg_offset(queue_id); + if (hw->intr.gl_unit == HNS3_INTR_COALESCE_GL_UINT_1US) + value = gl_value | HNS3_TQP_INTR_GL_UNIT_1US; + else +@@ -864,7 +882,7 @@ hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id, uint16_t rl_value) + if (rl_value > HNS3_TQP_INTR_RL_MAX) + return; + +- addr = HNS3_TQP_INTR_RL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE; ++ addr = HNS3_TQP_INTR_RL_REG + hns3_get_tqp_intr_reg_offset(queue_id); + value = HNS3_RL_USEC_TO_REG(rl_value); + if (value > 0) + value |= HNS3_TQP_INTR_RL_ENABLE_MASK; +@@ -885,10 +903,10 @@ hns3_set_queue_intr_ql(struct hns3_hw *hw, uint16_t queue_id, uint16_t ql_value) + if (hw->intr.int_ql_max == HNS3_INTR_QL_NONE) + return; + +- addr = HNS3_TQP_INTR_TX_QL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE; ++ addr = HNS3_TQP_INTR_TX_QL_REG + hns3_get_tqp_intr_reg_offset(queue_id); + hns3_write_dev(hw, addr, ql_value); + +- addr = HNS3_TQP_INTR_RX_QL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE; ++ addr = HNS3_TQP_INTR_RX_QL_REG + hns3_get_tqp_intr_reg_offset(queue_id); + hns3_write_dev(hw, addr, ql_value); + } + +@@ -897,7 +915,7 @@ hns3_queue_intr_enable(struct hns3_hw *hw, uint16_t queue_id, bool en) + { + uint32_t addr, value; + +- addr = HNS3_TQP_INTR_CTRL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE; ++ addr = HNS3_TQP_INTR_CTRL_REG + hns3_get_tqp_intr_reg_offset(queue_id); + value = en ? 1 : 0; + + hns3_write_dev(hw, addr, value); +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 331b507..8f5ae5c 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -680,6 +680,7 @@ int hns3_tx_burst_mode_get(struct rte_eth_dev *dev, + const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev); + void hns3_init_rx_ptype_tble(struct rte_eth_dev *dev); + void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev); ++uint32_t hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id); + void hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id, + uint8_t gl_idx, uint16_t gl_value); + void hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id, +-- +2.7.4 + diff --git a/0028-net-hns3-rename-RSS-functions.patch b/0028-net-hns3-rename-RSS-functions.patch new file mode 100644 index 0000000..f971195 --- /dev/null +++ b/0028-net-hns3-rename-RSS-functions.patch @@ -0,0 +1,137 @@ +From 65ffb8730c023e703e90dfefde782d1b70e830bf Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:48 +0800 +Subject: [PATCH 028/189] net/hns3: rename RSS functions + +Rename some function about RSS implement functions +in order to make the functions naming style more +reasonable and consistency. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 2 +- + drivers/net/hns3/hns3_ethdev_vf.c | 2 +- + drivers/net/hns3/hns3_flow.c | 2 +- + drivers/net/hns3/hns3_rss.c | 12 ++++++------ + drivers/net/hns3/hns3_rss.h | 4 ++-- + 5 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 4356860..94b6e44 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4685,7 +4685,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + goto err_fdir; + } + +- hns3_set_default_rss_args(hw); ++ hns3_rss_set_default_args(hw); + + ret = hns3_enable_hw_error_intr(hns, true); + if (ret) { +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 948d914..7eb0b11 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1832,7 +1832,7 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) + if (ret) + goto err_set_tc_queue; + +- hns3_set_default_rss_args(hw); ++ hns3_rss_set_default_args(hw); + + return 0; + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 9b161f4..8a5179d 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1469,7 +1469,7 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + if (ret) + return ret; + +- ret = hns3_set_rss_algo_key(hw, rss_config->key); ++ ret = hns3_rss_set_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 b5df374..7d1a297 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -193,7 +193,7 @@ static const struct { + * Used to set algorithm, key_offset and hash key of rss. + */ + int +-hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key) ++hns3_rss_set_algo_key(struct hns3_hw *hw, const uint8_t *key) + { + #define HNS3_KEY_OFFSET_MAX 3 + #define HNS3_SET_HASH_KEY_BYTE_FOUR 2 +@@ -245,7 +245,7 @@ hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key) + * Used to configure the tuple selection for RSS hash input. + */ + static int +-hns3_set_rss_input_tuple(struct hns3_hw *hw) ++hns3_rss_set_input_tuple(struct hns3_hw *hw) + { + struct hns3_rss_conf *rss_config = &hw->rss_info; + struct hns3_rss_input_tuple_cmd *req; +@@ -443,7 +443,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + ret = -EINVAL; + goto conf_err; + } +- ret = hns3_set_rss_algo_key(hw, key); ++ ret = hns3_rss_set_algo_key(hw, key); + if (ret) + goto conf_err; + } +@@ -649,7 +649,7 @@ hns3_rss_tuple_uninit(struct hns3_hw *hw) + * Set the default rss configuration in the init of driver. + */ + void +-hns3_set_default_rss_args(struct hns3_hw *hw) ++hns3_rss_set_default_args(struct hns3_hw *hw) + { + struct hns3_rss_conf *rss_cfg = &hw->rss_info; + uint16_t queue_num = hw->alloc_rss_size; +@@ -696,12 +696,12 @@ hns3_config_rss(struct hns3_adapter *hns) + hns3_rss_uninit(hns); + + /* Configure RSS hash algorithm and hash key offset */ +- ret = hns3_set_rss_algo_key(hw, hash_key); ++ ret = hns3_rss_set_algo_key(hw, hash_key); + if (ret) + return ret; + + /* Configure the tuple selection for RSS hash input */ +- ret = hns3_set_rss_input_tuple(hw); ++ ret = hns3_rss_set_input_tuple(hw); + if (ret) + return ret; + +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index 6d1d25f..05d5c26 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -102,7 +102,7 @@ int hns3_dev_rss_reta_update(struct rte_eth_dev *dev, + int hns3_dev_rss_reta_query(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size); +-void hns3_set_default_rss_args(struct hns3_hw *hw); ++void hns3_rss_set_default_args(struct hns3_hw *hw); + int hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, + uint16_t size); + int hns3_rss_reset_indir_table(struct hns3_hw *hw); +@@ -111,7 +111,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, const uint8_t *key); ++int hns3_rss_set_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.7.4 + diff --git a/0029-net-hns3-adjust-some-comments.patch b/0029-net-hns3-adjust-some-comments.patch new file mode 100644 index 0000000..6a64123 --- /dev/null +++ b/0029-net-hns3-adjust-some-comments.patch @@ -0,0 +1,98 @@ +From 2cfeae90323331be6a395bae314e170bfb3ff3b2 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:49 +0800 +Subject: [PATCH 029/189] net/hns3: adjust some comments + +Fix some error comments and remove some meaningless comments. + +Fixes: f8e7fcbfd0b8 ("net/hns3: support flow action of queue region") +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Fixes: ec674cb742e5 ("net/hns3: fix flushing RSS rule") +Cc: stable@dpdk.org + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 8a5179d..f2bff1e 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -91,9 +91,9 @@ net_addr_to_host(uint32_t *dst, const rte_be32_t *src, size_t len) + /* + * This function is used to find rss general action. + * 1. As we know RSS is used to spread packets among several queues, the flow +- * API provide the struct rte_flow_action_rss, user could config it's field ++ * API provide the struct rte_flow_action_rss, user could config its field + * sush as: func/level/types/key/queue to control RSS function. +- * 2. The flow API also support queue region configuration for hns3. It was ++ * 2. The flow API also supports queue region configuration for hns3. It was + * implemented by FDIR + RSS in hns3 hardware, user can create one FDIR rule + * which action is RSS queues region. + * 3. When action is RSS, we use the following rule to distinguish: +@@ -128,11 +128,11 @@ hns3_find_rss_general_action(const struct rte_flow_item pattern[], + rss = act->conf; + if (have_eth && rss->conf.queue_num) { + /* +- * Patter have ETH and action's queue_num > 0, indicate this is ++ * Pattern have ETH and action's queue_num > 0, indicate this is + * queue region configuration. + * Because queue region is implemented by FDIR + RSS in hns3 +- * hardware, it need enter FDIR process, so here return NULL to +- * avoid enter RSS process. ++ * hardware, it needs to enter FDIR process, so here return NULL ++ * to avoid enter RSS process. + */ + return NULL; + } +@@ -405,7 +405,6 @@ hns3_handle_actions(struct rte_eth_dev *dev, + return 0; + } + +-/* Parse to get the attr and action info of flow director rule. */ + static int + hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) + { +@@ -782,7 +781,7 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + } + + /* +- * Check items before tunnel, save inner configs to outer configs,and clear ++ * Check items before tunnel, save inner configs to outer configs, and clear + * inner configs. + * The key consists of two parts: meta_data and tuple keys. + * Meta data uses 15 bits, including vlan_num(2bit), des_port(12bit) and tunnel +@@ -1473,10 +1472,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) + if (ret) + return ret; + +- /* Update algorithm of hw */ + hw->rss_info.conf.func = rss_config->func; + +- /* Set flow type supported */ + tuple = &hw->rss_info.rss_tuple_sets; + ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_config->types); + if (ret) +@@ -1561,7 +1558,7 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, + if (rss_flow_conf.queue_num) { + /* + * Due the content of queue pointer have been reset to +- * 0, the rss_info->conf.queue should be set NULL ++ * 0, the rss_info->conf.queue should be set to NULL + */ + rss_info->conf.queue = NULL; + rss_info->conf.queue_num = 0; +@@ -1727,7 +1724,7 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + /* + * Create or destroy a flow rule. + * Theorically one rule can match more than one filters. +- * We will let it use the filter which it hitt first. ++ * We will let it use the filter which it hit first. + * So, the sequence matters. + */ + static struct rte_flow * +-- +2.7.4 + diff --git a/0030-net-hns3-remove-unnecessary-parentheses.patch b/0030-net-hns3-remove-unnecessary-parentheses.patch new file mode 100644 index 0000000..064dc97 --- /dev/null +++ b/0030-net-hns3-remove-unnecessary-parentheses.patch @@ -0,0 +1,45 @@ +From d7fa7d59733c34f7d8083a6567ca8a0e3efb1fb6 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:50 +0800 +Subject: [PATCH 030/189] net/hns3: remove unnecessary parentheses + +Remove unnecessary parentheses as well as keep a reasonable +blank line. + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index f2bff1e..e9d0a0b 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -700,6 +700,7 @@ hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + hns3_set_bit(rule->input_set, INNER_IP_PROTO, 1); + rule->key_conf.spec.ip_proto = IPPROTO_UDP; + rule->key_conf.mask.ip_proto = IPPROTO_MASK; ++ + /* Only used to describe the protocol stack. */ + if (item->spec == NULL && item->mask == NULL) + return 0; +@@ -1264,7 +1265,7 @@ hns3_action_rss_same(const struct rte_flow_action_rss *comp, + if (comp->func == RTE_ETH_HASH_FUNCTION_MAX) + func_is_same = false; + else +- func_is_same = (with->func ? (comp->func == with->func) : true); ++ func_is_same = with->func ? (comp->func == with->func) : true; + + return (func_is_same && + comp->types == (with->types & HNS3_ETH_RSS_SUPPORT) && +@@ -1861,6 +1862,7 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, + flow, "Flow is NULL"); ++ + filter_type = flow->filter_type; + switch (filter_type) { + case RTE_ETH_FILTER_FDIR: +-- +2.7.4 + diff --git a/0031-net-hns3-adjust-format-specifier-for-enum.patch b/0031-net-hns3-adjust-format-specifier-for-enum.patch new file mode 100644 index 0000000..1409236 --- /dev/null +++ b/0031-net-hns3-adjust-format-specifier-for-enum.patch @@ -0,0 +1,31 @@ +From dc8b97b9ef327bcb295bc7a2d2e4ffaaca6ba1f0 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Fri, 22 Jan 2021 18:18:51 +0800 +Subject: [PATCH 031/189] net/hns3: adjust format specifier for enum + +Here uses %d as printing output for enumeration member. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index e9d0a0b..3e387ac 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1447,7 +1447,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, + *hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; + break; + default: +- hns3_err(hw, "Invalid RSS algorithm configuration(%u)", ++ hns3_err(hw, "Invalid RSS algorithm configuration(%d)", + algo_func); + return -EINVAL; + } +-- +2.7.4 + diff --git a/0032-net-hns3-support-LSC-event-report.patch b/0032-net-hns3-support-LSC-event-report.patch new file mode 100644 index 0000000..23df2bf --- /dev/null +++ b/0032-net-hns3-support-LSC-event-report.patch @@ -0,0 +1,245 @@ +From 0112993819b0a5ae9bf35f8a3adf45c6134d69bd Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 22 Jan 2021 18:18:52 +0800 +Subject: [PATCH 032/189] net/hns3: support LSC event report + +This patch support LSC (Link Status Change) event report. + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 52 +++++++++++++++++++++++++++++++++++---- + drivers/net/hns3/hns3_ethdev.h | 4 ++- + drivers/net/hns3/hns3_ethdev_vf.c | 40 +++++++++++++++++++++++++++++- + drivers/net/hns3/hns3_mbx.c | 14 ++++++----- + 4 files changed, 97 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 94b6e44..bc77608 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -19,6 +19,7 @@ + #define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1 + + #define HNS3_SERVICE_INTERVAL 1000000 /* us */ ++#define HNS3_SERVICE_QUICK_INTERVAL 10 + #define HNS3_INVALID_PVID 0xFFFF + + #define HNS3_FILTER_TYPE_VF 0 +@@ -93,6 +94,7 @@ 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 bool hns3_update_link_status(struct hns3_hw *hw); + + static int hns3_add_mc_addr(struct hns3_hw *hw, + struct rte_ether_addr *mac_addr); +@@ -4458,7 +4460,7 @@ hns3_get_mac_link_status(struct hns3_hw *hw) + return !!link_status; + } + +-void ++static bool + hns3_update_link_status(struct hns3_hw *hw) + { + int state; +@@ -4467,7 +4469,36 @@ hns3_update_link_status(struct hns3_hw *hw) + if (state != hw->mac.link_status) { + hw->mac.link_status = state; + hns3_warn(hw, "Link status change to %s!", state ? "up" : "down"); ++ return true; + } ++ ++ return false; ++} ++ ++/* ++ * Current, the PF driver get link status by two ways: ++ * 1) Periodic polling in the intr thread context, driver call ++ * hns3_update_link_status to update link status. ++ * 2) Firmware report async interrupt, driver process the event in the intr ++ * thread context, and call hns3_update_link_status to update link status. ++ * ++ * If detect link status changed, driver need report LSE. One method is add the ++ * report LSE logic in hns3_update_link_status. ++ * ++ * But the PF driver ops(link_update) also call hns3_update_link_status to ++ * update link status. ++ * If we report LSE in hns3_update_link_status, it may lead to deadlock in the ++ * bonding application. ++ * ++ * So add the one new API which used only in intr thread context. ++ */ ++void ++hns3_update_link_status_and_event(struct hns3_hw *hw) ++{ ++ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; ++ bool changed = hns3_update_link_status(hw); ++ if (changed) ++ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); + } + + static void +@@ -4479,9 +4510,10 @@ hns3_service_handler(void *param) + + if (!hns3_is_reset_pending(hns)) { + hns3_update_speed_duplex(eth_dev); +- hns3_update_link_status(hw); +- } else ++ hns3_update_link_status_and_event(hw); ++ } else { + hns3_warn(hw, "Cancel the query when reset is pending"); ++ } + + rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev); + } +@@ -5557,8 +5589,10 @@ hns3_stop_service(struct hns3_adapter *hns) + struct rte_eth_dev *eth_dev; + + eth_dev = &rte_eth_devices[hw->data->port_id]; +- if (hw->adapter_state == HNS3_NIC_STARTED) ++ if (hw->adapter_state == HNS3_NIC_STARTED) { + rte_eal_alarm_cancel(hns3_service_handler, eth_dev); ++ hns3_update_link_status_and_event(hw); ++ } + hw->mac.link_status = ETH_LINK_DOWN; + + hns3_set_rxtx_function(eth_dev); +@@ -5601,7 +5635,15 @@ hns3_start_service(struct hns3_adapter *hns) + hns3_set_rxtx_function(eth_dev); + hns3_mp_req_start_rxtx(eth_dev); + if (hw->adapter_state == HNS3_NIC_STARTED) { +- hns3_service_handler(eth_dev); ++ /* ++ * This API parent function already hold the hns3_hw.lock, the ++ * hns3_service_handler may report lse, in bonding application ++ * it will call driver's ops which may acquire the hns3_hw.lock ++ * again, thus lead to deadlock. ++ * We defer calls hns3_service_handler to avoid the deadlock. ++ */ ++ rte_eal_alarm_set(HNS3_SERVICE_QUICK_INTERVAL, ++ hns3_service_handler, eth_dev); + + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 0d17170..547e991 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -946,11 +946,13 @@ 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); ++void hns3_update_link_status_and_event(struct hns3_hw *hw); + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr); + int hns3_dev_infos_get(struct rte_eth_dev *eth_dev, + struct rte_eth_dev_info *info); ++void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status, ++ uint32_t link_speed, uint8_t link_duplex); + + static inline bool + is_reset_pending(struct hns3_adapter *hns) +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 7eb0b11..3a682e5 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1440,6 +1440,41 @@ hns3vf_request_link_info(struct hns3_hw *hw) + hns3_err(hw, "Failed to fetch link status from PF: %d", ret); + } + ++void ++hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status, ++ uint32_t link_speed, uint8_t link_duplex) ++{ ++ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; ++ struct hns3_mac *mac = &hw->mac; ++ bool report_lse; ++ bool changed; ++ ++ changed = mac->link_status != link_status || ++ mac->link_speed != link_speed || ++ mac->link_duplex != link_duplex; ++ if (!changed) ++ return; ++ ++ /* ++ * VF's link status/speed/duplex were updated by polling from PF driver, ++ * because the link status/speed/duplex may be changed in the polling ++ * interval, so driver will report lse (lsc event) once any of the above ++ * thress variables changed. ++ * But if the PF's link status is down and driver saved link status is ++ * also down, there are no need to report lse. ++ */ ++ report_lse = true; ++ if (link_status == ETH_LINK_DOWN && link_status == mac->link_status) ++ report_lse = false; ++ ++ mac->link_status = link_status; ++ mac->link_speed = link_speed; ++ mac->link_duplex = link_duplex; ++ ++ if (report_lse) ++ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); ++} ++ + static int + hns3vf_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) + { +@@ -2373,8 +2408,11 @@ hns3vf_stop_service(struct hns3_adapter *hns) + struct rte_eth_dev *eth_dev; + + eth_dev = &rte_eth_devices[hw->data->port_id]; +- if (hw->adapter_state == HNS3_NIC_STARTED) ++ if (hw->adapter_state == HNS3_NIC_STARTED) { + rte_eal_alarm_cancel(hns3vf_service_handler, eth_dev); ++ hns3vf_update_link_status(hw, ETH_LINK_DOWN, hw->mac.link_speed, ++ hw->mac.link_duplex); ++ } + hw->mac.link_status = ETH_LINK_DOWN; + + hns3_set_rxtx_function(eth_dev); +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index d2a5db8..3e44e3b 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -203,8 +203,9 @@ hns3_cmd_crq_empty(struct hns3_hw *hw) + static void + hns3_mbx_handler(struct hns3_hw *hw) + { +- struct hns3_mac *mac = &hw->mac; + enum hns3_reset_level reset_level; ++ uint8_t link_status, link_duplex; ++ uint32_t link_speed; + uint16_t *msg_q; + uint8_t opcode; + uint32_t tail; +@@ -218,10 +219,11 @@ hns3_mbx_handler(struct hns3_hw *hw) + opcode = msg_q[0] & 0xff; + switch (opcode) { + case HNS3_MBX_LINK_STAT_CHANGE: +- memcpy(&mac->link_speed, &msg_q[2], +- sizeof(mac->link_speed)); +- mac->link_status = rte_le_to_cpu_16(msg_q[1]); +- mac->link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]); ++ memcpy(&link_speed, &msg_q[2], sizeof(link_speed)); ++ link_status = rte_le_to_cpu_16(msg_q[1]); ++ link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]); ++ hns3vf_update_link_status(hw, link_status, link_speed, ++ link_duplex); + break; + case HNS3_MBX_ASSERTING_RESET: + /* PF has asserted reset hence VF should go in pending +@@ -310,7 +312,7 @@ hns3_handle_link_change_event(struct hns3_hw *hw, + if (!req->msg[LINK_STATUS_OFFSET]) + hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]); + +- hns3_update_link_status(hw); ++ hns3_update_link_status_and_event(hw); + } + + static void +-- +2.7.4 + diff --git a/0033-net-hns3-fix-query-order-of-link-status-and-link-inf.patch b/0033-net-hns3-fix-query-order-of-link-status-and-link-inf.patch new file mode 100644 index 0000000..6e1bb96 --- /dev/null +++ b/0033-net-hns3-fix-query-order-of-link-status-and-link-inf.patch @@ -0,0 +1,96 @@ +From fd6de494db0d040ca42a6f57f202515f537a62b3 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 3 Feb 2021 20:23:47 +0800 +Subject: [PATCH 033/189] net/hns3: fix query order of link status and link + info + +When link information is updated in the firmware, the link information +is updated first and then the link status is updated. In a 1s periodic +task, PF driver queries the link information and then obtains link +status. +It may lead to a 1s time difference for obtaining valid link information +when the port is up. Therefore, the query order of driver should be +reversed to the order of firmware. + +Fixes: 109e4dd1bd7a ("net/hns3: get link state change through mailbox") +Fixes: 59fad0f32135 ("net/hns3: support link update operation") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 27 ++++++++++++++++++++------- + 1 file changed, 20 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index bc77608..b624fce 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -93,7 +93,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 int hns3_update_link_info(struct rte_eth_dev *eth_dev); + static bool hns3_update_link_status(struct hns3_hw *hw); + + static int hns3_add_mc_addr(struct hns3_hw *hw, +@@ -2642,8 +2642,8 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, + struct rte_eth_link new_link; + + if (!hns3_is_reset_pending(hns)) { +- hns3_update_speed_duplex(eth_dev); + hns3_update_link_status(hw); ++ hns3_update_link_info(eth_dev); + } + + memset(&new_link, 0, sizeof(new_link)); +@@ -4368,11 +4368,9 @@ hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) + } + + static int +-hns3_update_speed_duplex(struct rte_eth_dev *eth_dev) ++hns3_update_fiber_link_info(struct hns3_hw *hw) + { +- struct hns3_adapter *hns = eth_dev->data->dev_private; +- struct hns3_hw *hw = &hns->hw; +- struct hns3_pf *pf = &hns->pf; ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); + uint32_t speed; + int ret; + +@@ -4395,6 +4393,21 @@ hns3_update_speed_duplex(struct rte_eth_dev *eth_dev) + } + + static int ++hns3_update_link_info(struct rte_eth_dev *eth_dev) ++{ ++ struct hns3_adapter *hns = eth_dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ int ret = 0; ++ ++ if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) ++ return 0; ++ else if (hw->mac.media_type == HNS3_MEDIA_TYPE_FIBER) ++ ret = hns3_update_fiber_link_info(hw); ++ ++ return ret; ++} ++ ++static int + hns3_cfg_mac_mode(struct hns3_hw *hw, bool enable) + { + struct hns3_config_mac_mode_cmd *req; +@@ -4509,8 +4522,8 @@ hns3_service_handler(void *param) + struct hns3_hw *hw = &hns->hw; + + if (!hns3_is_reset_pending(hns)) { +- hns3_update_speed_duplex(eth_dev); + hns3_update_link_status_and_event(hw); ++ hns3_update_link_info(eth_dev); + } else { + hns3_warn(hw, "Cancel the query when reset is pending"); + } +-- +2.7.4 + diff --git a/0034-net-hns3-fix-link-status-change-from-firmware.patch b/0034-net-hns3-fix-link-status-change-from-firmware.patch new file mode 100644 index 0000000..4cf077b --- /dev/null +++ b/0034-net-hns3-fix-link-status-change-from-firmware.patch @@ -0,0 +1,115 @@ +From 721dce02ae8a5ca9da07849d9759310f1e3cafda Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 3 Feb 2021 20:23:48 +0800 +Subject: [PATCH 034/189] net/hns3: fix link status change from firmware + +When the hardware link status changes, the firmware proactively +reports the link status change message, and then driver update +link status. This feature is lack of a switch to control in PF +driver. Otherwise, this feature does not take effect when the +kernel PF driver that supports the feature is not loaded. + +Fixes: 109e4dd1bd7a ("net/hns3: get link state change through mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.h | 10 ++++++++++ + drivers/net/hns3/hns3_ethdev.c | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index dc97a1a..ad5e188 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -206,6 +206,9 @@ enum hns3_opcode_type { + /* Clear hardware state command */ + HNS3_OPC_CLEAR_HW_STATE = 0x700B, + ++ /* Firmware stats command */ ++ HNS3_OPC_FIRMWARE_COMPAT_CFG = 0x701A, ++ + /* SFP command */ + HNS3_OPC_SFP_GET_SPEED = 0x7104, + +@@ -633,6 +636,13 @@ enum hns3_promisc_type { + HNS3_BROADCAST = 3, + }; + ++#define HNS3_LINK_EVENT_REPORT_EN_B 0 ++#define HNS3_NCSI_ERROR_REPORT_EN_B 1 ++struct hns3_firmware_compat_cmd { ++ uint32_t compat; ++ uint8_t rsv[20]; ++}; ++ + #define HNS3_MAC_TX_EN_B 6 + #define HNS3_MAC_RX_EN_B 7 + #define HNS3_MAC_PAD_TX_B 11 +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index b624fce..30f09a7 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -3919,6 +3919,26 @@ hns3_buffer_alloc(struct hns3_hw *hw) + } + + static int ++hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init) ++{ ++ struct hns3_firmware_compat_cmd *req; ++ struct hns3_cmd_desc desc; ++ uint32_t compat = 0; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false); ++ req = (struct hns3_firmware_compat_cmd *)desc.data; ++ ++ if (is_init) { ++ hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1); ++ hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0); ++ } ++ ++ req->compat = rte_cpu_to_le_32(compat); ++ ++ return hns3_cmd_send(hw, &desc, 1); ++} ++ ++static int + hns3_mac_init(struct hns3_hw *hw) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +@@ -4610,6 +4630,15 @@ hns3_init_hardware(struct hns3_adapter *hns) + goto err_mac_init; + } + ++ /* ++ * Requiring firmware to enable some features, driver can ++ * still work without it. ++ */ ++ ret = hns3_firmware_compat_config(hw, true); ++ if (ret) ++ PMD_INIT_LOG(WARNING, "firmware compatible features not " ++ "supported, ret = %d.", ret); ++ + return 0; + + err_mac_init: +@@ -4746,6 +4775,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + err_enable_intr: + hns3_fdir_filter_uninit(hns); + err_fdir: ++ (void)hns3_firmware_compat_config(hw, false); + hns3_uninit_umv_space(hw); + err_init_hw: + hns3_tqp_stats_uninit(hw); +@@ -4780,6 +4810,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) + (void)hns3_config_gro(hw, false); + hns3_promisc_uninit(hw); + hns3_fdir_filter_uninit(hns); ++ (void)hns3_firmware_compat_config(hw, false); + hns3_uninit_umv_space(hw); + hns3_tqp_stats_uninit(hw); + hns3_pf_disable_irq0(hw); +-- +2.7.4 + diff --git a/0035-net-hns3-fix-RSS-indirection-table-size.patch b/0035-net-hns3-fix-RSS-indirection-table-size.patch new file mode 100644 index 0000000..197876c --- /dev/null +++ b/0035-net-hns3-fix-RSS-indirection-table-size.patch @@ -0,0 +1,334 @@ +From 00cee658ee4db31787baecbaff321d14734f6494 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Wed, 3 Feb 2021 20:23:49 +0800 +Subject: [PATCH 035/189] net/hns3: fix RSS indirection table size + +The driver should not use the fixed value as the validity check of +RSS indirection table size with HW supported. As a result, it will +cause misjudgment when the RSS RETA size with HW supported have +changed. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Cc: stable@dpdk.org + +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.c | 11 +++++++++++ + drivers/net/hns3/hns3_cmd.h | 7 ++++++- + drivers/net/hns3/hns3_dcb.c | 2 +- + drivers/net/hns3/hns3_ethdev.c | 18 ++++++++++++++++-- + drivers/net/hns3/hns3_ethdev_vf.c | 18 ++++++++++++++++-- + drivers/net/hns3/hns3_flow.c | 6 +++--- + drivers/net/hns3/hns3_rss.c | 28 ++++++++++++++-------------- + drivers/net/hns3/hns3_rss.h | 5 ++--- + 8 files changed, 69 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 4c301cb..a6ea072 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -430,6 +430,16 @@ static void hns3_parse_capability(struct hns3_hw *hw, + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_STASH_B, 1); + } + ++static uint32_t ++hns3_build_api_caps(void) ++{ ++ uint32_t api_caps = 0; ++ ++ hns3_set_bit(api_caps, HNS3_API_CAP_FLEX_RSS_TBL_B, 1); ++ ++ return rte_cpu_to_le_32(api_caps); ++} ++ + static enum hns3_cmd_status + hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw) + { +@@ -439,6 +449,7 @@ hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw) + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_FW_VER, 1); + resp = (struct hns3_query_version_cmd *)desc.data; ++ resp->api_caps = hns3_build_api_caps(); + + /* Initialize the cmd function */ + ret = hns3_cmd_send(hw, &desc, 1); +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index ad5e188..5640fe4 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -295,11 +295,16 @@ enum HNS3_CAPS_BITS { + HNS3_CAPS_HW_PAD_B, + HNS3_CAPS_STASH_B, + }; ++ ++enum HNS3_API_CAP_BITS { ++ HNS3_API_CAP_FLEX_RSS_TBL_B, ++}; ++ + #define HNS3_QUERY_CAP_LENGTH 3 + struct hns3_query_version_cmd { + uint32_t firmware; + uint32_t hardware; +- uint32_t rsv; ++ uint32_t api_caps; + uint32_t caps[HNS3_QUERY_CAP_LENGTH]; /* capabilities of device */ + }; + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index 5aa374c..7fc6ac9 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -644,7 +644,7 @@ hns3_set_rss_size(struct hns3_hw *hw, uint16_t nb_rx_q) + * stage of the reset process. + */ + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { +- for (i = 0; i < HNS3_RSS_IND_TBL_SIZE; i++) ++ for (i = 0; i < hw->rss_ind_tbl_size; i++) + rss_cfg->rss_indirection_tbl[i] = + i % hw->alloc_rss_size; + } +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 30f09a7..df7220b 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2593,7 +2593,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + + info->vmdq_queue_num = 0; + +- info->reta_size = HNS3_RSS_IND_TBL_SIZE; ++ info->reta_size = hw->rss_ind_tbl_size; + info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; + +@@ -2984,6 +2984,20 @@ hns3_parse_dev_specifications(struct hns3_hw *hw, struct hns3_cmd_desc *desc) + } + + static int ++hns3_check_dev_specifications(struct hns3_hw *hw) ++{ ++ if (hw->rss_ind_tbl_size == 0 || ++ hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { ++ hns3_err(hw, "the size of hash lookup table configured (%u)" ++ " exceeds the maximum(%u)", hw->rss_ind_tbl_size, ++ HNS3_RSS_IND_TBL_SIZE_MAX); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int + hns3_query_dev_specifications(struct hns3_hw *hw) + { + struct hns3_cmd_desc desc[HNS3_QUERY_DEV_SPECS_BD_NUM]; +@@ -3003,7 +3017,7 @@ hns3_query_dev_specifications(struct hns3_hw *hw) + + hns3_parse_dev_specifications(hw, desc); + +- return 0; ++ return hns3_check_dev_specifications(hw); + } + + static int +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 3a682e5..1b1989e 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1016,7 +1016,7 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + + info->vmdq_queue_num = 0; + +- info->reta_size = HNS3_RSS_IND_TBL_SIZE; ++ info->reta_size = hw->rss_ind_tbl_size; + info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; + info->default_rxportconf.ring_size = HNS3_DEFAULT_RING_DESC; +@@ -1149,6 +1149,20 @@ hns3vf_parse_dev_specifications(struct hns3_hw *hw, struct hns3_cmd_desc *desc) + } + + static int ++hns3vf_check_dev_specifications(struct hns3_hw *hw) ++{ ++ if (hw->rss_ind_tbl_size == 0 || ++ hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { ++ hns3_warn(hw, "the size of hash lookup table configured (%u)" ++ " exceeds the maximum(%u)", hw->rss_ind_tbl_size, ++ HNS3_RSS_IND_TBL_SIZE_MAX); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int + hns3vf_query_dev_specifications(struct hns3_hw *hw) + { + struct hns3_cmd_desc desc[HNS3_QUERY_DEV_SPECS_BD_NUM]; +@@ -1168,7 +1182,7 @@ hns3vf_query_dev_specifications(struct hns3_hw *hw) + + hns3vf_parse_dev_specifications(hw, desc); + +- return 0; ++ return hns3vf_check_dev_specifications(hw); + } + + static int +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 3e387ac..a601124 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1489,14 +1489,14 @@ hns3_update_indir_table(struct rte_eth_dev *dev, + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE]; ++ uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; + uint16_t j; + uint32_t i; + + /* Fill in redirection table */ + memcpy(indir_tbl, hw->rss_info.rss_indirection_tbl, + sizeof(hw->rss_info.rss_indirection_tbl)); +- for (i = 0, j = 0; i < HNS3_RSS_IND_TBL_SIZE; i++, j++) { ++ for (i = 0, j = 0; i < hw->rss_ind_tbl_size; i++, j++) { + j %= num; + if (conf->queue[j] >= hw->alloc_rss_size) { + hns3_err(hw, "queue id(%u) set to redirection table " +@@ -1507,7 +1507,7 @@ hns3_update_indir_table(struct rte_eth_dev *dev, + indir_tbl[i] = conf->queue[j]; + } + +- return hns3_set_rss_indir_table(hw, indir_tbl, HNS3_RSS_IND_TBL_SIZE); ++ return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size); + } + + static int +diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c +index 7d1a297..858e31a 100644 +--- a/drivers/net/hns3/hns3_rss.c ++++ b/drivers/net/hns3/hns3_rss.c +@@ -312,7 +312,7 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) + + /* Update redirection table of hw */ + memcpy(hw->rss_info.rss_indirection_tbl, indir, +- sizeof(hw->rss_info.rss_indirection_tbl)); ++ sizeof(uint16_t) * size); + + return 0; + } +@@ -324,13 +324,13 @@ hns3_rss_reset_indir_table(struct hns3_hw *hw) + int ret; + + lut = rte_zmalloc("hns3_rss_lut", +- HNS3_RSS_IND_TBL_SIZE * sizeof(uint16_t), 0); ++ hw->rss_ind_tbl_size * sizeof(uint16_t), 0); + if (lut == NULL) { + hns3_err(hw, "No hns3_rss_lut memory can be allocated"); + return -ENOMEM; + } + +- ret = hns3_set_rss_indir_table(hw, lut, HNS3_RSS_IND_TBL_SIZE); ++ ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size); + if (ret) + hns3_err(hw, "RSS uninit indir table failed: %d", ret); + rte_free(lut); +@@ -428,7 +428,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, + } else if (rss_hf && rss_cfg->conf.types == 0) { + /* Enable RSS, restore indirection table by hw's config */ + ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, +- HNS3_RSS_IND_TBL_SIZE); ++ hw->rss_ind_tbl_size); + if (ret) + goto conf_err; + } +@@ -505,15 +505,15 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + struct hns3_rss_conf *rss_cfg = &hw->rss_info; +- uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ +- uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; ++ uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; + uint16_t idx, shift; ++ uint16_t i; + int ret; + +- if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { ++ if (reta_size != hw->rss_ind_tbl_size) { + hns3_err(hw, "The size of hash lookup table configured (%u)" + "doesn't match the number hardware can supported" +- "(%u)", reta_size, indir_size); ++ "(%u)", reta_size, hw->rss_ind_tbl_size); + return -EINVAL; + } + rte_spinlock_lock(&hw->lock); +@@ -536,7 +536,7 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, + } + + ret = hns3_set_rss_indir_table(hw, indirection_tbl, +- HNS3_RSS_IND_TBL_SIZE); ++ hw->rss_ind_tbl_size); + + rte_spinlock_unlock(&hw->lock); + return ret; +@@ -561,13 +561,13 @@ hns3_dev_rss_reta_query(struct rte_eth_dev *dev, + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + struct hns3_rss_conf *rss_cfg = &hw->rss_info; +- uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ + uint16_t idx, shift; ++ uint16_t i; + +- if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { ++ if (reta_size != hw->rss_ind_tbl_size) { + hns3_err(hw, "The size of hash lookup table configured (%u)" + " doesn't match the number hardware can supported" +- "(%u)", reta_size, indir_size); ++ "(%u)", reta_size, hw->rss_ind_tbl_size); + return -EINVAL; + } + rte_spinlock_lock(&hw->lock); +@@ -662,7 +662,7 @@ hns3_rss_set_default_args(struct hns3_hw *hw) + memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); + + /* Initialize RSS indirection table */ +- for (i = 0; i < HNS3_RSS_IND_TBL_SIZE; i++) ++ for (i = 0; i < hw->rss_ind_tbl_size; i++) + rss_cfg->rss_indirection_tbl[i] = i % queue_num; + } + +@@ -711,7 +711,7 @@ hns3_config_rss(struct hns3_adapter *hns) + */ + if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG)) { + ret = hns3_set_rss_indir_table(hw, rss_cfg->rss_indirection_tbl, +- HNS3_RSS_IND_TBL_SIZE); ++ hw->rss_ind_tbl_size); + if (ret) + goto rss_tuple_uninit; + } +diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h +index 05d5c26..94668ed 100644 +--- a/drivers/net/hns3/hns3_rss.h ++++ b/drivers/net/hns3/hns3_rss.h +@@ -24,9 +24,8 @@ + ETH_RSS_L4_DST_ONLY) + + #define HNS3_RSS_IND_TBL_SIZE 512 /* The size of hash lookup table */ ++#define HNS3_RSS_IND_TBL_SIZE_MAX 2048 + #define HNS3_RSS_KEY_SIZE 40 +-#define HNS3_RSS_CFG_TBL_NUM \ +- (HNS3_RSS_IND_TBL_SIZE / HNS3_RSS_CFG_TBL_SIZE) + #define HNS3_RSS_SET_BITMAP_MSK 0xffff + + #define HNS3_RSS_HASH_ALGO_TOEPLITZ 0 +@@ -45,7 +44,7 @@ struct hns3_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; +- uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; /* Shadow table */ ++ uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; + uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ + bool valid; /* check if RSS rule is valid */ + /* +-- +2.7.4 + diff --git a/0036-net-hns3-constrain-TM-peak-rate.patch b/0036-net-hns3-constrain-TM-peak-rate.patch new file mode 100644 index 0000000..9b5fd76 --- /dev/null +++ b/0036-net-hns3-constrain-TM-peak-rate.patch @@ -0,0 +1,37 @@ +From aefb4f06db3a837b7e93f8088c1d4882aa9a5041 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 3 Feb 2021 20:23:50 +0800 +Subject: [PATCH 036/189] net/hns3: constrain TM peak rate + +User could config Port or TC's peak rate by TM ops, but hardware does +not support peak rate which lower than 1Mbps. So we constraint TM +peak rate must be at least 1Mbps. + +Fixes: c09c7847d892 ("net/hns3: support traffic management") + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_tm.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/hns3/hns3_tm.c b/drivers/net/hns3/hns3_tm.c +index d1639d4..bcae57a 100644 +--- a/drivers/net/hns3/hns3_tm.c ++++ b/drivers/net/hns3/hns3_tm.c +@@ -200,6 +200,12 @@ hns3_tm_shaper_profile_param_check(struct rte_eth_dev *dev, + return -EINVAL; + } + ++ if (profile->peak.rate < hns3_tm_rate_convert_firmware2tm(1)) { ++ error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_RATE; ++ error->message = "peak rate must be at least 1Mbps"; ++ return -EINVAL; ++ } ++ + if (profile->peak.size) { + error->type = RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PEAK_SIZE; + error->message = "peak bucket size not supported"; +-- +2.7.4 + diff --git a/0037-net-hns3-remove-MPLS-from-supported-flow-items.patch b/0037-net-hns3-remove-MPLS-from-supported-flow-items.patch new file mode 100644 index 0000000..1f1525d --- /dev/null +++ b/0037-net-hns3-remove-MPLS-from-supported-flow-items.patch @@ -0,0 +1,54 @@ +From 93de9a96a68093772f0137a9899616cfd8cea0c6 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 3 Feb 2021 20:23:51 +0800 +Subject: [PATCH 037/189] net/hns3: remove MPLS from supported flow items + +The Kunpeng920 and Kunpeng930 don't support parse MPLS packet, so +remove the type from supported flow items. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index a601124..c484114 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -44,8 +44,7 @@ static enum rte_flow_item_type first_items[] = { + RTE_FLOW_ITEM_TYPE_NVGRE, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_GENEVE, +- RTE_FLOW_ITEM_TYPE_VXLAN_GPE, +- RTE_FLOW_ITEM_TYPE_MPLS ++ RTE_FLOW_ITEM_TYPE_VXLAN_GPE + }; + + static enum rte_flow_item_type L2_next_items[] = { +@@ -65,8 +64,7 @@ static enum rte_flow_item_type L3_next_items[] = { + static enum rte_flow_item_type L4_next_items[] = { + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_GENEVE, +- RTE_FLOW_ITEM_TYPE_VXLAN_GPE, +- RTE_FLOW_ITEM_TYPE_MPLS ++ RTE_FLOW_ITEM_TYPE_VXLAN_GPE + }; + + static enum rte_flow_item_type tunnel_next_items[] = { +@@ -1118,8 +1116,7 @@ is_tunnel_packet(enum rte_flow_item_type type) + if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || + type == RTE_FLOW_ITEM_TYPE_VXLAN || + type == RTE_FLOW_ITEM_TYPE_NVGRE || +- type == RTE_FLOW_ITEM_TYPE_GENEVE || +- type == RTE_FLOW_ITEM_TYPE_MPLS) ++ type == RTE_FLOW_ITEM_TYPE_GENEVE) + return true; + return false; + } +-- +2.7.4 + diff --git a/0038-net-hns3-fix-stats-flip-overflow.patch b/0038-net-hns3-fix-stats-flip-overflow.patch new file mode 100644 index 0000000..9aa09ac --- /dev/null +++ b/0038-net-hns3-fix-stats-flip-overflow.patch @@ -0,0 +1,67 @@ +From a2524d07bf2f71c925d363fbb7fcfc6d7def57c4 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Wed, 3 Feb 2021 20:23:52 +0800 +Subject: [PATCH 038/189] net/hns3: fix stats flip overflow + +Currently, statistics may overflow in some scenarios. + +For example, if HW statistics are reset by stats reset operation, +but there are still a lot of residual packets exist in the HW +queues and these packets are error packets, flip may occurred +because the ipacket is obtained by subtracting the number of +software error packets from the number of HW received packets. + +This patch verifies the calculation and returns 0 when overflow +may occur. + +Fixes: 8839c5e202f3 ("net/hns3: support device stats") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_stats.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 3ba09e2..e0e40ca 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -554,8 +554,14 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + } + + rte_stats->oerrors = 0; +- rte_stats->ipackets = stats->rcb_rx_ring_pktnum_rcd - +- rte_stats->ierrors; ++ /* ++ * If HW statistics are reset by stats_reset, but a lot of residual ++ * packets exist in the hardware queue and these packets are error ++ * packets, flip overflow may occurred. So return 0 in this case. ++ */ ++ rte_stats->ipackets = ++ stats->rcb_rx_ring_pktnum_rcd > rte_stats->ierrors ? ++ stats->rcb_rx_ring_pktnum_rcd - rte_stats->ierrors : 0; + rte_stats->opackets = stats->rcb_tx_ring_pktnum_rcd - + rte_stats->oerrors; + rte_stats->rx_nombuf = eth_dev->data->rx_mbuf_alloc_failed; +@@ -792,8 +798,15 @@ hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + rxq_stats = &rxq->basic_stats; + rxq_stats->errors = rxq->err_stats.l2_errors + + rxq->err_stats.pkt_len_errors; +- rxq_stats->packets = stats->rcb_rx_ring_pktnum[i] - +- rxq_stats->errors; ++ /* ++ * If HW statistics are reset by stats_reset, but a lot of ++ * residual packets exist in the hardware queue and these ++ * packets are error packets, flip overflow may occurred. ++ * So return 0 in this case. ++ */ ++ rxq_stats->packets = ++ stats->rcb_rx_ring_pktnum[i] > rxq_stats->errors ? ++ stats->rcb_rx_ring_pktnum[i] - rxq_stats->errors : 0; + rxq_stats->bytes = 0; + for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) { + val = (char *)rxq_stats + +-- +2.7.4 + diff --git a/0039-net-hns3-use-C11-atomics.patch b/0039-net-hns3-use-C11-atomics.patch new file mode 100644 index 0000000..804e533 --- /dev/null +++ b/0039-net-hns3-use-C11-atomics.patch @@ -0,0 +1,338 @@ +From 458bb9377c72010ed41f4d2faedad2bd08562cd1 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Wed, 3 Feb 2021 20:23:53 +0800 +Subject: [PATCH 039/189] net/hns3: use C11 atomics + +Replace all the atomic type with C11 atomic builtins in hns3 +PMD. + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.c | 13 +++++++------ + drivers/net/hns3/hns3_ethdev.c | 21 ++++++++++++--------- + drivers/net/hns3/hns3_ethdev.h | 4 ++-- + drivers/net/hns3/hns3_ethdev_vf.c | 19 +++++++++++-------- + drivers/net/hns3/hns3_intr.c | 22 ++++++++++++++-------- + drivers/net/hns3/hns3_mbx.c | 4 ++-- + 6 files changed, 48 insertions(+), 35 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index a6ea072..9393978 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -202,7 +202,8 @@ hns3_cmd_csq_clean(struct hns3_hw *hw) + hns3_err(hw, "wrong cmd head (%u, %u-%u)", head, + csq->next_to_use, csq->next_to_clean); + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, ++ __ATOMIC_RELAXED); + hns3_schedule_delayed_reset(HNS3_DEV_HW_TO_ADAPTER(hw)); + } + +@@ -311,7 +312,7 @@ static int hns3_cmd_poll_reply(struct hns3_hw *hw) + if (hns3_cmd_csq_done(hw)) + return 0; + +- if (rte_atomic16_read(&hw->reset.disable_cmd)) { ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) { + hns3_err(hw, + "Don't wait for reply because of disable_cmd"); + return -EBUSY; +@@ -358,7 +359,7 @@ hns3_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, int num) + int retval; + uint32_t ntc; + +- if (rte_atomic16_read(&hw->reset.disable_cmd)) ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) + return -EBUSY; + + rte_spinlock_lock(&hw->cmq.csq.lock); +@@ -535,7 +536,7 @@ hns3_cmd_init(struct hns3_hw *hw) + ret = -EBUSY; + goto err_cmd_init; + } +- rte_atomic16_clear(&hw->reset.disable_cmd); ++ __atomic_store_n(&hw->reset.disable_cmd, 0, __ATOMIC_RELAXED); + + ret = hns3_cmd_query_firmware_version_and_capability(hw); + if (ret) { +@@ -557,7 +558,7 @@ hns3_cmd_init(struct hns3_hw *hw) + return 0; + + err_cmd_init: +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + return ret; + } + +@@ -583,7 +584,7 @@ hns3_cmd_uninit(struct hns3_hw *hw) + { + rte_spinlock_lock(&hw->cmq.csq.lock); + rte_spinlock_lock(&hw->cmq.crq.lock); +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + hns3_cmd_clear_regs(hw); + rte_spinlock_unlock(&hw->cmq.crq.lock); + rte_spinlock_unlock(&hw->cmq.csq.lock); +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index df7220b..f54b7c2 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -130,7 +130,7 @@ hns3_proc_imp_reset_event(struct hns3_adapter *hns, bool is_delay, + { + struct hns3_hw *hw = &hns->hw; + +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending); + *vec_val = BIT(HNS3_VECTOR0_IMPRESET_INT_B); + if (!is_delay) { +@@ -150,7 +150,7 @@ hns3_proc_global_reset_event(struct hns3_adapter *hns, bool is_delay, + { + struct hns3_hw *hw = &hns->hw; + +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + hns3_atomic_set_bit(HNS3_GLOBAL_RESET, &hw->reset.pending); + *vec_val = BIT(HNS3_VECTOR0_GLOBALRESET_INT_B); + if (!is_delay) { +@@ -5070,7 +5070,7 @@ hns3_do_stop(struct hns3_adapter *hns) + return ret; + hw->mac.link_status = ETH_LINK_DOWN; + +- if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) { ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) { + hns3_configure_all_mac_addr(hns, true); + ret = hns3_reset_all_tqps(hns); + if (ret) { +@@ -5613,7 +5613,7 @@ hns3_prepare_reset(struct hns3_adapter *hns) + * any mailbox handling or command to firmware is only valid + * after hns3_cmd_init is called. + */ +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + hw->reset.stats.request_cnt++; + break; + case HNS3_IMP_RESET: +@@ -5673,7 +5673,7 @@ hns3_stop_service(struct hns3_adapter *hns) + * from table space. Hence, for function reset software intervention is + * required to delete the entries + */ +- if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) + hns3_configure_all_mc_mac_addr(hns, true); + rte_spinlock_unlock(&hw->lock); + +@@ -5795,8 +5795,10 @@ hns3_reset_service(void *param) + * The interrupt may have been lost. It is necessary to handle + * the interrupt to recover from the error. + */ +- if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_DEFERRED) { +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_REQUESTED); ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == ++ SCHEDULE_DEFERRED) { ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_REQUESTED, ++ __ATOMIC_RELAXED); + hns3_err(hw, "Handling interrupts in delayed tasks"); + hns3_interrupt_handler(&rte_eth_devices[hw->data->port_id]); + reset_level = hns3_get_reset_level(hns, &hw->reset.pending); +@@ -5805,7 +5807,7 @@ hns3_reset_service(void *param) + hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending); + } + } +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_NONE); ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_NONE, __ATOMIC_RELAXED); + + /* + * Check if there is any ongoing reset in the hardware. This status can +@@ -6325,7 +6327,8 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + + hw->adapter_state = HNS3_NIC_INITIALIZED; + +- if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_PENDING) { ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == ++ SCHEDULE_PENDING) { + hns3_err(hw, "Reschedule reset service after dev_init"); + hns3_schedule_reset(hns); + } else { +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 547e991..cf42ef1 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -352,11 +352,11 @@ enum hns3_schedule { + + struct hns3_reset_data { + enum hns3_reset_stage stage; +- rte_atomic16_t schedule; ++ uint16_t schedule; + /* Reset flag, covering the entire reset process */ + uint16_t resetting; + /* Used to disable sending cmds during reset */ +- rte_atomic16_t disable_cmd; ++ uint16_t disable_cmd; + /* The reset level being processed */ + enum hns3_reset_level level; + /* Reset level set, each bit represents a reset level */ +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 1b1989e..42cee37 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1059,7 +1059,7 @@ hns3vf_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + rst_ing_reg = hns3_read_dev(hw, HNS3_FUN_RST_ING); + hns3_warn(hw, "resetting reg: 0x%x", rst_ing_reg); + hns3_atomic_set_bit(HNS3_VF_RESET, &hw->reset.pending); +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + val = hns3_read_dev(hw, HNS3_VF_RST_ING); + hns3_write_dev(hw, HNS3_VF_RST_ING, val | HNS3_VF_RST_ING_BIT); + val = cmdq_stat_reg & ~BIT(HNS3_VECTOR0_RST_INT_B); +@@ -1934,7 +1934,7 @@ hns3vf_do_stop(struct hns3_adapter *hns) + + hw->mac.link_status = ETH_LINK_DOWN; + +- if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) { ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) { + hns3vf_configure_mac_addr(hns, true); + ret = hns3_reset_all_tqps(hns); + if (ret) { +@@ -2410,7 +2410,7 @@ hns3vf_prepare_reset(struct hns3_adapter *hns) + ret = hns3_send_mbx_msg(hw, HNS3_MBX_RESET, 0, NULL, + 0, true, NULL, 0); + } +- rte_atomic16_set(&hw->reset.disable_cmd, 1); ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + + return ret; + } +@@ -2449,7 +2449,7 @@ hns3vf_stop_service(struct hns3_adapter *hns) + * from table space. Hence, for function reset software intervention is + * required to delete the entries. + */ +- if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) + hns3vf_configure_all_mc_mac_addr(hns, true); + rte_spinlock_unlock(&hw->lock); + +@@ -2621,8 +2621,10 @@ hns3vf_reset_service(void *param) + * The interrupt may have been lost. It is necessary to handle + * the interrupt to recover from the error. + */ +- if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_DEFERRED) { +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_REQUESTED); ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == ++ SCHEDULE_DEFERRED) { ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_REQUESTED, ++ __ATOMIC_RELAXED); + hns3_err(hw, "Handling interrupts in delayed tasks"); + hns3vf_interrupt_handler(&rte_eth_devices[hw->data->port_id]); + reset_level = hns3vf_get_reset_level(hw, &hw->reset.pending); +@@ -2631,7 +2633,7 @@ hns3vf_reset_service(void *param) + hns3_atomic_set_bit(HNS3_VF_RESET, &hw->reset.pending); + } + } +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_NONE); ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_NONE, __ATOMIC_RELAXED); + + /* + * Hardware reset has been notified, we now have to poll & check if +@@ -2854,7 +2856,8 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) + + hw->adapter_state = HNS3_NIC_INITIALIZED; + +- if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_PENDING) { ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == ++ SCHEDULE_PENDING) { + hns3_err(hw, "Reschedule reset service after dev_init"); + hns3_schedule_reset(hns); + } else { +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 51f19b4..88ce4c6 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -1762,7 +1762,7 @@ hns3_reset_init(struct hns3_hw *hw) + hw->reset.request = 0; + hw->reset.pending = 0; + hw->reset.resetting = 0; +- rte_atomic16_init(&hw->reset.disable_cmd); ++ __atomic_store_n(&hw->reset.disable_cmd, 0, __ATOMIC_RELAXED); + hw->reset.wait_data = rte_zmalloc("wait_data", + sizeof(struct hns3_wait_data), 0); + if (!hw->reset.wait_data) { +@@ -1779,7 +1779,8 @@ hns3_schedule_reset(struct hns3_adapter *hns) + + /* Reschedule the reset process after successful initialization */ + if (hw->adapter_state == HNS3_NIC_UNINITIALIZED) { +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_PENDING); ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_PENDING, ++ __ATOMIC_RELAXED); + return; + } + +@@ -1787,11 +1788,14 @@ hns3_schedule_reset(struct hns3_adapter *hns) + return; + + /* Schedule restart alarm if it is not scheduled yet */ +- if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_REQUESTED) ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == ++ SCHEDULE_REQUESTED) + return; +- if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_DEFERRED) ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == ++ SCHEDULE_DEFERRED) + rte_eal_alarm_cancel(hw->reset.ops->reset_service, hns); +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_REQUESTED); ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_REQUESTED, ++ __ATOMIC_RELAXED); + + rte_eal_alarm_set(SWITCH_CONTEXT_US, hw->reset.ops->reset_service, hns); + } +@@ -1808,9 +1812,11 @@ hns3_schedule_delayed_reset(struct hns3_adapter *hns) + return; + } + +- if (rte_atomic16_read(&hns->hw.reset.schedule) != SCHEDULE_NONE) ++ if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) != ++ SCHEDULE_NONE) + return; +- rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_DEFERRED); ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_DEFERRED, ++ __ATOMIC_RELAXED); + rte_eal_alarm_set(DEFERRED_SCHED_US, hw->reset.ops->reset_service, hns); + } + +@@ -1983,7 +1989,7 @@ hns3_reset_err_handle(struct hns3_adapter *hns) + * Regardless of whether the execution is successful or not, the + * flow after execution must be continued. + */ +- if (rte_atomic16_read(&hw->reset.disable_cmd)) ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) + (void)hns3_cmd_init(hw); + reset_fail: + hw->reset.attempts = 0; +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 3e44e3b..e745843 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -83,7 +83,7 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, + end = now + HNS3_MAX_RETRY_MS; + while ((hw->mbx_resp.head != hw->mbx_resp.tail + hw->mbx_resp.lost) && + (now < end)) { +- if (rte_atomic16_read(&hw->reset.disable_cmd)) { ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) { + hns3_err(hw, "Don't wait for mbx respone because of " + "disable_cmd"); + return -EBUSY; +@@ -369,7 +369,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + int i; + + while (!hns3_cmd_crq_empty(hw)) { +- if (rte_atomic16_read(&hw->reset.disable_cmd)) ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) + return; + + desc = &crq->desc[crq->next_to_use]; +-- +2.7.4 + diff --git a/0040-net-hns3-fix-flow-director-rule-residue-on-malloc-fa.patch b/0040-net-hns3-fix-flow-director-rule-residue-on-malloc-fa.patch new file mode 100644 index 0000000..8332e2f --- /dev/null +++ b/0040-net-hns3-fix-flow-director-rule-residue-on-malloc-fa.patch @@ -0,0 +1,65 @@ +From 2b24ee3f6acfaa8170a37022aab4b5b93d4dc0ae Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 3 Feb 2021 20:23:54 +0800 +Subject: [PATCH 040/189] net/hns3: fix flow director rule residue on malloc + failure + +After FD rule config success, driver will malloc fdir_rule to hold the +rule info, if malloc fail the FD rule in hardware was not cleanup. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_flow.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index c484114..a016857 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1806,17 +1806,18 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + + flow->counter_id = fdir_rule.act_cnt.id; + } ++ ++ fdir_rule_ptr = rte_zmalloc("hns3 fdir rule", ++ sizeof(struct hns3_fdir_rule_ele), ++ 0); ++ if (fdir_rule_ptr == NULL) { ++ hns3_err(hw, "failed to allocate fdir_rule memory."); ++ ret = -ENOMEM; ++ goto err_fdir; ++ } ++ + ret = hns3_fdir_filter_program(hns, &fdir_rule, false); + if (!ret) { +- fdir_rule_ptr = rte_zmalloc("hns3 fdir rule", +- sizeof(struct hns3_fdir_rule_ele), +- 0); +- if (fdir_rule_ptr == NULL) { +- hns3_err(hw, "Failed to allocate fdir_rule memory"); +- ret = -ENOMEM; +- goto err_fdir; +- } +- + memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule, + sizeof(struct hns3_fdir_rule)); + TAILQ_INSERT_TAIL(&process_list->fdir_list, +@@ -1827,10 +1828,10 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + return flow; + } + ++ rte_free(fdir_rule_ptr); + err_fdir: + if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) + hns3_counter_release(dev, fdir_rule.act_cnt.id); +- + err: + rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to create flow"); +-- +2.7.4 + diff --git a/0041-net-hns3-fix-firmware-exceptions-by-concurrent-comma.patch b/0041-net-hns3-fix-firmware-exceptions-by-concurrent-comma.patch new file mode 100644 index 0000000..0a053a8 --- /dev/null +++ b/0041-net-hns3-fix-firmware-exceptions-by-concurrent-comma.patch @@ -0,0 +1,76 @@ +From 50cb4151490c7814418be61cc54d45ad335c11aa Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Wed, 3 Feb 2021 20:23:55 +0800 +Subject: [PATCH 041/189] net/hns3: fix firmware exceptions by concurrent + commands + +There are two scenarios that command queue uninit performed +concurrently with the firmware command: asynchronous command +and timeout command. + +For asynchronous command, if a large number of functions send +commands, these commands may need to be queued to wait for +firmware processing. If a function is uninited suddenly, CMDQ +clearing and firmware processing may be performed concurrently. + +For timeout command, if the command failed due to busy scheduling +of firmware, this command will be processed in the next scheduling. +And this may lead to concurrency. + +The preceding concurrency may lead to a firmware exceptions. + +This patch add a waiting time to ensure the firmware complete the +processing of left over command when PMD uninit. + +Fixes: 737f30e1c3ab ("net/hns3: support command interface with firmware") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.c | 14 +++++++++++++- + drivers/net/hns3/hns3_cmd.h | 1 + + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 9393978..0590898 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -582,9 +582,21 @@ hns3_cmd_destroy_queue(struct hns3_hw *hw) + void + hns3_cmd_uninit(struct hns3_hw *hw) + { ++ __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); ++ ++ /* ++ * A delay is added to ensure that the register cleanup operations ++ * will not be performed concurrently with the firmware command and ++ * ensure that all the reserved commands are executed. ++ * Concurrency may occur in two scenarios: asynchronous command and ++ * timeout command. If the command fails to be executed due to busy ++ * scheduling, the command will be processed in the next scheduling ++ * of the firmware. ++ */ ++ rte_delay_ms(HNS3_CMDQ_CLEAR_WAIT_TIME); ++ + rte_spinlock_lock(&hw->cmq.csq.lock); + rte_spinlock_lock(&hw->cmq.crq.lock); +- __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + hns3_cmd_clear_regs(hw); + rte_spinlock_unlock(&hw->cmq.crq.lock); + rte_spinlock_unlock(&hw->cmq.csq.lock); +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 5640fe4..5010278 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -8,6 +8,7 @@ + #include + + #define HNS3_CMDQ_TX_TIMEOUT 30000 ++#define HNS3_CMDQ_CLEAR_WAIT_TIME 200 + #define HNS3_CMDQ_RX_INVLD_B 0 + #define HNS3_CMDQ_RX_OUTVLD_B 1 + #define HNS3_CMD_DESC_ALIGNMENT 4096 +-- +2.7.4 + diff --git a/0042-net-hns3-fix-VF-reset-on-mailbox-failure.patch b/0042-net-hns3-fix-VF-reset-on-mailbox-failure.patch new file mode 100644 index 0000000..58533e7 --- /dev/null +++ b/0042-net-hns3-fix-VF-reset-on-mailbox-failure.patch @@ -0,0 +1,50 @@ +From 6ceabcab7a4b103f854f338486c1d9fd08349e90 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Wed, 3 Feb 2021 20:23:56 +0800 +Subject: [PATCH 042/189] net/hns3: fix VF reset on mailbox failure + +Currently, during the VF reset, the VF will send a MBX to inform +PF to reset it and the disable command bit will be set whether +the MBX is successful. Generally, multiple reset attempts are made +after a failure. However, because the command is disabled, all +subsequent reset will all fail. + +This patch disable the command only after the MBX message is +successfully. + +Fixes: 2790c6464725 ("net/hns3: support device reset") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev_vf.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 42cee37..fc9f3c8 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2404,15 +2404,17 @@ static int + hns3vf_prepare_reset(struct hns3_adapter *hns) + { + struct hns3_hw *hw = &hns->hw; +- int ret = 0; ++ int ret; + + if (hw->reset.level == HNS3_VF_FUNC_RESET) { + ret = hns3_send_mbx_msg(hw, HNS3_MBX_RESET, 0, NULL, + 0, true, NULL, 0); ++ if (ret) ++ return ret; + } + __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + +- return ret; ++ return 0; + } + + static int +-- +2.7.4 + diff --git a/0043-net-hns3-validate-requested-maximum-Rx-frame-length.patch b/0043-net-hns3-validate-requested-maximum-Rx-frame-length.patch new file mode 100644 index 0000000..a352dce --- /dev/null +++ b/0043-net-hns3-validate-requested-maximum-Rx-frame-length.patch @@ -0,0 +1,98 @@ +From 835880a4bec5fc2fd64d199f3a899e2864c11252 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 3 Feb 2021 20:23:57 +0800 +Subject: [PATCH 043/189] net/hns3: validate requested maximum Rx frame length + +When jumbo frame is enabled, the MTU size needs to be modified +based on 'max_rx_pkt_len'. Driver needs to check the validity +of 'max_rx_pkt_len'. And it should be in the range of +HNS3_DEFAULT_FRAME_LEN and HNS3_MAX_FRAME_LEN. Otherwise, it may +cause that the MTU size is inconsistent with jumbo frame offload. + +Fixes: 19a3ca4c99cf ("net/hns3: add start/stop and configure operations") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 19 +++++++++++++------ + drivers/net/hns3/hns3_ethdev_vf.c | 19 +++++++++++++------ + 2 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index f54b7c2..7ed55b1 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2343,6 +2343,7 @@ hns3_dev_configure(struct rte_eth_dev *dev) + uint16_t nb_rx_q = dev->data->nb_rx_queues; + uint16_t nb_tx_q = dev->data->nb_tx_queues; + struct rte_eth_rss_conf rss_conf; ++ uint32_t max_rx_pkt_len; + uint16_t mtu; + bool gro_en; + int ret; +@@ -2396,12 +2397,18 @@ hns3_dev_configure(struct rte_eth_dev *dev) + * according to the maximum RX packet length. + */ + if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { +- /* +- * Security of max_rx_pkt_len is guaranteed in dpdk frame. +- * Maximum value of max_rx_pkt_len is HNS3_MAX_FRAME_LEN, so it +- * can safely assign to "uint16_t" type variable. +- */ +- mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(conf->rxmode.max_rx_pkt_len); ++ max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; ++ if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || ++ max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { ++ hns3_err(hw, "maximum Rx packet length must be greater " ++ "than %u and less than %u when jumbo frame enabled.", ++ (uint16_t)HNS3_DEFAULT_FRAME_LEN, ++ (uint16_t)HNS3_MAX_FRAME_LEN); ++ ret = -EINVAL; ++ goto cfg_err; ++ } ++ ++ mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); + ret = hns3_dev_mtu_set(dev, mtu); + if (ret) + goto cfg_err; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index fc9f3c8..d5157cf 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -778,6 +778,7 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) + uint16_t nb_rx_q = dev->data->nb_rx_queues; + uint16_t nb_tx_q = dev->data->nb_tx_queues; + struct rte_eth_rss_conf rss_conf; ++ uint32_t max_rx_pkt_len; + uint16_t mtu; + bool gro_en; + int ret; +@@ -825,12 +826,18 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) + * according to the maximum RX packet length. + */ + if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { +- /* +- * Security of max_rx_pkt_len is guaranteed in dpdk frame. +- * Maximum value of max_rx_pkt_len is HNS3_MAX_FRAME_LEN, so it +- * can safely assign to "uint16_t" type variable. +- */ +- mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(conf->rxmode.max_rx_pkt_len); ++ max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; ++ if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || ++ max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { ++ hns3_err(hw, "maximum Rx packet length must be greater " ++ "than %u and less than %u when jumbo frame enabled.", ++ (uint16_t)HNS3_DEFAULT_FRAME_LEN, ++ (uint16_t)HNS3_MAX_FRAME_LEN); ++ ret = -EINVAL; ++ goto cfg_err; ++ } ++ ++ mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); + ret = hns3vf_dev_mtu_set(dev, mtu); + if (ret) + goto cfg_err; +-- +2.7.4 + diff --git a/0044-drivers-net-redefine-array-size-macros.patch b/0044-drivers-net-redefine-array-size-macros.patch new file mode 100644 index 0000000..d6cd224 --- /dev/null +++ b/0044-drivers-net-redefine-array-size-macros.patch @@ -0,0 +1,156 @@ +From 6b66b8fd3b82d5f7c7d35b5e1c52d2611abc4317 Mon Sep 17 00:00:00 2001 +From: Andrew Boyer +Date: Fri, 29 Jan 2021 14:44:32 -0800 +Subject: [PATCH 044/189] drivers/net: redefine array size macros + +Replace copies of size(arr)/size(arr[0]) with RTE_DIM(). +Eventually all of these macro definitions should be removed. + +Signed-off-by: Andrew Boyer +Reviewed-by: Ferruh Yigit +--- + drivers/net/atlantic/atl_hw_regs.h | 2 +- + drivers/net/axgbe/axgbe_common.h | 2 +- + drivers/net/bnx2x/bnx2x.h | 2 +- + drivers/net/bnx2x/elink.h | 2 +- + drivers/net/ena/ena_ethdev.c | 2 +- + drivers/net/enic/base/vnic_devcmd.h | 2 +- + drivers/net/hns3/hns3_ethdev.h | 2 +- + drivers/net/i40e/base/i40e_osdep.h | 2 +- + drivers/net/nfp/nfpcore/nfp-common/nfp_platform.h | 2 +- + drivers/net/thunderx/base/nicvf_hw.h | 2 +- + 10 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/atlantic/atl_hw_regs.h b/drivers/net/atlantic/atl_hw_regs.h +index a2d6ca8..4f6cd35 100644 +--- a/drivers/net/atlantic/atl_hw_regs.h ++++ b/drivers/net/atlantic/atl_hw_regs.h +@@ -26,7 +26,7 @@ + + #define mdelay rte_delay_ms + #define udelay rte_delay_us +-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ++#define ARRAY_SIZE(arr) RTE_DIM(arr) + #define BIT(x) (1UL << (x)) + + #define AQ_HW_WAIT_FOR(_B_, _US_, _N_) \ +diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h +index fb97f0b..799382a 100644 +--- a/drivers/net/axgbe/axgbe_common.h ++++ b/drivers/net/axgbe/axgbe_common.h +@@ -42,7 +42,7 @@ + + #define BIT(nr) (1 << (nr)) + #ifndef ARRAY_SIZE +-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ++#define ARRAY_SIZE(arr) RTE_DIM(arr) + #endif + + #define AXGBE_HZ 250 +diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h +index 69cc143..e13ab15 100644 +--- a/drivers/net/bnx2x/bnx2x.h ++++ b/drivers/net/bnx2x/bnx2x.h +@@ -81,7 +81,7 @@ + #endif + + #ifndef ARRAY_SIZE +-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ++#define ARRAY_SIZE(arr) RTE_DIM(arr) + #endif + #ifndef DIV_ROUND_UP + #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +diff --git a/drivers/net/bnx2x/elink.h b/drivers/net/bnx2x/elink.h +index dd70ac6..6b2e85f 100644 +--- a/drivers/net/bnx2x/elink.h ++++ b/drivers/net/bnx2x/elink.h +@@ -86,7 +86,7 @@ extern void elink_cb_notify_link_changed(struct bnx2x_softc *sc); + #define ELINK_EVENT_ID_SFP_UNQUALIFIED_MODULE 1 + #define ELINK_EVENT_ID_SFP_POWER_FAULT 2 + +-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) ++#define ARRAY_SIZE(x) RTE_DIM(x) + /* Debug prints */ + #ifdef ELINK_DEBUG + +diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c +index 20ff365..b4b8794 100644 +--- a/drivers/net/ena/ena_ethdev.c ++++ b/drivers/net/ena/ena_ethdev.c +@@ -47,7 +47,7 @@ + #define ENA_HASH_KEY_SIZE 40 + #define ETH_GSTRING_LEN 32 + +-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#define ARRAY_SIZE(x) RTE_DIM(x) + + #define ENA_MIN_RING_DESC 128 + +diff --git a/drivers/net/enic/base/vnic_devcmd.h b/drivers/net/enic/base/vnic_devcmd.h +index a2f577f..4675e5a 100644 +--- a/drivers/net/enic/base/vnic_devcmd.h ++++ b/drivers/net/enic/base/vnic_devcmd.h +@@ -63,7 +63,7 @@ + #define _CMD_VTYPE(cmd) (((cmd) >> _CMD_VTYPESHIFT) & _CMD_VTYPEMASK) + #define _CMD_N(cmd) (((cmd) >> _CMD_NSHIFT) & _CMD_NMASK) + +-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#define ARRAY_SIZE(x) RTE_DIM(x) + + enum vnic_devcmd_cmd { + CMD_NONE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_NONE, 0), +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index cf42ef1..6178f0b 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -887,7 +887,7 @@ static inline uint32_t hns3_read_reg(void *base, uint32_t reg) + #define hns3_read_dev(a, reg) \ + hns3_read_reg((a)->io_base, (reg)) + +-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#define ARRAY_SIZE(x) RTE_DIM(x) + + #define NEXT_ITEM_OF_ACTION(act, actions, index) \ + do { \ +diff --git a/drivers/net/i40e/base/i40e_osdep.h b/drivers/net/i40e/base/i40e_osdep.h +index 9b50330..9b79ece 100644 +--- a/drivers/net/i40e/base/i40e_osdep.h ++++ b/drivers/net/i40e/base/i40e_osdep.h +@@ -155,7 +155,7 @@ static inline uint32_t i40e_read_addr(volatile void *addr) + I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value)) + #define flush(a) i40e_read_addr(I40E_PCI_REG_ADDR((a), (I40E_GLGEN_STAT))) + +-#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) ++#define ARRAY_SIZE(arr) RTE_DIM(arr) + + /* memory allocation tracking */ + struct i40e_dma_mem { +diff --git a/drivers/net/nfp/nfpcore/nfp-common/nfp_platform.h b/drivers/net/nfp/nfpcore/nfp-common/nfp_platform.h +index d46574b..7b64e2d 100644 +--- a/drivers/net/nfp/nfpcore/nfp-common/nfp_platform.h ++++ b/drivers/net/nfp/nfpcore/nfp-common/nfp_platform.h +@@ -23,7 +23,7 @@ + #endif + + #ifndef ARRAY_SIZE +-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#define ARRAY_SIZE(x) RTE_DIM(x) + #endif + + #define NFP_ERRNO(err) (errno = (err), -1) +diff --git a/drivers/net/thunderx/base/nicvf_hw.h b/drivers/net/thunderx/base/nicvf_hw.h +index fd13ea8..d6f3a57 100644 +--- a/drivers/net/thunderx/base/nicvf_hw.h ++++ b/drivers/net/thunderx/base/nicvf_hw.h +@@ -17,7 +17,7 @@ + #define PCI_SUB_DEVICE_ID_CN81XX_NICVF 0xA234 + #define PCI_SUB_DEVICE_ID_CN83XX_NICVF 0xA334 + +-#define NICVF_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ++#define NICVF_ARRAY_SIZE(arr) RTE_DIM(arr) + + #define NICVF_GET_RX_STATS(reg) \ + nicvf_reg_read(nic, NIC_VNIC_RX_STAT_0_13 | (reg << 3)) +-- +2.7.4 + diff --git a/0045-net-hns3-support-module-EEPROM-dump.patch b/0045-net-hns3-support-module-EEPROM-dump.patch new file mode 100644 index 0000000..2c756ef --- /dev/null +++ b/0045-net-hns3-support-module-EEPROM-dump.patch @@ -0,0 +1,241 @@ +From 4d36d14e1683f50904525e26fbf311c0aa677940 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 4 Mar 2021 15:44:41 +0800 +Subject: [PATCH 045/189] net/hns3: support module EEPROM dump + +This patch add support for dumping module EEPROM. + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + doc/guides/nics/features/hns3.ini | 1 + + drivers/net/hns3/hns3_cmd.h | 16 ++++ + drivers/net/hns3/hns3_ethdev.c | 159 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 176 insertions(+) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index f0747e3..5ccaca5 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -38,6 +38,7 @@ Extended stats = Y + Stats per queue = Y + FW version = Y + Registers dump = Y ++Module EEPROM dump = Y + Multiprocess aware = Y + Linux UIO = Y + Linux VFIO = Y +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 5010278..ff424a0 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -211,6 +211,8 @@ enum hns3_opcode_type { + HNS3_OPC_FIRMWARE_COMPAT_CFG = 0x701A, + + /* SFP command */ ++ HNS3_OPC_GET_SFP_EEPROM = 0x7100, ++ HNS3_OPC_GET_SFP_EXIST = 0x7101, + HNS3_OPC_SFP_GET_SPEED = 0x7104, + + /* Interrupts commands */ +@@ -714,6 +716,20 @@ struct hns3_config_auto_neg_cmd { + #define HNS3_MAC_FEC_BASER 1 + #define HNS3_MAC_FEC_RS 2 + ++#define HNS3_SFP_INFO_BD0_LEN 20UL ++#define HNS3_SFP_INFO_BDX_LEN 24UL ++ ++struct hns3_sfp_info_bd0_cmd { ++ uint16_t offset; ++ uint16_t read_len; ++ uint8_t data[HNS3_SFP_INFO_BD0_LEN]; ++}; ++ ++struct hns3_sfp_type { ++ uint8_t type; ++ uint8_t ext_type; ++}; ++ + struct hns3_sfp_speed_cmd { + uint32_t sfp_speed; + uint8_t query_type; /* 0: sfp speed, 1: active fec */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7ed55b1..2a37fcc 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6172,6 +6172,163 @@ hns3_query_dev_fec_info(struct hns3_hw *hw) + return ret; + } + ++static bool ++hns3_optical_module_existed(struct hns3_hw *hw) ++{ ++ struct hns3_cmd_desc desc; ++ bool existed; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GET_SFP_EXIST, true); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, ++ "fail to get optical module exist state, ret = %d.\n", ++ ret); ++ return false; ++ } ++ existed = !!desc.data[0]; ++ ++ return existed; ++} ++ ++static int ++hns3_get_module_eeprom_data(struct hns3_hw *hw, uint32_t offset, ++ uint32_t len, uint8_t *data) ++{ ++#define HNS3_SFP_INFO_CMD_NUM 6 ++#define HNS3_SFP_INFO_MAX_LEN \ ++ (HNS3_SFP_INFO_BD0_LEN + \ ++ (HNS3_SFP_INFO_CMD_NUM - 1) * HNS3_SFP_INFO_BDX_LEN) ++ struct hns3_cmd_desc desc[HNS3_SFP_INFO_CMD_NUM]; ++ struct hns3_sfp_info_bd0_cmd *sfp_info_bd0; ++ uint16_t read_len; ++ uint16_t copy_len; ++ int ret; ++ int i; ++ ++ for (i = 0; i < HNS3_SFP_INFO_CMD_NUM; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_GET_SFP_EEPROM, ++ true); ++ if (i < HNS3_SFP_INFO_CMD_NUM - 1) ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ ++ sfp_info_bd0 = (struct hns3_sfp_info_bd0_cmd *)desc[0].data; ++ sfp_info_bd0->offset = rte_cpu_to_le_16((uint16_t)offset); ++ read_len = RTE_MIN(len, HNS3_SFP_INFO_MAX_LEN); ++ sfp_info_bd0->read_len = rte_cpu_to_le_16((uint16_t)read_len); ++ ++ ret = hns3_cmd_send(hw, desc, HNS3_SFP_INFO_CMD_NUM); ++ if (ret) { ++ hns3_err(hw, "fail to get module EEPROM info, ret = %d.\n", ++ ret); ++ return ret; ++ } ++ ++ /* The data format in BD0 is different with the others. */ ++ copy_len = RTE_MIN(len, HNS3_SFP_INFO_BD0_LEN); ++ memcpy(data, sfp_info_bd0->data, copy_len); ++ read_len = copy_len; ++ ++ for (i = 1; i < HNS3_SFP_INFO_CMD_NUM; i++) { ++ if (read_len >= len) ++ break; ++ ++ copy_len = RTE_MIN(len - read_len, HNS3_SFP_INFO_BDX_LEN); ++ memcpy(data + read_len, desc[i].data, copy_len); ++ read_len += copy_len; ++ } ++ ++ return (int)read_len; ++} ++ ++static int ++hns3_get_module_eeprom(struct rte_eth_dev *dev, ++ struct rte_dev_eeprom_info *info) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns); ++ uint32_t offset = info->offset; ++ uint32_t len = info->length; ++ uint8_t *data = info->data; ++ uint32_t read_len = 0; ++ ++ if (hw->mac.media_type != HNS3_MEDIA_TYPE_FIBER) ++ return -ENOTSUP; ++ ++ if (!hns3_optical_module_existed(hw)) { ++ hns3_err(hw, "fail to read module EEPROM: no module is connected.\n"); ++ return -EIO; ++ } ++ ++ while (read_len < len) { ++ int ret; ++ ret = hns3_get_module_eeprom_data(hw, offset + read_len, ++ len - read_len, ++ data + read_len); ++ if (ret < 0) ++ return -EIO; ++ read_len += ret; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_get_module_info(struct rte_eth_dev *dev, ++ struct rte_eth_dev_module_info *modinfo) ++{ ++#define HNS3_SFF8024_ID_SFP 0x03 ++#define HNS3_SFF8024_ID_QSFP_8438 0x0c ++#define HNS3_SFF8024_ID_QSFP_8436_8636 0x0d ++#define HNS3_SFF8024_ID_QSFP28_8636 0x11 ++#define HNS3_SFF_8636_V1_3 0x03 ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns); ++ struct rte_dev_eeprom_info info; ++ struct hns3_sfp_type sfp_type; ++ int ret; ++ ++ memset(&sfp_type, 0, sizeof(sfp_type)); ++ memset(&info, 0, sizeof(info)); ++ info.data = (uint8_t *)&sfp_type; ++ info.length = sizeof(sfp_type); ++ ret = hns3_get_module_eeprom(dev, &info); ++ if (ret) ++ return ret; ++ ++ switch (sfp_type.type) { ++ case HNS3_SFF8024_ID_SFP: ++ modinfo->type = RTE_ETH_MODULE_SFF_8472; ++ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN; ++ break; ++ case HNS3_SFF8024_ID_QSFP_8438: ++ modinfo->type = RTE_ETH_MODULE_SFF_8436; ++ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN; ++ break; ++ case HNS3_SFF8024_ID_QSFP_8436_8636: ++ if (sfp_type.ext_type < HNS3_SFF_8636_V1_3) { ++ modinfo->type = RTE_ETH_MODULE_SFF_8436; ++ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN; ++ } else { ++ modinfo->type = RTE_ETH_MODULE_SFF_8636; ++ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN; ++ } ++ break; ++ case HNS3_SFF8024_ID_QSFP28_8636: ++ modinfo->type = RTE_ETH_MODULE_SFF_8636; ++ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN; ++ break; ++ default: ++ hns3_err(hw, "unknown module, type = %u, extra_type = %u.\n", ++ sfp_type.type, sfp_type.ext_type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static const struct eth_dev_ops hns3_eth_dev_ops = { + .dev_configure = hns3_dev_configure, + .dev_start = hns3_dev_start, +@@ -6223,6 +6380,8 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { + .vlan_offload_set = hns3_vlan_offload_set, + .vlan_pvid_set = hns3_vlan_pvid_set, + .get_reg = hns3_get_regs, ++ .get_module_info = hns3_get_module_info, ++ .get_module_eeprom = hns3_get_module_eeprom, + .get_dcb_info = hns3_get_dcb_info, + .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get, + .fec_get_capability = hns3_fec_get_capability, +-- +2.7.4 + diff --git a/0046-net-hns3-add-more-registers-to-dump.patch b/0046-net-hns3-add-more-registers-to-dump.patch new file mode 100644 index 0000000..54ff5d9 --- /dev/null +++ b/0046-net-hns3-add-more-registers-to-dump.patch @@ -0,0 +1,255 @@ +From b7995f87e190e4ab83ff6a5faea584a4ea4c2198 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 4 Mar 2021 15:44:42 +0800 +Subject: [PATCH 046/189] net/hns3: add more registers to dump + +This patch makes more registers dumped in the dump_reg API to help +locate the fault. + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.h | 13 ++++ + drivers/net/hns3/hns3_regs.c | 171 ++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 180 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index ff424a0..2e23f99 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -95,6 +95,19 @@ enum hns3_opcode_type { + HNS3_OPC_QUERY_REG_NUM = 0x0040, + HNS3_OPC_QUERY_32_BIT_REG = 0x0041, + HNS3_OPC_QUERY_64_BIT_REG = 0x0042, ++ HNS3_OPC_DFX_BD_NUM = 0x0043, ++ HNS3_OPC_DFX_BIOS_COMMON_REG = 0x0044, ++ HNS3_OPC_DFX_SSU_REG_0 = 0x0045, ++ HNS3_OPC_DFX_SSU_REG_1 = 0x0046, ++ HNS3_OPC_DFX_IGU_EGU_REG = 0x0047, ++ HNS3_OPC_DFX_RPU_REG_0 = 0x0048, ++ HNS3_OPC_DFX_RPU_REG_1 = 0x0049, ++ HNS3_OPC_DFX_NCSI_REG = 0x004A, ++ HNS3_OPC_DFX_RTC_REG = 0x004B, ++ HNS3_OPC_DFX_PPP_REG = 0x004C, ++ HNS3_OPC_DFX_RCB_REG = 0x004D, ++ HNS3_OPC_DFX_TQP_REG = 0x004E, ++ HNS3_OPC_DFX_SSU_REG_2 = 0x004F, + + HNS3_OPC_QUERY_DEV_SPECS = 0x0050, + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 8afe132..5b14727 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -15,6 +15,8 @@ + #define REG_NUM_PER_LINE 4 + #define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(uint32_t)) + ++static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *length); ++ + static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG, + HNS3_CMDQ_TX_ADDR_H_REG, + HNS3_CMDQ_TX_DEPTH_REG, +@@ -77,6 +79,21 @@ static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG, + HNS3_TQP_INTR_GL2_REG, + HNS3_TQP_INTR_RL_REG}; + ++static const uint32_t hns3_dfx_reg_opcode_list[] = { ++ HNS3_OPC_DFX_BIOS_COMMON_REG, ++ HNS3_OPC_DFX_SSU_REG_0, ++ HNS3_OPC_DFX_SSU_REG_1, ++ HNS3_OPC_DFX_IGU_EGU_REG, ++ HNS3_OPC_DFX_RPU_REG_0, ++ HNS3_OPC_DFX_RPU_REG_1, ++ HNS3_OPC_DFX_NCSI_REG, ++ HNS3_OPC_DFX_RTC_REG, ++ HNS3_OPC_DFX_PPP_REG, ++ HNS3_OPC_DFX_RCB_REG, ++ HNS3_OPC_DFX_TQP_REG, ++ HNS3_OPC_DFX_SSU_REG_2 ++}; ++ + static int + hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit, + uint32_t *regs_num_64_bit) +@@ -123,14 +140,21 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + if (!hns->is_vf) { + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); + if (ret) { +- hns3_err(hw, "Get register number failed, ret = %d.", +- ret); +- return -ENOTSUP; ++ hns3_err(hw, "fail to get the number of registers, " ++ "ret = %d.", ret); ++ return ret; + } + dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) / + REG_LEN_PER_LINE + 1; + dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) / + REG_LEN_PER_LINE + 1; ++ ++ ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines); ++ if (ret) { ++ hns3_err(hw, "fail to get the number of dfx registers, " ++ "ret = %d.", ret); ++ return ret; ++ } + len += dfx_reg_lines * REG_NUM_PER_LINE; + } + +@@ -310,6 +334,144 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + return data - origin_data_ptr; + } + ++static int ++hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list, ++ uint32_t list_size) ++{ ++#define HNS3_GET_DFX_REG_BD_NUM_SIZE 4 ++ struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE]; ++ uint32_t index, desc_index; ++ uint32_t bd_num; ++ uint32_t i; ++ int ret; ++ ++ for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ /* The last BD does not need a next flag */ ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true); ++ ++ ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE); ++ if (ret) { ++ hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret); ++ return ret; ++ } ++ ++ /* The first data in the first BD is a reserved field */ ++ for (i = 1; i <= list_size; i++) { ++ desc_index = i / HNS3_CMD_DESC_DATA_NUM; ++ index = i % HNS3_CMD_DESC_DATA_NUM; ++ bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]); ++ bd_num_list[i - 1] = bd_num; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, ++ int bd_num, uint32_t opcode) ++{ ++ int ret; ++ int i; ++ ++ for (i = 0; i < bd_num - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], opcode, true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ /* The last BD does not need a next flag */ ++ hns3_cmd_setup_basic_desc(&desc[i], opcode, true); ++ ++ ret = hns3_cmd_send(hw, desc, bd_num); ++ if (ret) { ++ hns3_err(hw, "fail to query dfx registers, opcode = 0x%04X, " ++ "ret = %d.\n", opcode, ret); ++ } ++ ++ return ret; ++} ++ ++static int ++hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg) ++{ ++ int desc_index; ++ int reg_num; ++ int index; ++ int i; ++ ++ reg_num = bd_num * HNS3_CMD_DESC_DATA_NUM; ++ for (i = 0; i < reg_num; i++) { ++ desc_index = i / HNS3_CMD_DESC_DATA_NUM; ++ index = i % HNS3_CMD_DESC_DATA_NUM; ++ *reg++ = desc[desc_index].data[index]; ++ } ++ reg_num += hns3_insert_reg_separator(reg_num, reg); ++ ++ return reg_num; ++} ++ ++static int ++hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines) ++{ ++ int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); ++ uint32_t bd_num_list[opcode_num]; ++ uint32_t bd_num, data_len; ++ int ret; ++ int i; ++ ++ ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < opcode_num; i++) { ++ bd_num = bd_num_list[i]; ++ data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t); ++ *lines += data_len / REG_LEN_PER_LINE + 1; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_get_dfx_regs(struct hns3_hw *hw, void **data) ++{ ++ int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); ++ uint32_t max_bd_num, bd_num, opcode; ++ uint32_t bd_num_list[opcode_num]; ++ struct hns3_cmd_desc *cmd_descs; ++ uint32_t *reg_val = (uint32_t *)*data; ++ int ret; ++ int i; ++ ++ ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num); ++ if (ret) ++ return ret; ++ ++ max_bd_num = 0; ++ for (i = 0; i < opcode_num; i++) ++ max_bd_num = RTE_MAX(bd_num_list[i], max_bd_num); ++ ++ cmd_descs = rte_zmalloc(NULL, sizeof(*cmd_descs) * max_bd_num, 0); ++ if (cmd_descs == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < opcode_num; i++) { ++ opcode = hns3_dfx_reg_opcode_list[i]; ++ bd_num = bd_num_list[i]; ++ if (bd_num == 0) ++ continue; ++ ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode); ++ if (ret) ++ break; ++ reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val); ++ } ++ rte_free(cmd_descs); ++ *data = (void *)reg_val; ++ ++ return ret; ++} ++ + int + hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + { +@@ -371,5 +533,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE; + data += hns3_insert_reg_separator(regs_num_64_bit * + HNS3_64_BIT_REG_SIZE, data); +- return ret; ++ ++ return hns3_get_dfx_regs(hw, (void **)&data); + } +-- +2.7.4 + diff --git a/0047-net-hns3-implement-Tx-mbuf-free-on-demand.patch b/0047-net-hns3-implement-Tx-mbuf-free-on-demand.patch new file mode 100644 index 0000000..17fcd7f --- /dev/null +++ b/0047-net-hns3-implement-Tx-mbuf-free-on-demand.patch @@ -0,0 +1,151 @@ +From f789787f6d1f096a04d39e3de46e5292a7bde3fe Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 4 Mar 2021 15:44:43 +0800 +Subject: [PATCH 047/189] net/hns3: implement Tx mbuf free on demand + +This patch add support tx_done_cleanup ops, which could support for +the API rte_eth_tx_done_cleanup to free consumed mbufs on Tx ring. + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + doc/guides/nics/features/hns3.ini | 1 + + doc/guides/nics/features/hns3_vf.ini | 1 + + drivers/net/hns3/hns3_ethdev.c | 1 + + drivers/net/hns3/hns3_ethdev_vf.c | 1 + + drivers/net/hns3/hns3_rxtx.c | 59 ++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx.h | 1 + + 6 files changed, 64 insertions(+) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index 5ccaca5..00a26cd 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -10,6 +10,7 @@ Queue start/stop = Y + Runtime Rx queue setup = Y + Runtime Tx queue setup = Y + Burst mode info = Y ++Free Tx mbuf on demand = Y + MTU update = Y + Jumbo frame = Y + Scattered Rx = Y +diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini +index 3128b63..f3dd239 100644 +--- a/doc/guides/nics/features/hns3_vf.ini ++++ b/doc/guides/nics/features/hns3_vf.ini +@@ -10,6 +10,7 @@ Queue start/stop = Y + Runtime Rx queue setup = Y + Runtime Tx queue setup = Y + Burst mode info = Y ++Free Tx mbuf on demand = Y + MTU update = Y + Jumbo frame = Y + Scattered Rx = Y +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 2a37fcc..6e0f3b1 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6388,6 +6388,7 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { + .fec_get = hns3_fec_get, + .fec_set = hns3_fec_set, + .tm_ops_get = hns3_tm_ops_get, ++ .tx_done_cleanup = hns3_tx_done_cleanup, + }; + + static const struct hns3_reset_ops hns3_reset_ops = { +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index d5157cf..5b4c587 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2763,6 +2763,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = { + .vlan_offload_set = hns3vf_vlan_offload_set, + .get_reg = hns3_get_regs, + .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get, ++ .tx_done_cleanup = hns3_tx_done_cleanup, + }; + + static const struct hns3_reset_ops hns3vf_reset_ops = { +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 1991b4e..df97018 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -3913,6 +3913,65 @@ hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) + return 0; + } + ++static int ++hns3_tx_done_cleanup_full(struct hns3_tx_queue *txq, uint32_t free_cnt) ++{ ++ uint16_t next_to_clean = txq->next_to_clean; ++ uint16_t next_to_use = txq->next_to_use; ++ uint16_t tx_bd_ready = txq->tx_bd_ready; ++ struct hns3_entry *tx_pkt = &txq->sw_ring[next_to_clean]; ++ struct hns3_desc *desc = &txq->tx_ring[next_to_clean]; ++ uint32_t idx; ++ ++ if (free_cnt == 0 || free_cnt > txq->nb_tx_desc) ++ free_cnt = txq->nb_tx_desc; ++ ++ for (idx = 0; idx < free_cnt; idx++) { ++ if (next_to_clean == next_to_use) ++ break; ++ ++ if (desc->tx.tp_fe_sc_vld_ra_ri & ++ rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B))) ++ break; ++ ++ if (tx_pkt->mbuf != NULL) { ++ rte_pktmbuf_free_seg(tx_pkt->mbuf); ++ tx_pkt->mbuf = NULL; ++ } ++ ++ next_to_clean++; ++ tx_bd_ready++; ++ tx_pkt++; ++ desc++; ++ if (next_to_clean == txq->nb_tx_desc) { ++ tx_pkt = txq->sw_ring; ++ desc = txq->tx_ring; ++ next_to_clean = 0; ++ } ++ } ++ ++ if (idx > 0) { ++ txq->next_to_clean = next_to_clean; ++ txq->tx_bd_ready = tx_bd_ready; ++ } ++ ++ return (int)idx; ++} ++ ++int ++hns3_tx_done_cleanup(void *txq, uint32_t free_cnt) ++{ ++ struct hns3_tx_queue *q = (struct hns3_tx_queue *)txq; ++ struct rte_eth_dev *dev = &rte_eth_devices[q->port_id]; ++ ++ if (dev->tx_pkt_burst == hns3_xmit_pkts) ++ return hns3_tx_done_cleanup_full(q, free_cnt); ++ else if (dev->tx_pkt_burst == hns3_dummy_rxtx_burst) ++ return 0; ++ else ++ return -ENOTSUP; ++} ++ + uint32_t + hns3_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) + { +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 8f5ae5c..7118bd4 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -706,5 +706,6 @@ int hns3_start_all_txqs(struct rte_eth_dev *dev); + int hns3_start_all_rxqs(struct rte_eth_dev *dev); + void hns3_stop_all_txqs(struct rte_eth_dev *dev); + void hns3_restore_tqp_enable_state(struct hns3_hw *hw); ++int hns3_tx_done_cleanup(void *txq, uint32_t free_cnt); + + #endif /* _HNS3_RXTX_H_ */ +-- +2.7.4 + diff --git a/0048-net-hns3-add-bytes-stats.patch b/0048-net-hns3-add-bytes-stats.patch new file mode 100644 index 0000000..062040e --- /dev/null +++ b/0048-net-hns3-add-bytes-stats.patch @@ -0,0 +1,210 @@ +From e5b9ec998c2de659f177332bcdb4868116063b17 Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 4 Mar 2021 15:44:44 +0800 +Subject: [PATCH 048/189] net/hns3: add bytes stats + +In current HNS3 PMD, Rx/Tx bytes from packet stats are not +implemented. + +This patch implemented Rx/Tx bytes using soft counters. + +Signed-off-by: Min Hu (Connor) +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_rxtx.c | 16 ++++++++++++++++ + drivers/net/hns3/hns3_rxtx_vec_neon.h | 9 +++++++++ + drivers/net/hns3/hns3_rxtx_vec_sve.c | 8 ++++++++ + drivers/net/hns3/hns3_stats.c | 18 ++++++++++++++---- + 4 files changed, 47 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index df97018..897e5fa 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2181,6 +2181,9 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + cksum_err); + hns3_rxd_to_vlan_tci(rxq, rxm, l234_info, &rxd); + ++ /* Increment bytes counter */ ++ rxq->basic_stats.bytes += rxm->pkt_len; ++ + rx_pkts[nb_rx++] = rxm; + continue; + pkt_err: +@@ -2401,6 +2404,9 @@ hns3_recv_scattered_pkts(void *rx_queue, + cksum_err); + hns3_rxd_to_vlan_tci(rxq, first_seg, l234_info, &rxd); + ++ /* Increment bytes counter */ ++ rxq->basic_stats.bytes += first_seg->pkt_len; ++ + rx_pkts[nb_rx++] = first_seg; + first_seg = NULL; + continue; +@@ -3516,6 +3522,11 @@ hns3_tx_fill_hw_ring(struct hns3_tx_queue *txq, + for (i = 0; i < mainpart; i += PER_LOOP_NUM) { + hns3_tx_backup_4mbuf(tx_entry + i, pkts + i); + hns3_tx_setup_4bd(txdp + i, pkts + i); ++ ++ /* Increment bytes counter */ ++ uint32_t j; ++ for (j = 0; j < PER_LOOP_NUM; j++) ++ txq->basic_stats.bytes += pkts[i + j]->pkt_len; + } + if (unlikely(leftover > 0)) { + for (i = 0; i < leftover; i++) { +@@ -3523,6 +3534,9 @@ hns3_tx_fill_hw_ring(struct hns3_tx_queue *txq, + pkts + mainpart + i); + hns3_tx_setup_1bd(txdp + mainpart + i, + pkts + mainpart + i); ++ ++ /* Increment bytes counter */ ++ txq->basic_stats.bytes += pkts[mainpart + i]->pkt_len; + } + } + } +@@ -3661,6 +3675,8 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) + desc->tx.tp_fe_sc_vld_ra_ri |= + rte_cpu_to_le_16(BIT(HNS3_TXD_FE_B)); + ++ /* Increment bytes counter */ ++ txq->basic_stats.bytes += tx_pkt->pkt_len; + nb_hold += i; + txq->next_to_use = tx_next_use; + txq->tx_bd_ready -= i; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_neon.h b/drivers/net/hns3/hns3_rxtx_vec_neon.h +index a693b4b..68f098f 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_neon.h ++++ b/drivers/net/hns3/hns3_rxtx_vec_neon.h +@@ -61,6 +61,9 @@ hns3_xmit_fixed_burst_vec(void *__restrict tx_queue, + for (i = 0; i < n; i++, tx_pkts++, tx_desc++) { + hns3_vec_tx(tx_desc, *tx_pkts); + tx_entry[i].mbuf = *tx_pkts; ++ ++ /* Increment bytes counter */ ++ txq->basic_stats.bytes += (*tx_pkts)->pkt_len; + } + + nb_commit -= n; +@@ -72,6 +75,9 @@ hns3_xmit_fixed_burst_vec(void *__restrict tx_queue, + for (i = 0; i < nb_commit; i++, tx_pkts++, tx_desc++) { + hns3_vec_tx(tx_desc, *tx_pkts); + tx_entry[i].mbuf = *tx_pkts; ++ ++ /* Increment bytes counter */ ++ txq->basic_stats.bytes += (*tx_pkts)->pkt_len; + } + + next_to_use += nb_commit; +@@ -116,6 +122,9 @@ hns3_desc_parse_field(struct hns3_rx_queue *rxq, + if (likely(bd_base_info & BIT(HNS3_RXD_L3L4P_B))) + hns3_rx_set_cksum_flag(pkt, pkt->packet_type, + cksum_err); ++ ++ /* Increment bytes counter */ ++ rxq->basic_stats.bytes += pkt->pkt_len; + } + + return retcode; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index 8c2c8f6..947c19f 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -58,6 +58,9 @@ hns3_desc_parse_field_sve(struct hns3_rx_queue *rxq, + if (likely(key->bd_base_info[i] & BIT(HNS3_RXD_L3L4P_B))) + hns3_rx_set_cksum_flag(rx_pkts[i], + rx_pkts[i]->packet_type, cksum_err); ++ ++ /* Increment bytes counter */ ++ rxq->basic_stats.bytes += rx_pkts[i]->pkt_len; + } + + return retcode; +@@ -408,6 +411,11 @@ hns3_tx_fill_hw_ring_sve(struct hns3_tx_queue *txq, + svst1_scatter_u64offset_u64(pg, (uint64_t *)&txdp->tx.paylen, + offsets, svdup_n_u64(valid_bit)); + ++ /* Increment bytes counter */ ++ uint32_t idx; ++ for (idx = 0; idx < svcntd(); idx++) ++ txq->basic_stats.bytes += pkts[idx]->pkt_len; ++ + /* update index for next loop */ + i += svcntd(); + pkts += svcntd(); +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index e0e40ca..777d36a 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -358,6 +358,7 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = { + HNS3_NUM_RESET_XSTATS) + + static void hns3_tqp_stats_clear(struct hns3_hw *hw); ++static void hns3_tqp_basic_stats_clear(struct rte_eth_dev *dev); + + /* + * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034. +@@ -543,16 +544,26 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + return ret; + } + +- /* Get the error stats of received packets */ ++ /* Get the error stats and bytes of received packets */ + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq) { + cnt = rxq->err_stats.l2_errors + + rxq->err_stats.pkt_len_errors; + rte_stats->ierrors += cnt; ++ ++ rte_stats->ibytes += rxq->basic_stats.bytes; + } + } + ++ /* Get the bytes of received packets */ ++ struct hns3_tx_queue *txq; ++ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { ++ txq = eth_dev->data->tx_queues[i]; ++ if (txq) ++ rte_stats->obytes += txq->basic_stats.bytes; ++ } ++ + rte_stats->oerrors = 0; + /* + * If HW statistics are reset by stats_reset, but a lot of residual +@@ -623,6 +634,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + * their source. + */ + hns3_tqp_stats_clear(hw); ++ hns3_tqp_basic_stats_clear(eth_dev); + + return 0; + } +@@ -807,7 +819,6 @@ hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + rxq_stats->packets = + stats->rcb_rx_ring_pktnum[i] > rxq_stats->errors ? + stats->rcb_rx_ring_pktnum[i] - rxq_stats->errors : 0; +- rxq_stats->bytes = 0; + for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) { + val = (char *)rxq_stats + + hns3_rxq_basic_stats_strings[j].offset; +@@ -836,7 +847,7 @@ hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + + txq_stats = &txq->basic_stats; + txq_stats->packets = stats->rcb_tx_ring_pktnum[i]; +- txq_stats->bytes = 0; ++ + for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) { + val = (char *)txq_stats + + hns3_txq_basic_stats_strings[j].offset; +@@ -1328,7 +1339,6 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) + if (ret) + return ret; + +- hns3_tqp_basic_stats_clear(dev); + hns3_tqp_dfx_stats_clear(dev); + + /* Clear reset stats */ +-- +2.7.4 + diff --git a/0049-net-hns3-add-imissed-packet-stats.patch b/0049-net-hns3-add-imissed-packet-stats.patch new file mode 100644 index 0000000..222d3fa --- /dev/null +++ b/0049-net-hns3-add-imissed-packet-stats.patch @@ -0,0 +1,274 @@ +From 682546e9b26cf26a4b82a0c022f5c8dd4a7aa7ed Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 4 Mar 2021 15:44:45 +0800 +Subject: [PATCH 049/189] net/hns3: add imissed packet stats + +This patch implement Rx imissed stats by querying cmdq. + +Signed-off-by: Min Hu (Connor) +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.h | 7 +++ + drivers/net/hns3/hns3_ethdev.c | 7 +++ + drivers/net/hns3/hns3_ethdev.h | 1 + + drivers/net/hns3/hns3_stats.c | 106 ++++++++++++++++++++++++++++++++++++++++- + drivers/net/hns3/hns3_stats.h | 8 ++++ + 5 files changed, 128 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 2e23f99..93bfa74 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -905,6 +905,13 @@ struct hns3_dev_specs_0_cmd { + uint32_t max_tm_rate; + }; + ++struct hns3_query_rpu_cmd { ++ uint32_t tc_queue_num; ++ uint32_t rsv1[2]; ++ uint32_t rpu_rx_pkt_drop_cnt; ++ uint32_t rsv2[2]; ++}; ++ + #define HNS3_MAX_TQP_NUM_HIP08_PF 64 + #define HNS3_DEFAULT_TX_BUF 0x4000 /* 16k bytes */ + #define HNS3_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 6e0f3b1..96ad9b0 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4742,6 +4742,13 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + goto err_cmd_init; + } + ++ /* Hardware statistics of imissed registers cleared. */ ++ ret = hns3_update_imissed_stats(hw, true); ++ if (ret) { ++ hns3_err(hw, "clear imissed stats failed, ret = %d", ret); ++ return ret; ++ } ++ + hns3_config_all_msix_error(hw, true); + + ret = rte_intr_callback_register(&pci_dev->intr_handle, +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 6178f0b..2954422 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -434,6 +434,7 @@ struct hns3_hw { + struct hns3_tqp_stats tqp_stats; + /* Include Mac stats | Rx stats | Tx stats */ + struct hns3_mac_stats mac_stats; ++ struct hns3_rx_missed_stats imissed_stats; + uint32_t fw_version; + + uint16_t num_msi; +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 777d36a..87035e3 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -324,6 +324,12 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = { + {"TX_QUEUE_FBD", HNS3_RING_TX_FBDNUM_REG} + }; + ++/* The statistic of imissed packet */ ++static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = { ++ {"RPU_DROP_CNT", ++ HNS3_IMISSED_STATS_FIELD_OFFSET(rpu_rx_drop_cnt)}, ++}; ++ + #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \ + sizeof(hns3_mac_strings[0])) + +@@ -354,8 +360,11 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = { + #define HNS3_NUM_TXQ_BASIC_STATS (sizeof(hns3_txq_basic_stats_strings) / \ + sizeof(hns3_txq_basic_stats_strings[0])) + ++#define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \ ++ sizeof(hns3_imissed_stats_strings[0])) ++ + #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \ +- HNS3_NUM_RESET_XSTATS) ++ HNS3_NUM_RESET_XSTATS + HNS3_NUM_IMISSED_XSTATS) + + static void hns3_tqp_stats_clear(struct hns3_hw *hw); + static void hns3_tqp_basic_stats_clear(struct rte_eth_dev *dev); +@@ -515,6 +524,52 @@ hns3_update_tqp_stats(struct hns3_hw *hw) + return 0; + } + ++static int ++hns3_update_rpu_drop_stats(struct hns3_hw *hw) ++{ ++ struct hns3_rx_missed_stats *stats = &hw->imissed_stats; ++ struct hns3_query_rpu_cmd *req; ++ struct hns3_cmd_desc desc; ++ uint64_t cnt; ++ uint32_t tc_num; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_DFX_RPU_REG_0, true); ++ req = (struct hns3_query_rpu_cmd *)desc.data; ++ ++ /* ++ * tc_num is 0, means rpu stats of all TC channels will be ++ * get from firmware ++ */ ++ tc_num = 0; ++ req->tc_queue_num = rte_cpu_to_le_32(tc_num); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "failed to query RPU stats: %d", ret); ++ return ret; ++ } ++ ++ cnt = rte_le_to_cpu_32(req->rpu_rx_pkt_drop_cnt); ++ stats->rpu_rx_drop_cnt += cnt; ++ ++ return 0; ++} ++ ++int ++hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear) ++{ ++ int ret; ++ ++ ret = hns3_update_rpu_drop_stats(hw); ++ if (ret) ++ return ret; ++ ++ if (is_clear) ++ memset(&hw->imissed_stats, 0, sizeof(hw->imissed_stats)); ++ ++ return 0; ++} ++ + /* + * Query tqp tx queue statistics ,opcode id: 0x0B03. + * Query tqp rx queue statistics ,opcode id: 0x0B13. +@@ -531,6 +586,7 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + { + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; ++ struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats; + struct hns3_tqp_stats *stats = &hw->tqp_stats; + struct hns3_rx_queue *rxq; + uint64_t cnt; +@@ -544,6 +600,18 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + return ret; + } + ++ if (!hns->is_vf) { ++ /* Update imissed stats */ ++ ret = hns3_update_imissed_stats(hw, false); ++ if (ret) { ++ hns3_err(hw, "update imissed stats failed, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt; ++ } ++ + /* Get the error stats and bytes of received packets */ + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; +@@ -616,6 +684,19 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + } + } + ++ if (!hns->is_vf) { ++ /* ++ * Note: Reading hardware statistics of imissed registers will ++ * clear them. ++ */ ++ ret = hns3_update_imissed_stats(hw, true); ++ if (ret) { ++ hns3_err(hw, "clear imissed stats failed, ret = %d", ++ ret); ++ return ret; ++ } ++ } ++ + /* + * Clear soft stats of rx error packet which will be dropped + * in driver. +@@ -928,6 +1009,7 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_pf *pf = &hns->pf; + struct hns3_hw *hw = &hns->hw; ++ struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats; + struct hns3_mac_stats *mac_stats = &hw->mac_stats; + struct hns3_reset_stats *reset_stats = &hw->reset.stats; + struct hns3_rx_bd_errors_stats *rx_err_stats; +@@ -966,6 +1048,21 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + count++; + } + ++ ret = hns3_update_imissed_stats(hw, false); ++ if (ret) { ++ hns3_err(hw, "update imissed stats failed, ret = %d", ++ ret); ++ return ret; ++ } ++ ++ for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) { ++ addr = (char *)imissed_stats + ++ hns3_imissed_stats_strings[i].offset; ++ xstats[count].value = *(uint64_t *)addr; ++ xstats[count].id = count; ++ count++; ++ } ++ + for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) { + addr = (char *)&pf->abn_int_stats + + hns3_error_int_stats_strings[i].offset; +@@ -1108,6 +1205,13 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev, + count++; + } + ++ for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) { ++ snprintf(xstats_names[count].name, ++ sizeof(xstats_names[count].name), ++ "%s", hns3_imissed_stats_strings[i].name); ++ count++; ++ } ++ + for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), +diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h +index d213be5..01b4f36 100644 +--- a/drivers/net/hns3/hns3_stats.h ++++ b/drivers/net/hns3/hns3_stats.h +@@ -110,6 +110,10 @@ struct hns3_mac_stats { + uint64_t mac_rx_ctrl_pkt_num; + }; + ++struct hns3_rx_missed_stats { ++ uint64_t rpu_rx_drop_cnt; ++}; ++ + /* store statistics names and its offset in stats structure */ + struct hns3_xstats_name_offset { + char name[RTE_ETH_XSTATS_NAME_SIZE]; +@@ -141,6 +145,9 @@ struct hns3_reset_stats; + #define HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(f) \ + (offsetof(struct hns3_tx_basic_stats, f)) + ++#define HNS3_IMISSED_STATS_FIELD_OFFSET(f) \ ++ (offsetof(struct hns3_rx_missed_stats, f)) ++ + 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); +@@ -160,5 +167,6 @@ int hns3_stats_reset(struct rte_eth_dev *dev); + void hns3_error_int_stats_add(struct hns3_adapter *hns, const char *err); + int hns3_tqp_stats_init(struct hns3_hw *hw); + void hns3_tqp_stats_uninit(struct hns3_hw *hw); ++int hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear); + + #endif /* _HNS3_STATS_H_ */ +-- +2.7.4 + diff --git a/0050-net-hns3-encapsulate-port-shaping-interface.patch b/0050-net-hns3-encapsulate-port-shaping-interface.patch new file mode 100644 index 0000000..50ef1f9 --- /dev/null +++ b/0050-net-hns3-encapsulate-port-shaping-interface.patch @@ -0,0 +1,122 @@ +From 73f3a8aa0b5926083482f5e1f9999e246856a2ae Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 4 Mar 2021 15:44:46 +0800 +Subject: [PATCH 050/189] net/hns3: encapsulate port shaping interface + +When rate of port changes, the rate limit of the port needs to +be updated. So it is necessary to encapsulate an interface that +configures the rate limit based on the rate. + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_dcb.c | 22 +++++++++++++++++----- + drivers/net/hns3/hns3_dcb.h | 2 +- + drivers/net/hns3/hns3_ethdev.c | 10 +++------- + 3 files changed, 21 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index 7fc6ac9..ebfc240 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -330,8 +330,8 @@ hns3_dcb_get_shapping_para(uint8_t ir_b, uint8_t ir_u, uint8_t ir_s, + return shapping_para; + } + +-int +-hns3_dcb_port_shaper_cfg(struct hns3_hw *hw) ++static int ++hns3_dcb_port_shaper_cfg(struct hns3_hw *hw, uint32_t speed) + { + struct hns3_port_shapping_cmd *shap_cfg_cmd; + struct hns3_shaper_parameter shaper_parameter; +@@ -340,7 +340,7 @@ hns3_dcb_port_shaper_cfg(struct hns3_hw *hw) + struct hns3_cmd_desc desc; + int ret; + +- ret = hns3_shaper_para_calc(hw, hw->mac.link_speed, ++ ret = hns3_shaper_para_calc(hw, speed, + HNS3_SHAPER_LVL_PORT, &shaper_parameter); + if (ret) { + hns3_err(hw, "calculate shaper parameter failed: %d", ret); +@@ -366,12 +366,24 @@ hns3_dcb_port_shaper_cfg(struct hns3_hw *hw) + * depends on the firmware version. But driver still needs to + * calculate it and configure to firmware for better compatibility. + */ +- shap_cfg_cmd->port_rate = rte_cpu_to_le_32(hw->mac.link_speed); ++ shap_cfg_cmd->port_rate = rte_cpu_to_le_32(speed); + hns3_set_bit(shap_cfg_cmd->flag, HNS3_TM_RATE_VLD_B, 1); + + return hns3_cmd_send(hw, &desc, 1); + } + ++int ++hns3_port_shaper_update(struct hns3_hw *hw, uint32_t speed) ++{ ++ int ret; ++ ++ ret = hns3_dcb_port_shaper_cfg(hw, speed); ++ if (ret) ++ hns3_err(hw, "configure port shappering failed: ret = %d", ret); ++ ++ return ret; ++} ++ + static int + hns3_dcb_pg_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, + uint8_t pg_id, uint32_t shapping_para, uint32_t rate) +@@ -961,7 +973,7 @@ hns3_dcb_shaper_cfg(struct hns3_hw *hw) + { + int ret; + +- ret = hns3_dcb_port_shaper_cfg(hw); ++ ret = hns3_dcb_port_shaper_cfg(hw, hw->mac.link_speed); + if (ret) { + hns3_err(hw, "config port shaper failed: %d", ret); + return ret; +diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h +index 8248434..0d25d3b 100644 +--- a/drivers/net/hns3/hns3_dcb.h ++++ b/drivers/net/hns3/hns3_dcb.h +@@ -208,7 +208,7 @@ int hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, + uint16_t nb_tx_q); + + int hns3_dcb_cfg_update(struct hns3_adapter *hns); +-int hns3_dcb_port_shaper_cfg(struct hns3_hw *hw); ++int hns3_port_shaper_update(struct hns3_hw *hw, uint32_t speed); + int hns3_pg_shaper_rate_cfg(struct hns3_hw *hw, uint8_t pg_id, uint32_t rate); + int hns3_pri_shaper_rate_cfg(struct hns3_hw *hw, uint8_t tc_no, uint32_t rate); + uint8_t hns3_txq_mapped_tc_get(struct hns3_hw *hw, uint16_t txq_no); +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 96ad9b0..94c08e8 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4384,7 +4384,6 @@ static int + hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) + { + struct hns3_mac *mac = &hw->mac; +- uint32_t cur_speed = mac->link_speed; + int ret; + + duplex = hns3_check_speed_dup(duplex, speed); +@@ -4395,14 +4394,11 @@ hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) + if (ret) + return ret; + +- mac->link_speed = speed; +- ret = hns3_dcb_port_shaper_cfg(hw); +- if (ret) { +- hns3_err(hw, "failed to configure port shaper, ret = %d.", ret); +- mac->link_speed = cur_speed; ++ ret = hns3_port_shaper_update(hw, speed); ++ if (ret) + return ret; +- } + ++ mac->link_speed = speed; + mac->link_duplex = duplex; + + return 0; +-- +2.7.4 + diff --git a/0051-net-hns3-fix-device-capabilities-for-copper-media-ty.patch b/0051-net-hns3-fix-device-capabilities-for-copper-media-ty.patch new file mode 100644 index 0000000..1457ab4 --- /dev/null +++ b/0051-net-hns3-fix-device-capabilities-for-copper-media-ty.patch @@ -0,0 +1,48 @@ +From 35469e7e3c26afc79f340b8477bf7ce1dc65746e Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 4 Mar 2021 15:44:47 +0800 +Subject: [PATCH 051/189] net/hns3: fix device capabilities for copper media + type + +The configuration operation for PHY is implemented by firmware. And +a capability flag will be report to driver, which means the firmware +supports the PHY driver. However, the current implementation only +supports obtaining the capability bit, but some basic functions of +copper ports in driver, such as, the query of link status and link +info, are not supported. + +Therefore, it is necessary for driver to set the copper capability +bit to zero when the firmware supports the configuration of the PHY. + +Fixes: 438752358158 ("net/hns3: get device capability from firmware") +Fixes: 95e50325864c ("net/hns3: support copper media type") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +--- + drivers/net/hns3/hns3_cmd.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 0590898..f0bc177 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -423,8 +423,14 @@ static void hns3_parse_capability(struct hns3_hw *hw, + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_PTP_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_TX_PUSH_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TX_PUSH_B, 1); ++ /* ++ * Currently, the query of link status and link info on copper ports ++ * are not supported. So it is necessary for driver to set the copper ++ * capability bit to zero when the firmware supports the configuration ++ * of the PHY. ++ */ + if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B)) +- hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 1); ++ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 0); + if (hns3_get_bit(caps, HNS3_CAPS_TQP_TXRX_INDEP_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_STASH_B)) +-- +2.7.4 + diff --git a/0052-net-hns3-support-PF-device-with-copper-PHYs.patch b/0052-net-hns3-support-PF-device-with-copper-PHYs.patch new file mode 100644 index 0000000..5a766a3 --- /dev/null +++ b/0052-net-hns3-support-PF-device-with-copper-PHYs.patch @@ -0,0 +1,279 @@ +From ed40b1477365a3c581f487ba3c8261c53dcdc255 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 4 Mar 2021 15:44:48 +0800 +Subject: [PATCH 052/189] net/hns3: support PF device with copper PHYs + +The normal operation of devices with copper phys depends on the +initialization and configuration of the PHY chip. The task of +driving the PHY chip is implemented in some firmware versions. +If firmware supports the phy driver, it will report a capability +flag to driver in probing process. The driver determines whether +to support PF device with copper phys based on the capability bit. +If supported, the driver set a flag indicating that the firmware +takes over the PHY, and then the firmware initializes the PHY. + +This patch supports the query of link status and link info, and +existing basic features for PF device with copper phys. + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.c | 8 +-- + drivers/net/hns3/hns3_cmd.h | 37 +++++++++++++ + drivers/net/hns3/hns3_ethdev.c | 115 ++++++++++++++++++++++++++++++++++++++--- + drivers/net/hns3/hns3_ethdev.h | 5 ++ + 4 files changed, 152 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index f0bc177..0590898 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -423,14 +423,8 @@ static void hns3_parse_capability(struct hns3_hw *hw, + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_PTP_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_TX_PUSH_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TX_PUSH_B, 1); +- /* +- * Currently, the query of link status and link info on copper ports +- * are not supported. So it is necessary for driver to set the copper +- * capability bit to zero when the firmware supports the configuration +- * of the PHY. +- */ + if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B)) +- hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 0); ++ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_TQP_TXRX_INDEP_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_STASH_B)) +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 93bfa74..7f567cb 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -222,6 +222,8 @@ enum hns3_opcode_type { + + /* Firmware stats command */ + HNS3_OPC_FIRMWARE_COMPAT_CFG = 0x701A, ++ /* Firmware control phy command */ ++ HNS3_OPC_PHY_PARAM_CFG = 0x7025, + + /* SFP command */ + HNS3_OPC_GET_SFP_EEPROM = 0x7100, +@@ -659,11 +661,46 @@ enum hns3_promisc_type { + + #define HNS3_LINK_EVENT_REPORT_EN_B 0 + #define HNS3_NCSI_ERROR_REPORT_EN_B 1 ++#define HNS3_FIRMWARE_PHY_DRIVER_EN_B 2 + struct hns3_firmware_compat_cmd { + uint32_t compat; + uint8_t rsv[20]; + }; + ++/* Bitmap flags in supported, advertising and lp_advertising */ ++#define HNS3_PHY_LINK_SPEED_10M_HD_BIT BIT(0) ++#define HNS3_PHY_LINK_SPEED_10M_BIT BIT(1) ++#define HNS3_PHY_LINK_SPEED_100M_HD_BIT BIT(2) ++#define HNS3_PHY_LINK_SPEED_100M_BIT BIT(3) ++#define HNS3_PHY_LINK_MODE_AUTONEG_BIT BIT(6) ++#define HNS3_PHY_LINK_MODE_PAUSE_BIT BIT(13) ++#define HNS3_PHY_LINK_MODE_ASYM_PAUSE_BIT BIT(14) ++ ++#define HNS3_PHY_PARAM_CFG_BD_NUM 2 ++struct hns3_phy_params_bd0_cmd { ++ uint32_t speed; ++#define HNS3_PHY_DUPLEX_CFG_B 0 ++ uint8_t duplex; ++#define HNS3_PHY_AUTONEG_CFG_B 0 ++ uint8_t autoneg; ++ uint8_t eth_tp_mdix; ++ uint8_t eth_tp_mdix_ctrl; ++ uint8_t port; ++ uint8_t transceiver; ++ uint8_t phy_address; ++ uint8_t rsv; ++ uint32_t supported; ++ uint32_t advertising; ++ uint32_t lp_advertising; ++}; ++ ++struct hns3_phy_params_bd1_cmd { ++ uint8_t master_slave_cfg; ++ uint8_t master_slave_state; ++ uint8_t rsv1[2]; ++ uint32_t rsv2[5]; ++}; ++ + #define HNS3_MAC_TX_EN_B 6 + #define HNS3_MAC_RX_EN_B 7 + #define HNS3_MAC_PAD_TX_B 11 +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 94c08e8..6cb6bec 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -3090,6 +3090,37 @@ hns3_get_capability(struct hns3_hw *hw) + } + + static int ++hns3_check_media_type(struct hns3_hw *hw, uint8_t media_type) ++{ ++ int ret; ++ ++ switch (media_type) { ++ case HNS3_MEDIA_TYPE_COPPER: ++ if (!hns3_dev_copper_supported(hw)) { ++ PMD_INIT_LOG(ERR, ++ "Media type is copper, not supported."); ++ ret = -EOPNOTSUPP; ++ } else { ++ ret = 0; ++ } ++ break; ++ case HNS3_MEDIA_TYPE_FIBER: ++ ret = 0; ++ break; ++ case HNS3_MEDIA_TYPE_BACKPLANE: ++ PMD_INIT_LOG(ERR, "Media type is Backplane, not supported."); ++ ret = -EOPNOTSUPP; ++ break; ++ default: ++ PMD_INIT_LOG(ERR, "Unknown media type = %u!", media_type); ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int + hns3_get_board_configuration(struct hns3_hw *hw) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +@@ -3103,11 +3134,9 @@ hns3_get_board_configuration(struct hns3_hw *hw) + return ret; + } + +- 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; +- } ++ ret = hns3_check_media_type(hw, cfg.media_type); ++ if (ret) ++ return ret; + + hw->mac.media_type = cfg.media_type; + hw->rss_size_max = cfg.rss_size_max; +@@ -3952,6 +3981,8 @@ hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init) + if (is_init) { + hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1); + hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0); ++ if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) ++ hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1); + } + + req->compat = rte_cpu_to_le_32(compat); +@@ -4429,6 +4460,78 @@ hns3_update_fiber_link_info(struct hns3_hw *hw) + return hns3_cfg_mac_speed_dup(hw, speed, ETH_LINK_FULL_DUPLEX); + } + ++static void ++hns3_parse_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac) ++{ ++ struct hns3_phy_params_bd0_cmd *req; ++ ++ req = (struct hns3_phy_params_bd0_cmd *)desc[0].data; ++ mac->link_speed = rte_le_to_cpu_32(req->speed); ++ mac->link_duplex = hns3_get_bit(req->duplex, ++ HNS3_PHY_DUPLEX_CFG_B); ++ mac->link_autoneg = hns3_get_bit(req->autoneg, ++ HNS3_PHY_AUTONEG_CFG_B); ++ mac->supported_capa = rte_le_to_cpu_32(req->supported); ++ mac->advertising = rte_le_to_cpu_32(req->advertising); ++ mac->lp_advertising = rte_le_to_cpu_32(req->lp_advertising); ++ mac->support_autoneg = !!(mac->supported_capa & ++ HNS3_PHY_LINK_MODE_AUTONEG_BIT); ++} ++ ++static int ++hns3_get_phy_params(struct hns3_hw *hw, struct hns3_mac *mac) ++{ ++ struct hns3_cmd_desc desc[HNS3_PHY_PARAM_CFG_BD_NUM]; ++ uint16_t i; ++ int ret; ++ ++ for (i = 0; i < HNS3_PHY_PARAM_CFG_BD_NUM - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, ++ true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, true); ++ ++ ret = hns3_cmd_send(hw, desc, HNS3_PHY_PARAM_CFG_BD_NUM); ++ if (ret) { ++ hns3_err(hw, "get phy parameters failed, ret = %d.", ret); ++ return ret; ++ } ++ ++ hns3_parse_phy_params(desc, mac); ++ ++ return 0; ++} ++ ++static int ++hns3_update_phy_link_info(struct hns3_hw *hw) ++{ ++ struct hns3_mac *mac = &hw->mac; ++ struct hns3_mac mac_info; ++ int ret; ++ ++ memset(&mac_info, 0, sizeof(struct hns3_mac)); ++ ret = hns3_get_phy_params(hw, &mac_info); ++ if (ret) ++ return ret; ++ ++ if (mac_info.link_speed != mac->link_speed) { ++ ret = hns3_port_shaper_update(hw, mac_info.link_speed); ++ if (ret) ++ return ret; ++ } ++ ++ mac->link_speed = mac_info.link_speed; ++ mac->link_duplex = mac_info.link_duplex; ++ mac->link_autoneg = mac_info.link_autoneg; ++ mac->supported_capa = mac_info.supported_capa; ++ mac->advertising = mac_info.advertising; ++ mac->lp_advertising = mac_info.lp_advertising; ++ mac->support_autoneg = mac_info.support_autoneg; ++ ++ return 0; ++} ++ + static int + hns3_update_link_info(struct rte_eth_dev *eth_dev) + { +@@ -4437,7 +4540,7 @@ hns3_update_link_info(struct rte_eth_dev *eth_dev) + int ret = 0; + + if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) +- return 0; ++ ret = hns3_update_phy_link_info(hw); + else if (hw->mac.media_type == HNS3_MEDIA_TYPE_FIBER) + ret = hns3_update_fiber_link_info(hw); + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 2954422..3cbc2f2 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -180,6 +180,11 @@ struct hns3_mac { + uint8_t link_autoneg : 1; /* ETH_LINK_[AUTONEG/FIXED] */ + uint8_t link_status : 1; /* ETH_LINK_[DOWN/UP] */ + uint32_t link_speed; /* ETH_SPEED_NUM_ */ ++ uint32_t supported_capa; /* supported capability for current media */ ++ uint32_t advertising; /* advertised capability in the local part */ ++ /* advertised capability in the link partner */ ++ uint32_t lp_advertising; ++ uint8_t support_autoneg; + }; + + struct hns3_fake_queue_data { +-- +2.7.4 + diff --git a/0053-net-hns3-support-Rx-descriptor-advanced-layout.patch b/0053-net-hns3-support-Rx-descriptor-advanced-layout.patch new file mode 100644 index 0000000..14a81da --- /dev/null +++ b/0053-net-hns3-support-Rx-descriptor-advanced-layout.patch @@ -0,0 +1,442 @@ +From dd8dbf370b25e67e3ffaa845960c41c67775baa8 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 4 Mar 2021 15:44:49 +0800 +Subject: [PATCH 053/189] net/hns3: support Rx descriptor advanced layout + +Currently, the driver get packet type by parse the +L3_ID/L4_ID/OL3_ID/OL4_ID from Rx descriptor and then lookup multiple +tables, it's time consuming. + +Now Kunpeng930 support advanced RXD layout, which: +1. Combine OL3_ID/OL4_ID to 8bit PTYPE filed, so the driver get packet + type by lookup only one table. Note: L3_ID/L4_ID become reserved + fields. +2. The 1588 timestamp located at Rx descriptor instead of query from + firmware. +3. The L3E/L4E/OL3E/OL4E will be zero when L3L4P is zero, so driver + could optimize the good checksum calculations (when L3E/L4E is zero + then mark PKT_RX_IP_CKSUM_GOOD/PKT_RX_L4_CKSUM_GOOD). + +Considering compatibility, the firmware will report capability of +RXD advanced layout, the driver will identify and enable it by default. + +This patch only provides basic function: identify and enable the RXD +advanced layout, and lookup ptype table if supported. + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.c | 8 +- + drivers/net/hns3/hns3_cmd.h | 5 + + drivers/net/hns3/hns3_ethdev.c | 2 + + drivers/net/hns3/hns3_ethdev.h | 16 +++ + drivers/net/hns3/hns3_ethdev_vf.c | 2 + + drivers/net/hns3/hns3_regs.h | 1 + + drivers/net/hns3/hns3_rxtx.c | 200 ++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx.h | 11 +++ + 8 files changed, 243 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 0590898..8a2cc2d 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -409,8 +409,9 @@ hns3_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, int num) + return retval; + } + +-static void hns3_parse_capability(struct hns3_hw *hw, +- struct hns3_query_version_cmd *cmd) ++static void ++hns3_parse_capability(struct hns3_hw *hw, ++ struct hns3_query_version_cmd *cmd) + { + uint32_t caps = rte_le_to_cpu_32(cmd->caps[0]); + +@@ -429,6 +430,9 @@ static void hns3_parse_capability(struct hns3_hw *hw, + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_STASH_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_STASH_B, 1); ++ if (hns3_get_bit(caps, HNS3_CAPS_RXD_ADV_LAYOUT_B)) ++ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, ++ 1); + } + + static uint32_t +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 7f567cb..6ceb655 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -312,6 +312,11 @@ enum HNS3_CAPS_BITS { + HNS3_CAPS_TQP_TXRX_INDEP_B, + HNS3_CAPS_HW_PAD_B, + HNS3_CAPS_STASH_B, ++ HNS3_CAPS_UDP_TUNNEL_CSUM_B, ++ HNS3_CAPS_RAS_IMP_B, ++ HNS3_CAPS_FEC_B, ++ HNS3_CAPS_PAUSE_B, ++ HNS3_CAPS_RXD_ADV_LAYOUT_B, + }; + + enum HNS3_API_CAP_BITS { +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 6cb6bec..7993d2d 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4970,6 +4970,8 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + return ret; + } + ++ hns3_enable_rxd_adv_layout(hw); ++ + ret = hns3_init_queues(hns, reset_queue); + if (ret) { + PMD_INIT_LOG(ERR, "failed to init queues, ret = %d.", ret); +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 3cbc2f2..52e6c49 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -667,8 +667,13 @@ struct hns3_mp_param { + #define HNS3_OL2TBL_NUM 4 + #define HNS3_OL3TBL_NUM 16 + #define HNS3_OL4TBL_NUM 16 ++#define HNS3_PTYPE_NUM 256 + + struct hns3_ptype_table { ++ /* ++ * The next fields used to calc packet-type by the ++ * L3_ID/L4_ID/OL3_ID/OL4_ID from the Rx descriptor. ++ */ + uint32_t l2l3table[HNS3_L2TBL_NUM][HNS3_L3TBL_NUM]; + uint32_t l4table[HNS3_L4TBL_NUM]; + uint32_t inner_l2table[HNS3_L2TBL_NUM]; +@@ -677,6 +682,13 @@ struct hns3_ptype_table { + uint32_t ol2table[HNS3_OL2TBL_NUM]; + uint32_t ol3table[HNS3_OL3TBL_NUM]; + uint32_t ol4table[HNS3_OL4TBL_NUM]; ++ ++ /* ++ * The next field used to calc packet-type by the PTYPE from the Rx ++ * descriptor, it functions only when firmware report the capability of ++ * HNS3_CAPS_RXD_ADV_LAYOUT_B and driver enabled it. ++ */ ++ uint32_t ptype[HNS3_PTYPE_NUM] __rte_cache_min_aligned; + }; + + #define HNS3_FIXED_MAX_TQP_NUM_MODE 0 +@@ -771,6 +783,7 @@ struct hns3_adapter { + #define HNS3_DEV_SUPPORT_TX_PUSH_B 0x5 + #define HNS3_DEV_SUPPORT_INDEP_TXRX_B 0x6 + #define HNS3_DEV_SUPPORT_STASH_B 0x7 ++#define HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B 0x9 + + #define hns3_dev_dcb_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B) +@@ -801,6 +814,9 @@ struct hns3_adapter { + #define hns3_dev_stash_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_STASH_B) + ++#define hns3_dev_rxd_adv_layout_supported(hw) \ ++ hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B) ++ + #define HNS3_DEV_PRIVATE_TO_HW(adapter) \ + (&((struct hns3_adapter *)adapter)->hw) + #define HNS3_DEV_PRIVATE_TO_PF(adapter) \ +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 5b4c587..90951df 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2125,6 +2125,8 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) + if (ret) + return ret; + ++ hns3_enable_rxd_adv_layout(hw); ++ + ret = hns3_init_queues(hns, reset_queue); + if (ret) + hns3_err(hw, "failed to init queues, ret = %d.", ret); +diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h +index 39fc5d1..0540554 100644 +--- a/drivers/net/hns3/hns3_regs.h ++++ b/drivers/net/hns3/hns3_regs.h +@@ -36,6 +36,7 @@ + #define HNS3_GLOBAL_RESET_REG 0x20A00 + #define HNS3_FUN_RST_ING 0x20C00 + #define HNS3_GRO_EN_REG 0x28000 ++#define HNS3_RXD_ADV_LAYOUT_EN_REG 0x28008 + + /* Vector0 register bits for reset */ + #define HNS3_VECTOR0_FUNCRESET_INT_B 0 +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 897e5fa..09b38d4 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -1802,6 +1802,7 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + HNS3_PORT_BASE_VLAN_ENABLE; + else + rxq->pvid_sw_discard_en = false; ++ rxq->ptype_en = hns3_dev_rxd_adv_layout_supported(hw) ? true : false; + rxq->configured = true; + rxq->io_base = (void *)((char *)hw->io_base + HNS3_TQP_REG_OFFSET + + idx * HNS3_TQP_REG_SIZE); +@@ -1987,6 +1988,193 @@ hns3_init_tunnel_ptype_tbl(struct hns3_ptype_table *tbl) + tbl->ol4table[2] = RTE_PTYPE_TUNNEL_NVGRE; + } + ++static void ++hns3_init_adv_layout_ptype(struct hns3_ptype_table *tbl) ++{ ++ uint32_t *ptype = tbl->ptype; ++ ++ /* Non-tunnel L2 */ ++ ptype[1] = RTE_PTYPE_L2_ETHER_ARP; ++ ptype[3] = RTE_PTYPE_L2_ETHER_LLDP; ++ ptype[8] = RTE_PTYPE_L2_ETHER_TIMESYNC; ++ ++ /* Non-tunnel IPv4 */ ++ ptype[17] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_FRAG; ++ ptype[18] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_NONFRAG; ++ ptype[19] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_UDP; ++ ptype[20] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_TCP; ++ /* The next ptype is GRE over IPv4 */ ++ ptype[21] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; ++ ptype[22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_SCTP; ++ ptype[23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_IGMP; ++ ptype[24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_ICMP; ++ /* The next ptype is PTP over IPv4 + UDP */ ++ ptype[25] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_L4_UDP; ++ ++ /* IPv4 --> GRE/Teredo/VXLAN */ ++ ptype[29] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT; ++ /* IPv4 --> GRE/Teredo/VXLAN --> MAC */ ++ ptype[30] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER; ++ ++ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */ ++ ptype[31] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_FRAG; ++ ptype[32] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_NONFRAG; ++ ptype[33] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_UDP; ++ ptype[34] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_TCP; ++ ptype[35] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_SCTP; ++ /* The next ptype's inner L4 is IGMP */ ++ ptype[36] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; ++ ptype[37] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_ICMP; ++ ++ /* IPv4 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */ ++ ptype[39] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_FRAG; ++ ptype[40] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_NONFRAG; ++ ptype[41] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_UDP; ++ ptype[42] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_TCP; ++ ptype[43] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_SCTP; ++ /* The next ptype's inner L4 is IGMP */ ++ ptype[44] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; ++ ptype[45] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_ICMP; ++ ++ /* Non-tunnel IPv6 */ ++ ptype[111] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_FRAG; ++ ptype[112] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_NONFRAG; ++ ptype[113] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_UDP; ++ ptype[114] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_TCP; ++ /* The next ptype is GRE over IPv6 */ ++ ptype[115] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; ++ ptype[116] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_SCTP; ++ ptype[117] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_IGMP; ++ ptype[118] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_ICMP; ++ /* Special for PTP over IPv6 + UDP */ ++ ptype[119] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_L4_UDP; ++ ++ /* IPv6 --> GRE/Teredo/VXLAN */ ++ ptype[123] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT; ++ /* IPv6 --> GRE/Teredo/VXLAN --> MAC */ ++ ptype[124] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER; ++ ++ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv4 */ ++ ptype[125] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_FRAG; ++ ptype[126] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_NONFRAG; ++ ptype[127] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_UDP; ++ ptype[128] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_TCP; ++ ptype[129] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_SCTP; ++ /* The next ptype's inner L4 is IGMP */ ++ ptype[130] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; ++ ptype[131] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_ICMP; ++ ++ /* IPv6 --> GRE/Teredo/VXLAN --> MAC --> IPv6 */ ++ ptype[133] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_FRAG; ++ ptype[134] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_NONFRAG; ++ ptype[135] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_UDP; ++ ptype[136] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_TCP; ++ ptype[137] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_SCTP; ++ /* The next ptype's inner L4 is IGMP */ ++ ptype[138] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; ++ ptype[139] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_INNER_L4_ICMP; ++} ++ + void + hns3_init_rx_ptype_tble(struct rte_eth_dev *dev) + { +@@ -1997,6 +2185,7 @@ hns3_init_rx_ptype_tble(struct rte_eth_dev *dev) + + hns3_init_non_tunnel_ptype_tbl(tbl); + hns3_init_tunnel_ptype_tbl(tbl); ++ hns3_init_adv_layout_ptype(tbl); + } + + static inline void +@@ -4012,3 +4201,14 @@ hns3_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) + else + return fbd_num - driver_hold_bd_num; + } ++ ++void ++hns3_enable_rxd_adv_layout(struct hns3_hw *hw) ++{ ++ /* ++ * If the hardware support rxd advanced layout, then driver enable it ++ * default. ++ */ ++ if (hns3_dev_rxd_adv_layout_supported(hw)) ++ hns3_write_dev(hw, HNS3_RXD_ADV_LAYOUT_EN_REG, 1); ++} +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 7118bd4..9adeb24 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -88,6 +88,8 @@ + #define HNS3_RXD_OL3ID_M (0xf << HNS3_RXD_OL3ID_S) + #define HNS3_RXD_OL4ID_S 8 + #define HNS3_RXD_OL4ID_M (0xf << HNS3_RXD_OL4ID_S) ++#define HNS3_RXD_PTYPE_S 4 ++#define HNS3_RXD_PTYPE_M (0xff << HNS3_RXD_PTYPE_S) + #define HNS3_RXD_FBHI_S 12 + #define HNS3_RXD_FBHI_M (0x3 << HNS3_RXD_FBHI_S) + #define HNS3_RXD_FBLI_S 14 +@@ -328,6 +330,7 @@ struct hns3_rx_queue { + * point, the pvid_sw_discard_en will be false. + */ + bool pvid_sw_discard_en; ++ bool ptype_en; /* indicate if the ptype field enabled */ + bool enabled; /* indicate if Rx queue has been enabled */ + + struct hns3_rx_basic_stats basic_stats; +@@ -609,6 +612,13 @@ hns3_rx_calc_ptype(struct hns3_rx_queue *rxq, const uint32_t l234_info, + const struct hns3_ptype_table * const ptype_tbl = rxq->ptype_tbl; + uint32_t l2id, l3id, l4id; + uint32_t ol3id, ol4id, ol2id; ++ uint32_t ptype; ++ ++ if (rxq->ptype_en) { ++ ptype = hns3_get_field(ol_info, HNS3_RXD_PTYPE_M, ++ HNS3_RXD_PTYPE_S); ++ return ptype_tbl->ptype[ptype]; ++ } + + ol4id = hns3_get_field(ol_info, HNS3_RXD_OL4ID_M, HNS3_RXD_OL4ID_S); + ol3id = hns3_get_field(ol_info, HNS3_RXD_OL3ID_M, HNS3_RXD_OL3ID_S); +@@ -707,5 +717,6 @@ int hns3_start_all_rxqs(struct rte_eth_dev *dev); + void hns3_stop_all_txqs(struct rte_eth_dev *dev); + void hns3_restore_tqp_enable_state(struct hns3_hw *hw); + int hns3_tx_done_cleanup(void *txq, uint32_t free_cnt); ++void hns3_enable_rxd_adv_layout(struct hns3_hw *hw); + + #endif /* _HNS3_RXTX_H_ */ +-- +2.7.4 + diff --git a/0054-net-hns3-fix-HW-buffer-size-on-MTU-update.patch b/0054-net-hns3-fix-HW-buffer-size-on-MTU-update.patch new file mode 100644 index 0000000..a77fe4a --- /dev/null +++ b/0054-net-hns3-fix-HW-buffer-size-on-MTU-update.patch @@ -0,0 +1,78 @@ +From 7e76a11ae316966bb1094e3797a7f7c8fe4e3213 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 4 Mar 2021 15:44:50 +0800 +Subject: [PATCH 054/189] net/hns3: fix HW buffer size on MTU update + +After MTU changed, the buffer used to store packets in HW should be +reallocated. And buffer size is allocated based on the maximum frame +size in the PF struct. However, the value of maximum frame size is +not updated in time when MTU is changed. This would lead to a packet +loss for not enough buffer. + +This patch update the maximum frame size before reallocating the HW +buffer. And a rollback operation is added to avoid the side effects +of buffer reallocation failures. + +Fixes: 1f5ca0b460cd ("net/hns3: support some device operations") +Fixes: d51867db65c1 ("net/hns3: add initialization") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7993d2d..6a56a05 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2460,17 +2460,33 @@ hns3_set_mac_mtu(struct hns3_hw *hw, uint16_t new_mps) + static int + hns3_config_mtu(struct hns3_hw *hw, uint16_t mps) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ uint16_t original_mps = hns->pf.mps; ++ int err; + int ret; + + ret = hns3_set_mac_mtu(hw, mps); + if (ret) { +- hns3_err(hw, "Failed to set mtu, ret = %d", ret); ++ hns3_err(hw, "failed to set mtu, ret = %d", ret); + return ret; + } + ++ hns->pf.mps = mps; + ret = hns3_buffer_alloc(hw); +- if (ret) +- hns3_err(hw, "Failed to allocate buffer, ret = %d", ret); ++ if (ret) { ++ hns3_err(hw, "failed to allocate buffer, ret = %d", ret); ++ goto rollback; ++ } ++ ++ return 0; ++ ++rollback: ++ err = hns3_set_mac_mtu(hw, original_mps); ++ if (err) { ++ hns3_err(hw, "fail to rollback MTU, err = %d", err); ++ return ret; ++ } ++ hns->pf.mps = original_mps; + + return ret; + } +@@ -2505,7 +2521,7 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + dev->data->port_id, mtu, ret); + return ret; + } +- hns->pf.mps = (uint16_t)frame_size; ++ + if (is_jumbo_frame) + dev->data->dev_conf.rxmode.offloads |= + DEV_RX_OFFLOAD_JUMBO_FRAME; +-- +2.7.4 + diff --git a/0055-net-hns3-remove-unused-parameter-markers.patch b/0055-net-hns3-remove-unused-parameter-markers.patch new file mode 100644 index 0000000..b1b95ca --- /dev/null +++ b/0055-net-hns3-remove-unused-parameter-markers.patch @@ -0,0 +1,35 @@ +From 82c54c157d1cb684ef41a0ccdec0be4ecfa64a31 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 4 Mar 2021 15:44:51 +0800 +Subject: [PATCH 055/189] net/hns3: remove unused parameter markers + +All input parameters in the "hns3_dev_xstats_get_by_id" API are used, +so the rte_unused flag of some variables should be deleted. + +Fixes: 3213d584b698 ("net/hns3: fix xstats with id and names") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_stats.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h +index 01b4f36..70a9c5b 100644 +--- a/drivers/net/hns3/hns3_stats.h ++++ b/drivers/net/hns3/hns3_stats.h +@@ -156,8 +156,8 @@ 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, +- __rte_unused const uint64_t *ids, +- __rte_unused uint64_t *values, ++ const uint64_t *ids, ++ uint64_t *values, + uint32_t size); + int hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, +-- +2.7.4 + diff --git a/0056-net-hns3-fix-mbuf-leakage.patch b/0056-net-hns3-fix-mbuf-leakage.patch new file mode 100644 index 0000000..31a3424 --- /dev/null +++ b/0056-net-hns3-fix-mbuf-leakage.patch @@ -0,0 +1,200 @@ +From bd503f5817a2597e8431e02675a8c3847a31992e Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 4 Mar 2021 15:44:52 +0800 +Subject: [PATCH 056/189] net/hns3: fix mbuf leakage + +The mbufs of rx queue will be allocated in "hns3_do_start" function. +But these mbufs are not released when "hns3_dev_start" executes +failed. + +Fixes: c4ae39b2cfc5 ("net/hns3: fix Rx interrupt after reset") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_ethdev.c | 45 ++++++++++++++++++++++++--------------- + drivers/net/hns3/hns3_ethdev_vf.c | 43 ++++++++++++++++++++++--------------- + 2 files changed, 54 insertions(+), 34 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 6a56a05..1d56916 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -102,6 +102,7 @@ static int hns3_remove_mc_addr(struct hns3_hw *hw, + struct rte_ether_addr *mac_addr); + static int hns3_restore_fec(struct hns3_hw *hw); + static int hns3_query_dev_fec_info(struct hns3_hw *hw); ++static int hns3_do_stop(struct hns3_adapter *hns); + + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr) +@@ -5133,11 +5134,8 @@ hns3_dev_start(struct rte_eth_dev *dev) + return ret; + } + ret = hns3_map_rx_interrupt(dev); +- if (ret) { +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto map_rx_inter_err; + + /* + * There are three register used to control the status of a TQP +@@ -5151,19 +5149,12 @@ hns3_dev_start(struct rte_eth_dev *dev) + * status of queue in the dpdk framework. + */ + ret = hns3_start_all_txqs(dev); +- if (ret) { +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto map_rx_inter_err; + + ret = hns3_start_all_rxqs(dev); +- if (ret) { +- hns3_stop_all_txqs(dev); +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto start_all_rxqs_fail; + + hw->adapter_state = HNS3_NIC_STARTED; + rte_spinlock_unlock(&hw->lock); +@@ -5187,7 +5178,17 @@ hns3_dev_start(struct rte_eth_dev *dev) + hns3_tm_dev_start_proc(hw); + + hns3_info(hw, "hns3 dev start successful!"); ++ + return 0; ++ ++start_all_rxqs_fail: ++ hns3_stop_all_txqs(dev); ++map_rx_inter_err: ++ (void)hns3_do_stop(hns); ++ hw->adapter_state = HNS3_NIC_CONFIGURED; ++ rte_spinlock_unlock(&hw->lock); ++ ++ return ret; + } + + static int +@@ -5196,6 +5197,17 @@ hns3_do_stop(struct hns3_adapter *hns) + struct hns3_hw *hw = &hns->hw; + int ret; + ++ /* ++ * The "hns3_do_stop" function will also be called by .stop_service to ++ * prepare reset. At the time of global or IMP reset, the command cannot ++ * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be ++ * accessed during the reset process. So the mbuf can not be released ++ * during reset and is required to be released after the reset is ++ * completed. ++ */ ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) ++ hns3_dev_release_mbufs(hns); ++ + ret = hns3_cfg_mac_mode(hw, false); + if (ret) + return ret; +@@ -5273,7 +5285,6 @@ hns3_dev_stop(struct rte_eth_dev *dev) + hns3_stop_tqps(hw); + hns3_do_stop(hns); + hns3_unmap_rx_interrupt(dev); +- hns3_dev_release_mbufs(hns); + hw->adapter_state = HNS3_NIC_CONFIGURED; + } + hns3_rx_scattered_reset(dev); +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 90951df..12af105 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1941,6 +1941,17 @@ hns3vf_do_stop(struct hns3_adapter *hns) + + hw->mac.link_status = ETH_LINK_DOWN; + ++ /* ++ * The "hns3vf_do_stop" function will also be called by .stop_service to ++ * prepare reset. At the time of global or IMP reset, the command cannot ++ * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be ++ * accessed during the reset process. So the mbuf can not be released ++ * during reset and is required to be released after the reset is ++ * completed. ++ */ ++ if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) ++ hns3_dev_release_mbufs(hns); ++ + if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) { + hns3vf_configure_mac_addr(hns, true); + ret = hns3_reset_all_tqps(hns); +@@ -2010,7 +2021,6 @@ hns3vf_dev_stop(struct rte_eth_dev *dev) + hns3_stop_tqps(hw); + hns3vf_do_stop(hns); + hns3vf_unmap_rx_interrupt(dev); +- hns3_dev_release_mbufs(hns); + hw->adapter_state = HNS3_NIC_CONFIGURED; + } + hns3_rx_scattered_reset(dev); +@@ -2253,11 +2263,8 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + return ret; + } + ret = hns3vf_map_rx_interrupt(dev); +- if (ret) { +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto map_rx_inter_err; + + /* + * There are three register used to control the status of a TQP +@@ -2271,19 +2278,12 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + * status of queue in the dpdk framework. + */ + ret = hns3_start_all_txqs(dev); +- if (ret) { +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto map_rx_inter_err; + + ret = hns3_start_all_rxqs(dev); +- if (ret) { +- hns3_stop_all_txqs(dev); +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto start_all_rxqs_fail; + + hw->adapter_state = HNS3_NIC_STARTED; + rte_spinlock_unlock(&hw->lock); +@@ -2305,6 +2305,15 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + hns3_start_tqps(hw); + + return ret; ++ ++start_all_rxqs_fail: ++ hns3_stop_all_txqs(dev); ++map_rx_inter_err: ++ (void)hns3vf_do_stop(hns); ++ hw->adapter_state = HNS3_NIC_CONFIGURED; ++ rte_spinlock_unlock(&hw->lock); ++ ++ return ret; + } + + static bool +-- +2.7.4 + diff --git a/0057-net-hns3-process-MAC-interrupt.patch b/0057-net-hns3-process-MAC-interrupt.patch new file mode 100644 index 0000000..d02fa91 --- /dev/null +++ b/0057-net-hns3-process-MAC-interrupt.patch @@ -0,0 +1,211 @@ +From b9fbefb52b791730d5720946713e6cb187337652 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Thu, 4 Mar 2021 15:44:53 +0800 +Subject: [PATCH 057/189] net/hns3: process MAC interrupt + +TNL is the abbreviation of tunnel, which means port +here. MAC TNL interrupt indicates the MAC status +report of the network port, which will be generated +when the MAC status changes. + +This patch enables MAC TNL interrupt reporting, and +queries and prints the corresponding MAC status when +the interrupt is received, then clear the MAC interrupt +status. Because this interrupt uses the same interrupt +as RAS, the interrupt log is adjusted. + +Signed-off-by: Hongbo Zheng +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_cmd.h | 3 +++ + drivers/net/hns3/hns3_ethdev.c | 57 ++++++++++++++++++++++++++++++++++++------ + drivers/net/hns3/hns3_intr.c | 20 +++++++++++++++ + drivers/net/hns3/hns3_intr.h | 4 +++ + 4 files changed, 76 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 6ceb655..094bf7e 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -116,6 +116,9 @@ enum hns3_opcode_type { + HNS3_OPC_QUERY_LINK_STATUS = 0x0307, + HNS3_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, + HNS3_OPC_CONFIG_SPEED_DUP = 0x0309, ++ HNS3_OPC_QUERY_MAC_TNL_INT = 0x0310, ++ HNS3_OPC_MAC_TNL_INT_EN = 0x0311, ++ HNS3_OPC_CLEAR_MAC_TNL_INT = 0x0312, + HNS3_OPC_CONFIG_FEC_MODE = 0x031A, + + /* PFC/Pause commands */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 1d56916..80f91a7 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -217,9 +217,6 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + goto out; + } + +- if (clearval && (vector0_int_stats || cmdq_src_val || hw_err_src_reg)) +- hns3_warn(hw, "vector0_int_stats:0x%x cmdq_src_val:0x%x hw_err_src_reg:0x%x", +- vector0_int_stats, cmdq_src_val, hw_err_src_reg); + val = vector0_int_stats; + ret = HNS3_VECTOR0_EVENT_OTHER; + out: +@@ -258,6 +255,34 @@ hns3_clear_all_event_cause(struct hns3_hw *hw) + } + + static void ++hns3_handle_mac_tnl(struct hns3_hw *hw) ++{ ++ struct hns3_cmd_desc desc; ++ uint32_t status; ++ int ret; ++ ++ /* query and clear mac tnl interruptions */ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_TNL_INT, true); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "failed to query mac tnl int, ret = %d.", ret); ++ return; ++ } ++ ++ status = rte_le_to_cpu_32(desc.data[0]); ++ if (status) { ++ hns3_warn(hw, "mac tnl int occurs, status = 0x%x.", status); ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CLEAR_MAC_TNL_INT, ++ false); ++ desc.data[0] = rte_cpu_to_le_32(HNS3_MAC_TNL_INT_CLR); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) ++ hns3_err(hw, "failed to clear mac tnl int, ret = %d.", ++ ret); ++ } ++} ++ ++static void + hns3_interrupt_handler(void *param) + { + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; +@@ -265,24 +290,36 @@ hns3_interrupt_handler(void *param) + struct hns3_hw *hw = &hns->hw; + enum hns3_evt_cause event_cause; + uint32_t clearval = 0; ++ uint32_t vector0_int; ++ uint32_t ras_int; ++ uint32_t cmdq_int; + + /* Disable interrupt */ + hns3_pf_disable_irq0(hw); + + event_cause = hns3_check_event_cause(hns, &clearval); ++ vector0_int = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG); ++ ras_int = hns3_read_dev(hw, HNS3_RAS_PF_OTHER_INT_STS_REG); ++ cmdq_int = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG); + /* vector 0 interrupt is shared with reset and mailbox source events. */ + if (event_cause == HNS3_VECTOR0_EVENT_ERR) { +- hns3_warn(hw, "Received err interrupt"); ++ hns3_warn(hw, "received interrupt: vector0_int_stat:0x%x " ++ "ras_int_stat:0x%x cmdq_int_stat:0x%x", ++ vector0_int, ras_int, cmdq_int); + hns3_handle_msix_error(hns, &hw->reset.request); + hns3_handle_ras_error(hns, &hw->reset.request); ++ hns3_handle_mac_tnl(hw); + hns3_schedule_reset(hns); + } else if (event_cause == HNS3_VECTOR0_EVENT_RST) { +- hns3_warn(hw, "Received reset interrupt"); ++ hns3_warn(hw, "received reset interrupt"); + hns3_schedule_reset(hns); +- } else if (event_cause == HNS3_VECTOR0_EVENT_MBX) ++ } else if (event_cause == HNS3_VECTOR0_EVENT_MBX) { + hns3_dev_handle_mbx_msg(hw); +- else +- hns3_err(hw, "Received unknown event"); ++ } else { ++ hns3_warn(hw, "received unknown event: vector0_int_stat:0x%x " ++ "ras_int_stat:0x%x cmdq_int_stat:0x%x", ++ vector0_int, ras_int, cmdq_int); ++ } + + hns3_clear_event_cause(hw, event_cause, clearval); + /* Enable interrupt if it is not cause by reset */ +@@ -4639,6 +4676,8 @@ hns3_update_link_status(struct hns3_hw *hw) + if (state != hw->mac.link_status) { + hw->mac.link_status = state; + hns3_warn(hw, "Link status change to %s!", state ? "up" : "down"); ++ hns3_config_mac_tnl_int(hw, ++ state == ETH_LINK_UP ? true : false); + return true; + } + +@@ -4957,6 +4996,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) + (void)hns3_firmware_compat_config(hw, false); + hns3_uninit_umv_space(hw); + hns3_tqp_stats_uninit(hw); ++ hns3_config_mac_tnl_int(hw, false); + hns3_pf_disable_irq0(hw); + rte_intr_disable(&pci_dev->intr_handle); + hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, +@@ -5282,6 +5322,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) + rte_spinlock_lock(&hw->lock); + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { + hns3_tm_dev_stop_proc(hw); ++ hns3_config_mac_tnl_int(hw, false); + hns3_stop_tqps(hw); + hns3_do_stop(hns); + hns3_unmap_rx_interrupt(dev); +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 88ce4c6..2563504 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -1248,6 +1248,26 @@ enable_ssu_err_intr(struct hns3_adapter *hns, bool en) + return ret; + } + ++void ++hns3_config_mac_tnl_int(struct hns3_hw *hw, bool en) ++{ ++ struct hns3_cmd_desc desc; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MAC_TNL_INT_EN, false); ++ if (en) ++ desc.data[0] = rte_cpu_to_le_32(HNS3_MAC_TNL_INT_EN); ++ else ++ desc.data[0] = 0; ++ ++ desc.data[1] = rte_cpu_to_le_32(HNS3_MAC_TNL_INT_EN_MASK); ++ ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) ++ hns3_err(hw, "fail to %s mac tnl intr, ret = %d", ++ en ? "enable" : "disable", ret); ++} ++ + static int + config_ppu_err_intrs(struct hns3_adapter *hns, uint32_t cmd, bool en) + { +diff --git a/drivers/net/hns3/hns3_intr.h b/drivers/net/hns3/hns3_intr.h +index 19de1aa..c569a9d 100644 +--- a/drivers/net/hns3/hns3_intr.h ++++ b/drivers/net/hns3/hns3_intr.h +@@ -22,6 +22,9 @@ + + #define HNS3_MAC_COMMON_ERR_INT_EN 0x107FF + #define HNS3_MAC_COMMON_ERR_INT_EN_MASK 0x107FF ++#define HNS3_MAC_TNL_INT_EN GENMASK(9, 0) ++#define HNS3_MAC_TNL_INT_EN_MASK GENMASK(9, 0) ++#define HNS3_MAC_TNL_INT_CLR GENMASK(9, 0) + + #define HNS3_IMP_TCM_ECC_ERR_INT_EN 0xFFFF0000 + #define HNS3_IMP_TCM_ECC_ERR_INT_EN_MASK 0xFFFF0000 +@@ -99,6 +102,7 @@ struct hns3_hw_error_desc { + int hns3_enable_hw_error_intr(struct hns3_adapter *hns, bool state); + void hns3_handle_msix_error(struct hns3_adapter *hns, uint64_t *levels); + void hns3_handle_ras_error(struct hns3_adapter *hns, uint64_t *levels); ++void hns3_config_mac_tnl_int(struct hns3_hw *hw, bool en); + + void hns3_intr_unregister(const struct rte_intr_handle *hdl, + rte_intr_callback_fn cb_fn, void *cb_arg); +-- +2.7.4 + diff --git a/0058-net-hns3-fix-imprecise-statistics.patch b/0058-net-hns3-fix-imprecise-statistics.patch new file mode 100644 index 0000000..e6347f4 --- /dev/null +++ b/0058-net-hns3-fix-imprecise-statistics.patch @@ -0,0 +1,376 @@ +From 7905cce75947b36dc0d955234d0930367e86bc17 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 4 Mar 2021 15:44:54 +0800 +Subject: [PATCH 058/189] net/hns3: fix imprecise statistics + +Currently, the hns3 statistics may be inaccurate due to the +following two problems: + +1. Queue-level statistics are read from the firmware, and only one Rx or + Tx can be read at a time. This results in a large time interval + between reading multiple queues statistics in a stress scenario, such + as 1280 queues used by a PF or 256 functions used at the same time. + Especially when the 256 functions are used at the same time, the + interval between every two firmware commands in a function can be + huge, because the scheduling mechanism of the firmware is similar to + RR. + +2. The current statistics are read by type. The HW statistics are read + first, and then the software statistics are read. Due to preceding + reasons, HW reading may be time-consuming, which cause a + synchronization problem between SW and HW statistics of the same + queue. + +In this patch, queue-level statistics are directly read from the bar +instead of the firmware, and all the statistics of a queue include HW +and SW are read at a time to reduce inconsistency. + +Fixes: 8839c5e202f3 ("net/hns3: support device stats") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Lijun Ou +--- + drivers/net/hns3/hns3_stats.c | 221 ++++++++++++++---------------------------- + 1 file changed, 72 insertions(+), 149 deletions(-) + +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 87035e3..941c75f 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -367,7 +367,6 @@ static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = { + HNS3_NUM_RESET_XSTATS + HNS3_NUM_IMISSED_XSTATS) + + static void hns3_tqp_stats_clear(struct hns3_hw *hw); +-static void hns3_tqp_basic_stats_clear(struct rte_eth_dev *dev); + + /* + * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034. +@@ -481,49 +480,6 @@ hns3_query_update_mac_stats(struct rte_eth_dev *dev) + return ret; + } + +-/* Get tqp stats from register */ +-static int +-hns3_update_tqp_stats(struct hns3_hw *hw) +-{ +- struct hns3_tqp_stats *stats = &hw->tqp_stats; +- struct hns3_cmd_desc desc; +- uint64_t cnt; +- uint16_t i; +- int ret; +- +- for (i = 0; i < hw->tqps_num; i++) { +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_RX_STATUS, +- true); +- +- desc.data[0] = rte_cpu_to_le_32((uint32_t)i); +- ret = hns3_cmd_send(hw, &desc, 1); +- if (ret) { +- hns3_err(hw, "Failed to query RX No.%u queue stat: %d", +- i, ret); +- return ret; +- } +- cnt = rte_le_to_cpu_32(desc.data[1]); +- stats->rcb_rx_ring_pktnum_rcd += cnt; +- stats->rcb_rx_ring_pktnum[i] += cnt; +- +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_TX_STATUS, +- true); +- +- desc.data[0] = rte_cpu_to_le_32((uint32_t)i); +- ret = hns3_cmd_send(hw, &desc, 1); +- if (ret) { +- hns3_err(hw, "Failed to query TX No.%u queue stat: %d", +- i, ret); +- return ret; +- } +- cnt = rte_le_to_cpu_32(desc.data[1]); +- stats->rcb_tx_ring_pktnum_rcd += cnt; +- stats->rcb_tx_ring_pktnum[i] += cnt; +- } +- +- return 0; +-} +- + static int + hns3_update_rpu_drop_stats(struct hns3_hw *hw) + { +@@ -589,17 +545,11 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats; + struct hns3_tqp_stats *stats = &hw->tqp_stats; + struct hns3_rx_queue *rxq; ++ struct hns3_tx_queue *txq; + uint64_t cnt; + uint16_t i; + int ret; + +- /* Update tqp stats by read register */ +- ret = hns3_update_tqp_stats(hw); +- if (ret) { +- hns3_err(hw, "Update tqp stats fail : %d", ret); +- return ret; +- } +- + if (!hns->is_vf) { + /* Update imissed stats */ + ret = hns3_update_imissed_stats(hw, false); +@@ -612,24 +562,34 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt; + } + +- /* Get the error stats and bytes of received packets */ ++ /* Reads all the stats of a rxq in a loop to keep them synchronized */ + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; +- if (rxq) { +- cnt = rxq->err_stats.l2_errors + +- rxq->err_stats.pkt_len_errors; +- rte_stats->ierrors += cnt; ++ if (rxq == NULL) ++ continue; + +- rte_stats->ibytes += rxq->basic_stats.bytes; +- } ++ cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG); ++ /* ++ * Read hardware and software in adjacent positions to minumize ++ * the timing variance. ++ */ ++ rte_stats->ierrors += rxq->err_stats.l2_errors + ++ rxq->err_stats.pkt_len_errors; ++ stats->rcb_rx_ring_pktnum_rcd += cnt; ++ stats->rcb_rx_ring_pktnum[i] += cnt; ++ rte_stats->ibytes += rxq->basic_stats.bytes; + } + +- /* Get the bytes of received packets */ +- struct hns3_tx_queue *txq; ++ /* Reads all the stats of a txq in a loop to keep them synchronized */ + for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { + txq = eth_dev->data->tx_queues[i]; +- if (txq) +- rte_stats->obytes += txq->basic_stats.bytes; ++ if (txq == NULL) ++ continue; ++ ++ cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG); ++ stats->rcb_tx_ring_pktnum_rcd += cnt; ++ stats->rcb_tx_ring_pktnum[i] += cnt; ++ rte_stats->obytes += txq->basic_stats.bytes; + } + + rte_stats->oerrors = 0; +@@ -653,37 +613,11 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + { + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- struct hns3_cmd_desc desc_reset; + struct hns3_rx_queue *rxq; ++ struct hns3_tx_queue *txq; + uint16_t i; + int ret; + +- /* +- * Note: Reading hardware statistics of rx/tx queue packet number +- * will clear them. +- */ +- for (i = 0; i < hw->tqps_num; i++) { +- hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_RX_STATUS, +- true); +- desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i); +- ret = hns3_cmd_send(hw, &desc_reset, 1); +- if (ret) { +- hns3_err(hw, "Failed to reset RX No.%u queue stat: %d", +- i, ret); +- return ret; +- } +- +- hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_TX_STATUS, +- true); +- desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i); +- ret = hns3_cmd_send(hw, &desc_reset, 1); +- if (ret) { +- hns3_err(hw, "Failed to reset TX No.%u queue stat: %d", +- i, ret); +- return ret; +- } +- } +- + if (!hns->is_vf) { + /* + * Note: Reading hardware statistics of imissed registers will +@@ -697,25 +631,44 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + } + } + +- /* +- * Clear soft stats of rx error packet which will be dropped +- * in driver. +- */ + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; +- if (rxq) { +- rxq->err_stats.pkt_len_errors = 0; +- rxq->err_stats.l2_errors = 0; +- } ++ if (rxq == NULL) ++ continue; ++ ++ rxq->err_stats.pkt_len_errors = 0; ++ rxq->err_stats.l2_errors = 0; ++ } ++ ++ /* Clear all the stats of a rxq in a loop to keep them synchronized */ ++ for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { ++ rxq = eth_dev->data->rx_queues[i]; ++ if (rxq == NULL) ++ continue; ++ ++ memset(&rxq->basic_stats, 0, ++ sizeof(struct hns3_rx_basic_stats)); ++ ++ /* This register is read-clear */ ++ (void)hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG); ++ rxq->err_stats.pkt_len_errors = 0; ++ rxq->err_stats.l2_errors = 0; ++ } ++ ++ /* Clear all the stats of a txq in a loop to keep them synchronized */ ++ for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { ++ txq = eth_dev->data->tx_queues[i]; ++ if (txq == NULL) ++ continue; ++ ++ memset(&txq->basic_stats, 0, ++ sizeof(struct hns3_tx_basic_stats)); ++ ++ /* This register is read-clear */ ++ (void)hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG); + } + +- /* +- * 'packets' in hns3_tx_basic_stats and hns3_rx_basic_stats come +- * from hw->tqp_stats. And clearing tqp stats is like clearing +- * their source. +- */ + hns3_tqp_stats_clear(hw); +- hns3_tqp_basic_stats_clear(eth_dev); + + return 0; + } +@@ -881,6 +834,7 @@ hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + struct hns3_rx_basic_stats *rxq_stats; + struct hns3_rx_queue *rxq; + uint16_t i, j; ++ uint32_t cnt; + char *val; + + for (i = 0; i < dev->data->nb_rx_queues; i++) { +@@ -888,9 +842,17 @@ hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + if (rxq == NULL) + continue; + ++ cnt = hns3_read_dev(rxq, HNS3_RING_RX_PKTNUM_RECORD_REG); ++ /* ++ * Read hardware and software in adjacent positions to minimize ++ * the time difference. ++ */ + rxq_stats = &rxq->basic_stats; + rxq_stats->errors = rxq->err_stats.l2_errors + + rxq->err_stats.pkt_len_errors; ++ stats->rcb_rx_ring_pktnum_rcd += cnt; ++ stats->rcb_rx_ring_pktnum[i] += cnt; ++ + /* + * If HW statistics are reset by stats_reset, but a lot of + * residual packets exist in the hardware queue and these +@@ -919,6 +881,7 @@ hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + struct hns3_tx_basic_stats *txq_stats; + struct hns3_tx_queue *txq; + uint16_t i, j; ++ uint32_t cnt; + char *val; + + for (i = 0; i < dev->data->nb_tx_queues; i++) { +@@ -926,6 +889,10 @@ hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + if (txq == NULL) + continue; + ++ cnt = hns3_read_dev(txq, HNS3_RING_TX_PKTNUM_RECORD_REG); ++ stats->rcb_tx_ring_pktnum_rcd += cnt; ++ stats->rcb_tx_ring_pktnum[i] += cnt; ++ + txq_stats = &txq->basic_stats; + txq_stats->packets = stats->rcb_tx_ring_pktnum[i]; + +@@ -939,54 +906,12 @@ hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + } + } + +-static int ++static void + hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + int *count) + { +- struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- int ret; +- +- /* Update tqp stats by read register */ +- ret = hns3_update_tqp_stats(hw); +- if (ret) { +- hns3_err(hw, "Update tqp stats fail, ret = %d.", ret); +- return ret; +- } +- + hns3_rxq_basic_stats_get(dev, xstats, count); + hns3_txq_basic_stats_get(dev, xstats, count); +- +- return 0; +-} +- +-/* +- * The function is only called by hns3_dev_xstats_reset to clear +- * basic stats of per-queue. TQP stats are all cleared in hns3_stats_reset +- * which is called before this function. +- * +- * @param dev +- * Pointer to Ethernet device. +- */ +-static void +-hns3_tqp_basic_stats_clear(struct rte_eth_dev *dev) +-{ +- struct hns3_tx_queue *txq; +- struct hns3_rx_queue *rxq; +- uint16_t i; +- +- for (i = 0; i < dev->data->nb_rx_queues; i++) { +- rxq = dev->data->rx_queues[i]; +- if (rxq) +- memset(&rxq->basic_stats, 0, +- sizeof(struct hns3_rx_basic_stats)); +- } +- +- for (i = 0; i < dev->data->nb_tx_queues; i++) { +- txq = dev->data->tx_queues[i]; +- if (txq) +- memset(&txq->basic_stats, 0, +- sizeof(struct hns3_tx_basic_stats)); +- } + } + + /* +@@ -1028,9 +953,7 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + + count = 0; + +- ret = hns3_tqp_basic_stats_get(dev, xstats, &count); +- if (ret < 0) +- return ret; ++ hns3_tqp_basic_stats_get(dev, xstats, &count); + + if (!hns->is_vf) { + /* Update Mac stats */ +-- +2.7.4 + diff --git a/0059-net-hns3-add-runtime-config-to-select-IO-burst-funct.patch b/0059-net-hns3-add-runtime-config-to-select-IO-burst-funct.patch new file mode 100644 index 0000000..05a1b0e --- /dev/null +++ b/0059-net-hns3-add-runtime-config-to-select-IO-burst-funct.patch @@ -0,0 +1,341 @@ +From 20570791fbb46112707b5ddb21da9446da8a938d Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 23 Mar 2021 19:21:00 +0800 +Subject: [PATCH 059/189] net/hns3: add runtime config to select IO burst + function + +Currently, the driver support multiple IO burst function and auto +selection of the most appropriate function based on offload +configuration. + +Most applications such as l2fwd/l3fwd don't provide the means to +change offload configuration, so it will use the auto selection's io +burst function. + +This patch support runtime config to select io burst function, which +add two config: rx_func_hint and tx_func_hint, both could assign +vec/sve/simple/common. + +The driver will use the following rules to select io burst func: +a. if hint equal vec and meet the vec Rx/Tx usage condition then use the + neon function. +b. if hint equal sve and meet the sve Rx/Tx usage condition then use the + sve function. +c. if hint equal simple and meet the simple Rx/Tx usage condition then + use the simple function. +d. if hint equal common then use the common function. +e. if hint not set then: +e.1. if meet the vec Rx/Tx usage condition then use the neon function. +e.2. if meet the simple Rx/Tx usage condition then use the simple + function. +e.3. else use the common function. + +Note: the sve Rx/Tx usage condition based on the vec Rx/Tx usage +condition and runtime environment (which must support SVE). + +In the previous versions, driver will preferred use the sve function +when meet the sve Rx/Tx usage condition, but in this case driver could +get better performance if use the neon function. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/hns3.rst | 37 +++++++++++++++++++ + drivers/net/hns3/hns3_ethdev.c | 77 +++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_ethdev.h | 15 ++++++++ + drivers/net/hns3/hns3_ethdev_vf.c | 4 ++ + drivers/net/hns3/hns3_rxtx.c | 54 ++++++++++++++++++++------- + 5 files changed, 173 insertions(+), 14 deletions(-) + +diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst +index 8db8867..e8abd07 100644 +--- a/doc/guides/nics/hns3.rst ++++ b/doc/guides/nics/hns3.rst +@@ -46,6 +46,43 @@ Prerequisites + - Follow the DPDK :ref:`Getting Started Guide for Linux ` to setup the basic DPDK environment. + + ++Runtime Config Options ++---------------------- ++ ++- ``rx_func_hint`` (default ``none``) ++ ++ Used to select Rx burst function, supported value are ``vec``, ``sve``, ++ ``simple``, ``common``. ++ ``vec``, if supported use the ``vec`` Rx function which indicates the ++ default vector algorithm, neon for Kunpeng Arm platform. ++ ``sve``, if supported use the ``sve`` Rx function which indicates the ++ sve algorithm. ++ ``simple``, if supported use the ``simple`` Rx function which indicates ++ the scalar algorithm. ++ ``common``, if supported use the ``common`` Rx function which indicates ++ the scalar scattered algorithm. ++ ++ When provided parameter is not supported, ``vec`` usage condition will ++ be first checked, if meets, use the ``vec``. Then, ``simple``, at last ++ ``common``. ++ ++- ``tx_func_hint`` (default ``none``) ++ ++ Used to select Tx burst function, supported value are ``vec``, ``sve``, ++ ``simple``, ``common``. ++ ``vec``, if supported use the ``vec`` Tx function which indicates the ++ default vector algorithm, neon for Kunpeng Arm platform. ++ ``sve``, if supported use the ``sve`` Tx function which indicates the ++ sve algorithm. ++ ``simple``, if supported use the ``simple`` Tx function which indicates ++ the scalar simple algorithm. ++ ``common``, if supported use the ``common`` Tx function which indicates ++ the scalar algorithm. ++ ++ When provided parameter is not supported, ``vec`` usage condition will ++ be first checked, if meets, use the ``vec``. Then, ``simple``, at last ++ ``common``. ++ + Driver compilation and testing + ------------------------------ + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 80f91a7..f6ec8ac 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include "hns3_ethdev.h" + #include "hns3_logs.h" +@@ -6505,6 +6506,78 @@ hns3_get_module_info(struct rte_eth_dev *dev, + return 0; + } + ++static int ++hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args) ++{ ++ uint32_t hint = HNS3_IO_FUNC_HINT_NONE; ++ ++ RTE_SET_USED(key); ++ ++ if (strcmp(value, "vec") == 0) ++ hint = HNS3_IO_FUNC_HINT_VEC; ++ else if (strcmp(value, "sve") == 0) ++ hint = HNS3_IO_FUNC_HINT_SVE; ++ else if (strcmp(value, "simple") == 0) ++ hint = HNS3_IO_FUNC_HINT_SIMPLE; ++ else if (strcmp(value, "common") == 0) ++ hint = HNS3_IO_FUNC_HINT_COMMON; ++ ++ /* If the hint is valid then update output parameters */ ++ if (hint != HNS3_IO_FUNC_HINT_NONE) ++ *(uint32_t *)extra_args = hint; ++ ++ return 0; ++} ++ ++static const char * ++hns3_get_io_hint_func_name(uint32_t hint) ++{ ++ switch (hint) { ++ case HNS3_IO_FUNC_HINT_VEC: ++ return "vec"; ++ case HNS3_IO_FUNC_HINT_SVE: ++ return "sve"; ++ case HNS3_IO_FUNC_HINT_SIMPLE: ++ return "simple"; ++ case HNS3_IO_FUNC_HINT_COMMON: ++ return "common"; ++ default: ++ return "none"; ++ } ++} ++ ++void ++hns3_parse_devargs(struct rte_eth_dev *dev) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE; ++ uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE; ++ struct hns3_hw *hw = &hns->hw; ++ struct rte_kvargs *kvlist; ++ ++ if (dev->device->devargs == NULL) ++ return; ++ ++ kvlist = rte_kvargs_parse(dev->device->devargs->args, NULL); ++ if (!kvlist) ++ return; ++ ++ rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT, ++ &hns3_parse_io_hint_func, &rx_func_hint); ++ rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT, ++ &hns3_parse_io_hint_func, &tx_func_hint); ++ rte_kvargs_free(kvlist); ++ ++ if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE) ++ hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_RX_FUNC_HINT, ++ hns3_get_io_hint_func_name(rx_func_hint)); ++ hns->rx_func_hint = rx_func_hint; ++ if (tx_func_hint != HNS3_IO_FUNC_HINT_NONE) ++ hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT, ++ hns3_get_io_hint_func_name(tx_func_hint)); ++ hns->tx_func_hint = tx_func_hint; ++} ++ + static const struct eth_dev_ops hns3_eth_dev_ops = { + .dev_configure = hns3_dev_configure, + .dev_start = hns3_dev_start, +@@ -6625,6 +6698,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + hw->adapter_state = HNS3_NIC_UNINITIALIZED; + hns->is_vf = false; + hw->data = eth_dev->data; ++ hns3_parse_devargs(eth_dev); + + /* + * Set default max packet size according to the mtu +@@ -6758,5 +6832,8 @@ static struct rte_pci_driver rte_hns3_pmd = { + RTE_PMD_REGISTER_PCI(net_hns3, rte_hns3_pmd); + RTE_PMD_REGISTER_PCI_TABLE(net_hns3, pci_id_hns3_map); + RTE_PMD_REGISTER_KMOD_DEP(net_hns3, "* igb_uio | vfio-pci"); ++RTE_PMD_REGISTER_PARAM_STRING(net_hns3, ++ HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common " ++ HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "); + RTE_LOG_REGISTER(hns3_logtype_init, pmd.net.hns3.init, NOTICE); + RTE_LOG_REGISTER(hns3_logtype_driver, pmd.net.hns3.driver, NOTICE); +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 52e6c49..67a69ba 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -772,9 +772,23 @@ struct hns3_adapter { + bool tx_simple_allowed; + bool tx_vec_allowed; + ++ uint32_t rx_func_hint; ++ uint32_t tx_func_hint; ++ + struct hns3_ptype_table ptype_tbl __rte_cache_min_aligned; + }; + ++enum { ++ HNS3_IO_FUNC_HINT_NONE = 0, ++ HNS3_IO_FUNC_HINT_VEC, ++ HNS3_IO_FUNC_HINT_SVE, ++ HNS3_IO_FUNC_HINT_SIMPLE, ++ HNS3_IO_FUNC_HINT_COMMON ++}; ++ ++#define HNS3_DEVARG_RX_FUNC_HINT "rx_func_hint" ++#define HNS3_DEVARG_TX_FUNC_HINT "tx_func_hint" ++ + #define HNS3_DEV_SUPPORT_DCB_B 0x0 + #define HNS3_DEV_SUPPORT_COPPER_B 0x1 + #define HNS3_DEV_SUPPORT_UDP_GSO_B 0x2 +@@ -975,6 +989,7 @@ int hns3_dev_infos_get(struct rte_eth_dev *eth_dev, + struct rte_eth_dev_info *info); + void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status, + uint32_t link_speed, uint8_t link_duplex); ++void hns3_parse_devargs(struct rte_eth_dev *dev); + + static inline bool + is_reset_pending(struct hns3_adapter *hns) +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 12af105..a4fd8ca 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2834,6 +2834,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) + hw->adapter_state = HNS3_NIC_UNINITIALIZED; + hns->is_vf = true; + hw->data = eth_dev->data; ++ hns3_parse_devargs(eth_dev); + + ret = hns3_reset_init(hw); + if (ret) +@@ -2962,3 +2963,6 @@ static struct rte_pci_driver rte_hns3vf_pmd = { + RTE_PMD_REGISTER_PCI(net_hns3_vf, rte_hns3vf_pmd); + RTE_PMD_REGISTER_PCI_TABLE(net_hns3_vf, pci_id_hns3vf_map); + RTE_PMD_REGISTER_KMOD_DEP(net_hns3_vf, "* igb_uio | vfio-pci"); ++RTE_PMD_REGISTER_PARAM_STRING(net_hns3_vf, ++ HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common " ++ HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "); +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 09b38d4..8e927f1 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2689,13 +2689,26 @@ hns3_get_rx_function(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; + uint64_t offloads = dev->data->dev_conf.rxmode.offloads; ++ bool vec_allowed, sve_allowed, simple_allowed; ++ ++ vec_allowed = hns->rx_vec_allowed && ++ hns3_rx_check_vec_support(dev) == 0; ++ sve_allowed = vec_allowed && hns3_check_sve_support(); ++ simple_allowed = hns->rx_simple_allowed && !dev->data->scattered_rx && ++ (offloads & DEV_RX_OFFLOAD_TCP_LRO) == 0; ++ ++ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed) ++ return hns3_recv_pkts_vec; ++ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_SVE && sve_allowed) ++ return hns3_recv_pkts_vec_sve; ++ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed) ++ return hns3_recv_pkts; ++ if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_COMMON) ++ return hns3_recv_scattered_pkts; + +- if (hns->rx_vec_allowed && hns3_rx_check_vec_support(dev) == 0) +- return hns3_check_sve_support() ? hns3_recv_pkts_vec_sve : +- hns3_recv_pkts_vec; +- +- if (hns->rx_simple_allowed && !dev->data->scattered_rx && +- (offloads & DEV_RX_OFFLOAD_TCP_LRO) == 0) ++ if (vec_allowed) ++ return hns3_recv_pkts_vec; ++ if (simple_allowed) + return hns3_recv_pkts; + + return hns3_recv_scattered_pkts; +@@ -3930,19 +3943,32 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + { + uint64_t offloads = dev->data->dev_conf.txmode.offloads; + struct hns3_adapter *hns = dev->data->dev_private; ++ bool vec_allowed, sve_allowed, simple_allowed; + +- if (hns->tx_vec_allowed && hns3_tx_check_vec_support(dev) == 0) { +- *prep = NULL; +- return hns3_check_sve_support() ? hns3_xmit_pkts_vec_sve : +- hns3_xmit_pkts_vec; +- } ++ vec_allowed = hns->tx_vec_allowed && ++ hns3_tx_check_vec_support(dev) == 0; ++ sve_allowed = vec_allowed && hns3_check_sve_support(); ++ simple_allowed = hns->tx_simple_allowed && ++ offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE); + +- if (hns->tx_simple_allowed && +- offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE)) { +- *prep = NULL; ++ *prep = NULL; ++ ++ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed) ++ return hns3_xmit_pkts_vec; ++ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_SVE && sve_allowed) ++ return hns3_xmit_pkts_vec_sve; ++ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed) + return hns3_xmit_pkts_simple; ++ if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_COMMON) { ++ *prep = hns3_prep_pkts; ++ return hns3_xmit_pkts; + } + ++ if (vec_allowed) ++ return hns3_xmit_pkts_vec; ++ if (simple_allowed) ++ return hns3_xmit_pkts_simple; ++ + *prep = hns3_prep_pkts; + return hns3_xmit_pkts; + } +-- +2.7.4 + diff --git a/0060-net-hns3-support-outer-UDP-checksum.patch b/0060-net-hns3-support-outer-UDP-checksum.patch new file mode 100644 index 0000000..98bf5c0 --- /dev/null +++ b/0060-net-hns3-support-outer-UDP-checksum.patch @@ -0,0 +1,292 @@ +From a9ababcfe9b34d979359f023833fbaebbb04e9d0 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Tue, 23 Mar 2021 19:21:01 +0800 +Subject: [PATCH 060/189] net/hns3: support outer UDP checksum + +Kunpeng930 support outer UDP cksum, this patch add support for it. + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 3 ++ + drivers/net/hns3/hns3_ethdev.c | 3 ++ + drivers/net/hns3/hns3_ethdev.h | 4 ++ + drivers/net/hns3/hns3_ethdev_vf.c | 3 ++ + drivers/net/hns3/hns3_rxtx.c | 85 +++++++++++++++++++++++++++++------- + drivers/net/hns3/hns3_rxtx.h | 4 +- + drivers/net/hns3/hns3_rxtx_vec_sve.c | 5 ++- + 7 files changed, 88 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 8a2cc2d..f8d8b0a 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -433,6 +433,9 @@ hns3_parse_capability(struct hns3_hw *hw, + if (hns3_get_bit(caps, HNS3_CAPS_RXD_ADV_LAYOUT_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, + 1); ++ if (hns3_get_bit(caps, HNS3_CAPS_UDP_TUNNEL_CSUM_B)) ++ hns3_set_bit(hw->capability, ++ HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, 1); + } + + static uint32_t +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index f6ec8ac..5da00b3 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2620,6 +2620,9 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + DEV_TX_OFFLOAD_MBUF_FAST_FREE | + hns3_txvlan_cap_get(hw)); + ++ if (hns3_dev_outer_udp_cksum_supported(hw)) ++ info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_UDP_CKSUM; ++ + if (hns3_dev_indep_txrx_supported(hw)) + info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 67a69ba..dc27bb1 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -798,6 +798,7 @@ enum { + #define HNS3_DEV_SUPPORT_INDEP_TXRX_B 0x6 + #define HNS3_DEV_SUPPORT_STASH_B 0x7 + #define HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B 0x9 ++#define HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B 0xA + + #define hns3_dev_dcb_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B) +@@ -831,6 +832,9 @@ enum { + #define hns3_dev_rxd_adv_layout_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B) + ++#define hns3_dev_outer_udp_cksum_supported(hw) \ ++ hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B) ++ + #define HNS3_DEV_PRIVATE_TO_HW(adapter) \ + (&((struct hns3_adapter *)adapter)->hw) + #define HNS3_DEV_PRIVATE_TO_PF(adapter) \ +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index a4fd8ca..35c42ca 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -988,6 +988,9 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + DEV_TX_OFFLOAD_MBUF_FAST_FREE | + hns3_txvlan_cap_get(hw)); + ++ if (hns3_dev_outer_udp_cksum_supported(hw)) ++ info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_UDP_CKSUM; ++ + if (hns3_dev_indep_txrx_supported(hw)) + info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 8e927f1..404c403 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2967,7 +2967,7 @@ hns3_fill_first_desc(struct hns3_tx_queue *txq, struct hns3_desc *desc, + 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); ++ desc->tx.paylen_fd_dop_ol4cs |= rte_cpu_to_le_32(paylen); + hns3_set_tso(desc, paylen, rxm); + + /* +@@ -3204,8 +3204,10 @@ hns3_parse_tunneling_params(struct hns3_tx_queue *txq, struct rte_mbuf *m, + { + struct hns3_desc *tx_ring = txq->tx_ring; + struct hns3_desc *desc = &tx_ring[tx_desc_id]; ++ uint64_t ol_flags = m->ol_flags; + uint32_t tmp_outer = 0; + uint32_t tmp_inner = 0; ++ uint32_t tmp_ol4cs; + int ret; + + /* +@@ -3215,7 +3217,7 @@ hns3_parse_tunneling_params(struct hns3_tx_queue *txq, struct rte_mbuf *m, + * calculations, the length of the L2 header include the outer and + * inner, will be filled during the parsing of tunnel packects. + */ +- if (!(m->ol_flags & PKT_TX_TUNNEL_MASK)) { ++ if (!(ol_flags & PKT_TX_TUNNEL_MASK)) { + /* + * For non tunnel type the tunnel type id is 0, so no need to + * assign a value to it. Only the inner(normal) L2 header length +@@ -3230,7 +3232,8 @@ hns3_parse_tunneling_params(struct hns3_tx_queue *txq, struct rte_mbuf *m, + * inner l2_len. It would lead a cksum error. So driver has to + * calculate the header length. + */ +- if (unlikely(!(m->ol_flags & PKT_TX_OUTER_IP_CKSUM) && ++ if (unlikely(!(ol_flags & ++ (PKT_TX_OUTER_IP_CKSUM | PKT_TX_OUTER_UDP_CKSUM)) && + m->outer_l2_len == 0)) { + struct rte_net_hdr_lens hdr_len; + (void)rte_net_get_ptype(m, &hdr_len, +@@ -3247,6 +3250,9 @@ hns3_parse_tunneling_params(struct hns3_tx_queue *txq, struct rte_mbuf *m, + + desc->tx.ol_type_vlan_len_msec = rte_cpu_to_le_32(tmp_outer); + desc->tx.type_cs_vlan_tso_len = rte_cpu_to_le_32(tmp_inner); ++ tmp_ol4cs = ol_flags & PKT_TX_OUTER_UDP_CKSUM ? ++ BIT(HNS3_TXD_OL4CS_B) : 0; ++ desc->tx.paylen_fd_dop_ol4cs = rte_cpu_to_le_32(tmp_ol4cs); + + return 0; + } +@@ -3376,31 +3382,78 @@ hns3_pkt_need_linearized(struct rte_mbuf *tx_pkts, uint32_t bd_num, + return false; + } + ++static bool ++hns3_outer_ipv4_cksum_prepared(struct rte_mbuf *m, uint64_t ol_flags, ++ uint32_t *l4_proto) ++{ ++ struct rte_ipv4_hdr *ipv4_hdr; ++ ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *, ++ m->outer_l2_len); ++ if (ol_flags & PKT_TX_OUTER_IP_CKSUM) ++ ipv4_hdr->hdr_checksum = 0; ++ if (ol_flags & PKT_TX_OUTER_UDP_CKSUM) { ++ struct rte_udp_hdr *udp_hdr; ++ /* ++ * If OUTER_UDP_CKSUM is support, HW can caclulate the pseudo ++ * header for TSO packets ++ */ ++ if (ol_flags & PKT_TX_TCP_SEG) ++ return true; ++ udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *, ++ m->outer_l2_len + m->outer_l3_len); ++ udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags); ++ ++ return true; ++ } ++ *l4_proto = ipv4_hdr->next_proto_id; ++ return false; ++} ++ ++static bool ++hns3_outer_ipv6_cksum_prepared(struct rte_mbuf *m, uint64_t ol_flags, ++ uint32_t *l4_proto) ++{ ++ struct rte_ipv6_hdr *ipv6_hdr; ++ ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *, ++ m->outer_l2_len); ++ if (ol_flags & PKT_TX_OUTER_UDP_CKSUM) { ++ struct rte_udp_hdr *udp_hdr; ++ /* ++ * If OUTER_UDP_CKSUM is support, HW can caclulate the pseudo ++ * header for TSO packets ++ */ ++ if (ol_flags & PKT_TX_TCP_SEG) ++ return true; ++ udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *, ++ m->outer_l2_len + m->outer_l3_len); ++ udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags); ++ ++ return true; ++ } ++ *l4_proto = ipv6_hdr->proto; ++ return false; ++} ++ + static void + hns3_outer_header_cksum_prepare(struct rte_mbuf *m) + { + uint64_t ol_flags = m->ol_flags; + uint32_t paylen, hdr_len, l4_proto; ++ struct rte_udp_hdr *udp_hdr; + + if (!(ol_flags & (PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IPV6))) + return; + + if (ol_flags & PKT_TX_OUTER_IPV4) { +- struct rte_ipv4_hdr *ipv4_hdr; +- ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *, +- m->outer_l2_len); +- l4_proto = ipv4_hdr->next_proto_id; +- if (ol_flags & PKT_TX_OUTER_IP_CKSUM) +- ipv4_hdr->hdr_checksum = 0; ++ if (hns3_outer_ipv4_cksum_prepared(m, ol_flags, &l4_proto)) ++ return; + } else { +- struct rte_ipv6_hdr *ipv6_hdr; +- ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *, +- m->outer_l2_len); +- l4_proto = ipv6_hdr->proto; ++ if (hns3_outer_ipv6_cksum_prepared(m, ol_flags, &l4_proto)) ++ return; + } ++ + /* driver should ensure the outer udp cksum is 0 for TUNNEL TSO */ + if (l4_proto == IPPROTO_UDP && (ol_flags & PKT_TX_TCP_SEG)) { +- struct rte_udp_hdr *udp_hdr; + hdr_len = m->l2_len + m->l3_len + m->l4_len; + hdr_len += m->outer_l2_len + m->outer_l3_len; + paylen = m->pkt_len - hdr_len; +@@ -3686,7 +3739,7 @@ hns3_tx_setup_4bd(struct hns3_desc *txdp, struct rte_mbuf **pkts) + dma_addr = rte_mbuf_data_iova(*pkts); + txdp->addr = rte_cpu_to_le_64(dma_addr); + txdp->tx.send_size = rte_cpu_to_le_16((*pkts)->data_len); +- txdp->tx.paylen = 0; ++ txdp->tx.paylen_fd_dop_ol4cs = 0; + txdp->tx.type_cs_vlan_tso_len = 0; + txdp->tx.ol_type_vlan_len_msec = 0; + txdp->tx.tp_fe_sc_vld_ra_ri = rte_cpu_to_le_16(bd_flag); +@@ -3702,7 +3755,7 @@ hns3_tx_setup_1bd(struct hns3_desc *txdp, struct rte_mbuf **pkts) + dma_addr = rte_mbuf_data_iova(*pkts); + txdp->addr = rte_cpu_to_le_64(dma_addr); + txdp->tx.send_size = rte_cpu_to_le_16((*pkts)->data_len); +- txdp->tx.paylen = 0; ++ txdp->tx.paylen_fd_dop_ol4cs = 0; + txdp->tx.type_cs_vlan_tso_len = 0; + txdp->tx.ol_type_vlan_len_msec = 0; + txdp->tx.tp_fe_sc_vld_ra_ri = rte_cpu_to_le_16(bd_flag); +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 9adeb24..cd04200 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -149,6 +149,7 @@ + #define HNS3_TXD_MSS_S 0 + #define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S) + ++#define HNS3_TXD_OL4CS_B 22 + #define HNS3_L2_LEN_UNIT 1UL + #define HNS3_L3_LEN_UNIT 2UL + #define HNS3_L4_LEN_UNIT 2UL +@@ -234,7 +235,7 @@ struct hns3_desc { + }; + }; + +- uint32_t paylen; ++ uint32_t paylen_fd_dop_ol4cs; + uint16_t tp_fe_sc_vld_ra_ri; + uint16_t mss; + } tx; +@@ -503,6 +504,7 @@ struct hns3_queue_info { + }; + + #define HNS3_TX_CKSUM_OFFLOAD_MASK ( \ ++ PKT_TX_OUTER_UDP_CKSUM | \ + PKT_TX_OUTER_IP_CKSUM | \ + PKT_TX_IP_CKSUM | \ + PKT_TX_TCP_SEG | \ +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index 947c19f..f6c6f52 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -408,8 +408,9 @@ hns3_tx_fill_hw_ring_sve(struct hns3_tx_queue *txq, + (uint64_t *)&txdp->tx.outer_vlan_tag, + offsets, svdup_n_u64(0)); + /* save offset 24~31byte of every BD */ +- svst1_scatter_u64offset_u64(pg, (uint64_t *)&txdp->tx.paylen, +- offsets, svdup_n_u64(valid_bit)); ++ svst1_scatter_u64offset_u64(pg, ++ (uint64_t *)&txdp->tx.paylen_fd_dop_ol4cs, ++ offsets, svdup_n_u64(valid_bit)); + + /* Increment bytes counter */ + uint32_t idx; +-- +2.7.4 + diff --git a/0061-net-hns3-adjust-format-of-RAS-related-structures.patch b/0061-net-hns3-adjust-format-of-RAS-related-structures.patch new file mode 100644 index 0000000..c7ff1b7 --- /dev/null +++ b/0061-net-hns3-adjust-format-of-RAS-related-structures.patch @@ -0,0 +1,2251 @@ +From 8d96829c74a9177cd4958c25946ae7ccf3db1957 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Tue, 23 Mar 2021 19:21:02 +0800 +Subject: [PATCH 061/189] net/hns3: adjust format of RAS related structures + +Adjust the format of hns3 RAS related structures to resolve +the static check warnings. + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_intr.c | 2126 ++++++++++++++++++++++++------------------ + 1 file changed, 1224 insertions(+), 902 deletions(-) + +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 2563504..265dae8 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -28,282 +28,375 @@ static const char *reset_string[HNS3_MAX_RESET] = { + }; + + static const struct hns3_hw_error mac_afifo_tnl_int[] = { +- { .int_msk = BIT(0), +- .msg = "egu_cge_afifo_ecc_1bit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(1), +- .msg = "egu_cge_afifo_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "egu_lge_afifo_ecc_1bit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(3), +- .msg = "egu_lge_afifo_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "cge_igu_afifo_ecc_1bit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(5), +- .msg = "cge_igu_afifo_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "lge_igu_afifo_ecc_1bit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(7), +- .msg = "lge_igu_afifo_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "cge_igu_afifo_overflow_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "lge_igu_afifo_overflow_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(10), +- .msg = "egu_cge_afifo_underrun_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "egu_lge_afifo_underrun_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(12), +- .msg = "egu_ge_afifo_underrun_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "ge_igu_afifo_overflow_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "egu_cge_afifo_ecc_1bit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "egu_cge_afifo_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "egu_lge_afifo_ecc_1bit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "egu_lge_afifo_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "cge_igu_afifo_ecc_1bit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "cge_igu_afifo_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "lge_igu_afifo_ecc_1bit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "lge_igu_afifo_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "cge_igu_afifo_overflow_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "lge_igu_afifo_overflow_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(10), ++ .msg = "egu_cge_afifo_underrun_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "egu_lge_afifo_underrun_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(12), ++ .msg = "egu_ge_afifo_underrun_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "ge_igu_afifo_overflow_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppu_mpf_abnormal_int_st1[] = { +- { .int_msk = 0xFFFFFFFF, +- .msg = "rpu_rx_pkt_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = 0xFFFFFFFF, ++ .msg = "rpu_rx_pkt_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppu_mpf_abnormal_int_st2_ras[] = { +- { .int_msk = BIT(13), +- .msg = "rpu_rx_pkt_bit32_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(14), +- .msg = "rpu_rx_pkt_bit33_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(15), +- .msg = "rpu_rx_pkt_bit34_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(16), +- .msg = "rpu_rx_pkt_bit35_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(17), +- .msg = "rcb_tx_ring_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(18), +- .msg = "rcb_rx_ring_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(19), +- .msg = "rcb_tx_fbd_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(20), +- .msg = "rcb_rx_ebd_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(21), +- .msg = "rcb_tso_info_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(22), +- .msg = "rcb_tx_int_info_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(23), +- .msg = "rcb_rx_int_info_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(24), +- .msg = "tpu_tx_pkt_0_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(25), +- .msg = "tpu_tx_pkt_1_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(26), +- .msg = "rd_bus_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(27), +- .msg = "wr_bus_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(30), +- .msg = "ooo_ecc_err_detect", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(31), +- .msg = "ooo_ecc_err_multpl", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(13), ++ .msg = "rpu_rx_pkt_bit32_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(14), ++ .msg = "rpu_rx_pkt_bit33_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "rpu_rx_pkt_bit34_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(16), ++ .msg = "rpu_rx_pkt_bit35_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "rcb_tx_ring_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(18), ++ .msg = "rcb_rx_ring_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(19), ++ .msg = "rcb_tx_fbd_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(20), ++ .msg = "rcb_rx_ebd_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(21), ++ .msg = "rcb_tso_info_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(22), ++ .msg = "rcb_tx_int_info_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(23), ++ .msg = "rcb_rx_int_info_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(24), ++ .msg = "tpu_tx_pkt_0_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(25), ++ .msg = "tpu_tx_pkt_1_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(26), ++ .msg = "rd_bus_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(27), ++ .msg = "wr_bus_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(30), ++ .msg = "ooo_ecc_err_detect", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(31), ++ .msg = "ooo_ecc_err_multpl", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppu_mpf_abnormal_int_st2_msix[] = { +- { .int_msk = BIT(29), +- .msg = "rx_q_search_miss", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(29), ++ .msg = "rx_q_search_miss", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ssu_port_based_pf_int[] = { +- { .int_msk = BIT(0), +- .msg = "roc_pkt_without_key_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "low_water_line_err_port", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "roc_pkt_without_key_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "low_water_line_err_port", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppp_pf_abnormal_int[] = { +- { .int_msk = BIT(0), +- .msg = "tx_vlan_tag_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(1), +- .msg = "rss_list_tc_unassigned_queue_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "tx_vlan_tag_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "rss_list_tc_unassigned_queue_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppu_pf_abnormal_int_ras[] = { +- { .int_msk = BIT(3), +- .msg = "tx_rd_fbd_poison", +- .reset_level = HNS3_FUNC_RESET }, +- { .int_msk = BIT(4), +- .msg = "rx_rd_ebd_poison", +- .reset_level = HNS3_FUNC_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(3), ++ .msg = "tx_rd_fbd_poison", ++ .reset_level = HNS3_FUNC_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "rx_rd_ebd_poison", ++ .reset_level = HNS3_FUNC_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppu_pf_abnormal_int_msix[] = { +- { .int_msk = BIT(0), +- .msg = "over_8bd_no_fe", +- .reset_level = HNS3_FUNC_RESET }, +- { .int_msk = BIT(1), +- .msg = "tso_mss_cmp_min_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(2), +- .msg = "tso_mss_cmp_max_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(5), +- .msg = "buf_wait_timeout", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "over_8bd_no_fe", ++ .reset_level = HNS3_FUNC_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "tso_mss_cmp_min_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "tso_mss_cmp_max_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "buf_wait_timeout", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error imp_tcm_ecc_int[] = { +- { .int_msk = BIT(1), +- .msg = "imp_itcm0_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(3), +- .msg = "imp_itcm1_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(5), +- .msg = "imp_itcm2_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(7), +- .msg = "imp_itcm3_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(9), +- .msg = "imp_dtcm0_mem0_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(11), +- .msg = "imp_dtcm0_mem1_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(13), +- .msg = "imp_dtcm1_mem0_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(15), +- .msg = "imp_dtcm1_mem1_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(17), +- .msg = "imp_itcm4_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(1), ++ .msg = "imp_itcm0_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "imp_itcm1_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "imp_itcm2_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "imp_itcm3_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "imp_dtcm0_mem0_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "imp_dtcm0_mem1_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "imp_dtcm1_mem0_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "imp_dtcm1_mem1_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "imp_itcm4_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error cmdq_mem_ecc_int[] = { +- { .int_msk = BIT(1), +- .msg = "cmdq_nic_rx_depth_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(3), +- .msg = "cmdq_nic_tx_depth_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(5), +- .msg = "cmdq_nic_rx_tail_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(7), +- .msg = "cmdq_nic_tx_tail_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(9), +- .msg = "cmdq_nic_rx_head_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(11), +- .msg = "cmdq_nic_tx_head_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(13), +- .msg = "cmdq_nic_rx_addr_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(15), +- .msg = "cmdq_nic_tx_addr_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(1), ++ .msg = "cmdq_nic_rx_depth_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "cmdq_nic_tx_depth_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "cmdq_nic_rx_tail_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "cmdq_nic_tx_tail_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "cmdq_nic_rx_head_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "cmdq_nic_tx_head_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "cmdq_nic_rx_addr_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "cmdq_nic_tx_addr_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error tqp_int_ecc_int[] = { +- { .int_msk = BIT(6), +- .msg = "tqp_int_cfg_even_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(7), +- .msg = "tqp_int_cfg_odd_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(8), +- .msg = "tqp_int_ctrl_even_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(9), +- .msg = "tqp_int_ctrl_odd_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(10), +- .msg = "tx_queue_scan_int_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(11), +- .msg = "rx_queue_scan_int_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(6), ++ .msg = "tqp_int_cfg_even_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "tqp_int_cfg_odd_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "tqp_int_ctrl_even_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "tqp_int_ctrl_odd_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(10), ++ .msg = "tx_queue_scan_int_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "rx_queue_scan_int_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error imp_rd_poison_int[] = { +- { .int_msk = BIT(0), +- .msg = "imp_rd_poison_int", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "imp_rd_poison_int", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + #define HNS3_SSU_MEM_ECC_ERR(x) \ +- { .int_msk = BIT(x), \ +- .msg = "ssu_mem" #x "_ecc_mbit_err", \ +- .reset_level = HNS3_GLOBAL_RESET } ++{ \ ++ .int_msk = BIT(x), \ ++ .msg = "ssu_mem" #x "_ecc_mbit_err", \ ++ .reset_level = HNS3_GLOBAL_RESET \ ++} + + static const struct hns3_hw_error ssu_ecc_multi_bit_int_0[] = { + HNS3_SSU_MEM_ECC_ERR(0), +@@ -344,722 +437,951 @@ static const struct hns3_hw_error ssu_ecc_multi_bit_int_0[] = { + }; + + static const struct hns3_hw_error ssu_ecc_multi_bit_int_1[] = { +- { .int_msk = BIT(0), +- .msg = "ssu_mem32_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "ssu_mem32_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ssu_common_ecc_int[] = { +- { .int_msk = BIT(0), +- .msg = "buf_sum_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(1), +- .msg = "ppp_mb_num_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = BIT(2), +- .msg = "ppp_mbid_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "ppp_rlt_mac_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "ppp_rlt_host_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "cks_edit_position_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "cks_edit_condition_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "vlan_edit_condition_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "vlan_num_ot_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "vlan_num_in_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "buf_sum_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "ppp_mb_num_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "ppp_mbid_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "ppp_rlt_mac_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "ppp_rlt_host_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "cks_edit_position_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "cks_edit_condition_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "vlan_edit_condition_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "vlan_num_ot_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "vlan_num_in_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error igu_int[] = { +- { .int_msk = BIT(0), +- .msg = "igu_rx_buf0_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "igu_rx_buf1_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "igu_rx_buf0_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "igu_rx_buf1_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error msix_ecc_int[] = { +- { .int_msk = BIT(1), +- .msg = "msix_nic_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(1), ++ .msg = "msix_nic_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppp_mpf_abnormal_int_st1[] = { +- { .int_msk = BIT(0), +- .msg = "vf_vlan_ad_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(1), +- .msg = "umv_mcast_group_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "umv_key_mem0_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "umv_key_mem1_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "umv_key_mem2_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "umv_key_mem3_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "umv_ad_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "rss_tc_mode_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "rss_idt_mem0_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "rss_idt_mem1_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(10), +- .msg = "rss_idt_mem2_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "rss_idt_mem3_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(12), +- .msg = "rss_idt_mem4_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "rss_idt_mem5_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(14), +- .msg = "rss_idt_mem6_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(15), +- .msg = "rss_idt_mem7_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(16), +- .msg = "rss_idt_mem8_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(17), +- .msg = "rss_idt_mem9_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(18), +- .msg = "rss_idt_mem10_ecc_m1bit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(19), +- .msg = "rss_idt_mem11_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(20), +- .msg = "rss_idt_mem12_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(21), +- .msg = "rss_idt_mem13_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(22), +- .msg = "rss_idt_mem14_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(23), +- .msg = "rss_idt_mem15_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(24), +- .msg = "port_vlan_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(25), +- .msg = "mcast_linear_table_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(26), +- .msg = "mcast_result_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(27), +- .msg = "flow_director_ad_mem0_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(28), +- .msg = "flow_director_ad_mem1_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(29), +- .msg = "rx_vlan_tag_memory_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(30), +- .msg = "Tx_UP_mapping_config_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "vf_vlan_ad_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "umv_mcast_group_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "umv_key_mem0_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "umv_key_mem1_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "umv_key_mem2_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "umv_key_mem3_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "umv_ad_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "rss_tc_mode_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "rss_idt_mem0_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "rss_idt_mem1_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(10), ++ .msg = "rss_idt_mem2_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "rss_idt_mem3_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(12), ++ .msg = "rss_idt_mem4_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "rss_idt_mem5_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(14), ++ .msg = "rss_idt_mem6_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "rss_idt_mem7_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(16), ++ .msg = "rss_idt_mem8_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "rss_idt_mem9_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(18), ++ .msg = "rss_idt_mem10_ecc_m1bit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(19), ++ .msg = "rss_idt_mem11_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(20), ++ .msg = "rss_idt_mem12_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(21), ++ .msg = "rss_idt_mem13_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(22), ++ .msg = "rss_idt_mem14_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(23), ++ .msg = "rss_idt_mem15_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(24), ++ .msg = "port_vlan_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(25), ++ .msg = "mcast_linear_table_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(26), ++ .msg = "mcast_result_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(27), ++ .msg = "flow_director_ad_mem0_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(28), ++ .msg = "flow_director_ad_mem1_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(29), ++ .msg = "rx_vlan_tag_memory_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(30), ++ .msg = "Tx_UP_mapping_config_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppp_mpf_abnormal_int_st3[] = { +- { .int_msk = BIT(0), +- .msg = "hfs_fifo_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(1), +- .msg = "rslt_descr_fifo_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "tx_vlan_tag_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "FD_CN0_memory_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "FD_CN1_memory_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "GRO_AD_memory_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "hfs_fifo_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "rslt_descr_fifo_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "tx_vlan_tag_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "FD_CN0_memory_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "FD_CN1_memory_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "GRO_AD_memory_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ppu_mpf_abnormal_int_st3[] = { +- { .int_msk = BIT(4), +- .msg = "gro_bd_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "gro_context_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "rx_stash_cfg_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "axi_rd_fbd_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(4), ++ .msg = "gro_bd_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "gro_context_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "rx_stash_cfg_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "axi_rd_fbd_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error tm_sch_int[] = { +- { .int_msk = BIT(1), +- .msg = "tm_sch_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "tm_sch_port_shap_sub_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "tm_sch_port_shap_sub_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "tm_sch_pg_pshap_sub_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "tm_sch_pg_pshap_sub_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "tm_sch_pg_cshap_sub_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "tm_sch_pg_cshap_sub_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "tm_sch_pri_pshap_sub_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "tm_sch_pri_pshap_sub_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(10), +- .msg = "tm_sch_pri_cshap_sub_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "tm_sch_pri_cshap_sub_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(12), +- .msg = "tm_sch_port_shap_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "tm_sch_port_shap_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(14), +- .msg = "tm_sch_pg_pshap_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(15), +- .msg = "tm_sch_pg_pshap_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(16), +- .msg = "tm_sch_pg_cshap_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(17), +- .msg = "tm_sch_pg_cshap_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(18), +- .msg = "tm_sch_pri_pshap_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(19), +- .msg = "tm_sch_pri_pshap_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(20), +- .msg = "tm_sch_pri_cshap_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(21), +- .msg = "tm_sch_pri_cshap_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(22), +- .msg = "tm_sch_rq_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(23), +- .msg = "tm_sch_rq_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(24), +- .msg = "tm_sch_nq_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(25), +- .msg = "tm_sch_nq_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(26), +- .msg = "tm_sch_roce_up_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(27), +- .msg = "tm_sch_roce_up_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(28), +- .msg = "tm_sch_rcb_byte_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(29), +- .msg = "tm_sch_rcb_byte_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(30), +- .msg = "tm_sch_ssu_byte_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(31), +- .msg = "tm_sch_ssu_byte_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(1), ++ .msg = "tm_sch_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "tm_sch_port_shap_sub_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "tm_sch_port_shap_sub_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "tm_sch_pg_pshap_sub_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "tm_sch_pg_pshap_sub_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "tm_sch_pg_cshap_sub_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "tm_sch_pg_cshap_sub_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "tm_sch_pri_pshap_sub_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "tm_sch_pri_pshap_sub_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(10), ++ .msg = "tm_sch_pri_cshap_sub_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "tm_sch_pri_cshap_sub_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(12), ++ .msg = "tm_sch_port_shap_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "tm_sch_port_shap_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(14), ++ .msg = "tm_sch_pg_pshap_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "tm_sch_pg_pshap_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(16), ++ .msg = "tm_sch_pg_cshap_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "tm_sch_pg_cshap_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(18), ++ .msg = "tm_sch_pri_pshap_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(19), ++ .msg = "tm_sch_pri_pshap_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(20), ++ .msg = "tm_sch_pri_cshap_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(21), ++ .msg = "tm_sch_pri_cshap_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(22), ++ .msg = "tm_sch_rq_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(23), ++ .msg = "tm_sch_rq_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(24), ++ .msg = "tm_sch_nq_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(25), ++ .msg = "tm_sch_nq_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(26), ++ .msg = "tm_sch_roce_up_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(27), ++ .msg = "tm_sch_roce_up_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(28), ++ .msg = "tm_sch_rcb_byte_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(29), ++ .msg = "tm_sch_rcb_byte_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(30), ++ .msg = "tm_sch_ssu_byte_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(31), ++ .msg = "tm_sch_ssu_byte_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error qcn_fifo_int[] = { +- { .int_msk = BIT(0), +- .msg = "qcn_shap_gp0_sch_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(1), +- .msg = "qcn_shap_gp0_sch_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "qcn_shap_gp1_sch_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "qcn_shap_gp1_sch_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "qcn_shap_gp2_sch_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "qcn_shap_gp2_sch_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "qcn_shap_gp3_sch_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "qcn_shap_gp3_sch_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "qcn_shap_gp0_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "qcn_shap_gp0_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(10), +- .msg = "qcn_shap_gp1_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "qcn_shap_gp1_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(12), +- .msg = "qcn_shap_gp2_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "qcn_shap_gp2_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(14), +- .msg = "qcn_shap_gp3_offset_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(15), +- .msg = "qcn_shap_gp3_offset_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(16), +- .msg = "qcn_byte_info_fifo_rd_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(17), +- .msg = "qcn_byte_info_fifo_wr_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "qcn_shap_gp0_sch_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "qcn_shap_gp0_sch_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "qcn_shap_gp1_sch_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "qcn_shap_gp1_sch_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "qcn_shap_gp2_sch_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "qcn_shap_gp2_sch_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "qcn_shap_gp3_sch_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "qcn_shap_gp3_sch_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "qcn_shap_gp0_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "qcn_shap_gp0_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(10), ++ .msg = "qcn_shap_gp1_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "qcn_shap_gp1_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(12), ++ .msg = "qcn_shap_gp2_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "qcn_shap_gp2_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(14), ++ .msg = "qcn_shap_gp3_offset_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "qcn_shap_gp3_offset_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(16), ++ .msg = "qcn_byte_info_fifo_rd_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "qcn_byte_info_fifo_wr_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error qcn_ecc_int[] = { +- { .int_msk = BIT(1), +- .msg = "qcn_byte_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "qcn_time_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "qcn_fb_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "qcn_link_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "qcn_rate_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "qcn_tmplt_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "qcn_shap_cfg_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(15), +- .msg = "qcn_gp0_barrel_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(17), +- .msg = "qcn_gp1_barrel_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(19), +- .msg = "qcn_gp2_barrel_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(21), +- .msg = "qcn_gp3_barral_mem_ecc_mbit_err", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(1), ++ .msg = "qcn_byte_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "qcn_time_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "qcn_fb_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "qcn_link_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "qcn_rate_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "qcn_tmplt_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "qcn_shap_cfg_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "qcn_gp0_barrel_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "qcn_gp1_barrel_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(19), ++ .msg = "qcn_gp2_barrel_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(21), ++ .msg = "qcn_gp3_barral_mem_ecc_mbit_err", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ncsi_ecc_int[] = { +- { .int_msk = BIT(1), +- .msg = "ncsi_tx_ecc_mbit_err", +- .reset_level = HNS3_NONE_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(1), ++ .msg = "ncsi_tx_ecc_mbit_err", ++ .reset_level = HNS3_NONE_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ssu_fifo_overflow_int[] = { +- { .int_msk = BIT(0), +- .msg = "ig_mac_inf_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(1), +- .msg = "ig_host_inf_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "ig_roc_buf_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "ig_host_data_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "ig_host_key_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "tx_qcn_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "rx_qcn_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "tx_pf_rd_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "rx_pf_rd_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(9), +- .msg = "qm_eof_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(10), +- .msg = "mb_rlt_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "dup_uncopy_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(12), +- .msg = "dup_cnt_rd_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "dup_cnt_drop_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(14), +- .msg = "dup_cnt_wrb_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(15), +- .msg = "host_cmd_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(16), +- .msg = "mac_cmd_fifo_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(17), +- .msg = "host_cmd_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(18), +- .msg = "mac_cmd_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(19), +- .msg = "dup_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(20), +- .msg = "out_queue_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(21), +- .msg = "bank2_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(22), +- .msg = "bank1_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(23), +- .msg = "bank0_bitmap_empty_int", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "ig_mac_inf_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "ig_host_inf_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "ig_roc_buf_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "ig_host_data_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "ig_host_key_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "tx_qcn_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "rx_qcn_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "tx_pf_rd_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "rx_pf_rd_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(9), ++ .msg = "qm_eof_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(10), ++ .msg = "mb_rlt_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "dup_uncopy_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(12), ++ .msg = "dup_cnt_rd_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "dup_cnt_drop_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(14), ++ .msg = "dup_cnt_wrb_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(15), ++ .msg = "host_cmd_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(16), ++ .msg = "mac_cmd_fifo_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(17), ++ .msg = "host_cmd_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(18), ++ .msg = "mac_cmd_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(19), ++ .msg = "dup_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(20), ++ .msg = "out_queue_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(21), ++ .msg = "bank2_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(22), ++ .msg = "bank1_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(23), ++ .msg = "bank0_bitmap_empty_int", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ssu_ets_tcg_int[] = { +- { .int_msk = BIT(0), +- .msg = "ets_rd_int_rx_tcg", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(1), +- .msg = "ets_wr_int_rx_tcg", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "ets_rd_int_tx_tcg", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "ets_wr_int_tx_tcg", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "ets_rd_int_rx_tcg", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "ets_wr_int_rx_tcg", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "ets_rd_int_tx_tcg", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "ets_wr_int_tx_tcg", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error igu_egu_tnl_int[] = { +- { .int_msk = BIT(0), +- .msg = "rx_buf_overflow", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(1), +- .msg = "rx_stp_fifo_overflow", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "rx_stp_fifo_underflow", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "tx_buf_overflow", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "tx_buf_underrun", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "rx_stp_buf_overflow", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "rx_buf_overflow", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "rx_stp_fifo_overflow", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "rx_stp_fifo_underflow", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "tx_buf_overflow", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "tx_buf_underrun", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "rx_stp_buf_overflow", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error ssu_port_based_err_int[] = { +- { .int_msk = BIT(0), +- .msg = "roc_pkt_without_key_port", +- .reset_level = HNS3_FUNC_RESET }, +- { .int_msk = BIT(1), +- .msg = "tpu_pkt_without_key_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(2), +- .msg = "igu_pkt_without_key_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(3), +- .msg = "roc_eof_mis_match_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(4), +- .msg = "tpu_eof_mis_match_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(5), +- .msg = "igu_eof_mis_match_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(6), +- .msg = "roc_sof_mis_match_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(7), +- .msg = "tpu_sof_mis_match_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(8), +- .msg = "igu_sof_mis_match_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(11), +- .msg = "ets_rd_int_rx_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(12), +- .msg = "ets_wr_int_rx_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(13), +- .msg = "ets_rd_int_tx_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = BIT(14), +- .msg = "ets_wr_int_tx_port", +- .reset_level = HNS3_GLOBAL_RESET }, +- { .int_msk = 0, +- .msg = NULL, +- .reset_level = HNS3_NONE_RESET} ++ { ++ .int_msk = BIT(0), ++ .msg = "roc_pkt_without_key_port", ++ .reset_level = HNS3_FUNC_RESET ++ }, { ++ .int_msk = BIT(1), ++ .msg = "tpu_pkt_without_key_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(2), ++ .msg = "igu_pkt_without_key_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(3), ++ .msg = "roc_eof_mis_match_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(4), ++ .msg = "tpu_eof_mis_match_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(5), ++ .msg = "igu_eof_mis_match_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(6), ++ .msg = "roc_sof_mis_match_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(7), ++ .msg = "tpu_sof_mis_match_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(8), ++ .msg = "igu_sof_mis_match_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(11), ++ .msg = "ets_rd_int_rx_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(12), ++ .msg = "ets_wr_int_rx_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(13), ++ .msg = "ets_rd_int_tx_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = BIT(14), ++ .msg = "ets_wr_int_tx_port", ++ .reset_level = HNS3_GLOBAL_RESET ++ }, { ++ .int_msk = 0, ++ .msg = NULL, ++ .reset_level = HNS3_NONE_RESET ++ } + }; + + static const struct hns3_hw_error_desc mpf_ras_err_tbl[] = { +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = "IMP_TCM_ECC_INT_STS", +- .hw_err = imp_tcm_ecc_int }, +- { .desc_offset = 0, +- .data_offset = 1, +- .msg = "CMDQ_MEM_ECC_INT_STS", +- .hw_err = cmdq_mem_ecc_int }, +- { .desc_offset = 0, +- .data_offset = 2, +- .msg = "IMP_RD_POISON_INT_STS", +- .hw_err = imp_rd_poison_int }, +- { .desc_offset = 0, +- .data_offset = 3, +- .msg = "TQP_INT_ECC_INT_STS", +- .hw_err = tqp_int_ecc_int }, +- { .desc_offset = 0, +- .data_offset = 4, +- .msg = "MSIX_ECC_INT_STS", +- .hw_err = msix_ecc_int }, +- { .desc_offset = 2, +- .data_offset = 2, +- .msg = "SSU_ECC_MULTI_BIT_INT_0", +- .hw_err = ssu_ecc_multi_bit_int_0 }, +- { .desc_offset = 2, +- .data_offset = 3, +- .msg = "SSU_ECC_MULTI_BIT_INT_1", +- .hw_err = ssu_ecc_multi_bit_int_1 }, +- { .desc_offset = 2, +- .data_offset = 4, +- .msg = "SSU_COMMON_ERR_INT", +- .hw_err = ssu_common_ecc_int }, +- { .desc_offset = 3, +- .data_offset = 0, +- .msg = "IGU_INT_STS", +- .hw_err = igu_int }, +- { .desc_offset = 4, +- .data_offset = 1, +- .msg = "PPP_MPF_ABNORMAL_INT_ST1", +- .hw_err = ppp_mpf_abnormal_int_st1 }, +- { .desc_offset = 4, +- .data_offset = 3, +- .msg = "PPP_MPF_ABNORMAL_INT_ST3", +- .hw_err = ppp_mpf_abnormal_int_st3 }, +- { .desc_offset = 5, +- .data_offset = 1, +- .msg = "PPU_MPF_ABNORMAL_INT_ST1", +- .hw_err = ppu_mpf_abnormal_int_st1 }, +- { .desc_offset = 5, +- .data_offset = 2, +- .msg = "PPU_MPF_ABNORMAL_INT_ST2_RAS", +- .hw_err = ppu_mpf_abnormal_int_st2_ras }, +- { .desc_offset = 5, +- .data_offset = 3, +- .msg = "PPU_MPF_ABNORMAL_INT_ST3", +- .hw_err = ppu_mpf_abnormal_int_st3 }, +- { .desc_offset = 6, +- .data_offset = 0, +- .msg = "TM_SCH_RINT", +- .hw_err = tm_sch_int }, +- { .desc_offset = 7, +- .data_offset = 0, +- .msg = "QCN_FIFO_RINT", +- .hw_err = qcn_fifo_int }, +- { .desc_offset = 7, +- .data_offset = 1, +- .msg = "QCN_ECC_RINT", +- .hw_err = qcn_ecc_int }, +- { .desc_offset = 9, +- .data_offset = 0, +- .msg = "NCSI_ECC_INT_RPT", +- .hw_err = ncsi_ecc_int }, +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = NULL, +- .hw_err = NULL } ++ { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = "IMP_TCM_ECC_INT_STS", ++ .hw_err = imp_tcm_ecc_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 1, ++ .msg = "CMDQ_MEM_ECC_INT_STS", ++ .hw_err = cmdq_mem_ecc_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 2, ++ .msg = "IMP_RD_POISON_INT_STS", ++ .hw_err = imp_rd_poison_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 3, ++ .msg = "TQP_INT_ECC_INT_STS", ++ .hw_err = tqp_int_ecc_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 4, ++ .msg = "MSIX_ECC_INT_STS", ++ .hw_err = msix_ecc_int ++ }, { ++ .desc_offset = 2, ++ .data_offset = 2, ++ .msg = "SSU_ECC_MULTI_BIT_INT_0", ++ .hw_err = ssu_ecc_multi_bit_int_0 ++ }, { ++ .desc_offset = 2, ++ .data_offset = 3, ++ .msg = "SSU_ECC_MULTI_BIT_INT_1", ++ .hw_err = ssu_ecc_multi_bit_int_1 ++ }, { ++ .desc_offset = 2, ++ .data_offset = 4, ++ .msg = "SSU_COMMON_ERR_INT", ++ .hw_err = ssu_common_ecc_int ++ }, { ++ .desc_offset = 3, ++ .data_offset = 0, ++ .msg = "IGU_INT_STS", ++ .hw_err = igu_int ++ }, { ++ .desc_offset = 4, ++ .data_offset = 1, ++ .msg = "PPP_MPF_ABNORMAL_INT_ST1", ++ .hw_err = ppp_mpf_abnormal_int_st1 ++ }, { ++ .desc_offset = 4, ++ .data_offset = 3, ++ .msg = "PPP_MPF_ABNORMAL_INT_ST3", ++ .hw_err = ppp_mpf_abnormal_int_st3 ++ }, { ++ .desc_offset = 5, ++ .data_offset = 1, ++ .msg = "PPU_MPF_ABNORMAL_INT_ST1", ++ .hw_err = ppu_mpf_abnormal_int_st1 ++ }, { ++ .desc_offset = 5, ++ .data_offset = 2, ++ .msg = "PPU_MPF_ABNORMAL_INT_ST2_RAS", ++ .hw_err = ppu_mpf_abnormal_int_st2_ras ++ }, { ++ .desc_offset = 5, ++ .data_offset = 3, ++ .msg = "PPU_MPF_ABNORMAL_INT_ST3", ++ .hw_err = ppu_mpf_abnormal_int_st3 ++ }, { ++ .desc_offset = 6, ++ .data_offset = 0, ++ .msg = "TM_SCH_RINT", ++ .hw_err = tm_sch_int ++ }, { ++ .desc_offset = 7, ++ .data_offset = 0, ++ .msg = "QCN_FIFO_RINT", ++ .hw_err = qcn_fifo_int ++ }, { ++ .desc_offset = 7, ++ .data_offset = 1, ++ .msg = "QCN_ECC_RINT", ++ .hw_err = qcn_ecc_int ++ }, { ++ .desc_offset = 9, ++ .data_offset = 0, ++ .msg = "NCSI_ECC_INT_RPT", ++ .hw_err = ncsi_ecc_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = NULL, ++ .hw_err = NULL ++ } + }; + + static const struct hns3_hw_error_desc pf_ras_err_tbl[] = { +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = "SSU_PORT_BASED_ERR_INT_RAS", +- .hw_err = ssu_port_based_err_int }, +- { .desc_offset = 0, +- .data_offset = 1, +- .msg = "SSU_FIFO_OVERFLOW_INT", +- .hw_err = ssu_fifo_overflow_int }, +- { .desc_offset = 0, +- .data_offset = 2, +- .msg = "SSU_ETS_TCG_INT", +- .hw_err = ssu_ets_tcg_int }, +- { .desc_offset = 1, +- .data_offset = 0, +- .msg = "IGU_EGU_TNL_INT_STS", +- .hw_err = igu_egu_tnl_int }, +- { .desc_offset = 3, +- .data_offset = 0, +- .msg = "PPU_PF_ABNORMAL_INT_ST_RAS", +- .hw_err = ppu_pf_abnormal_int_ras }, +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = NULL, +- .hw_err = NULL } ++ { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = "SSU_PORT_BASED_ERR_INT_RAS", ++ .hw_err = ssu_port_based_err_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 1, ++ .msg = "SSU_FIFO_OVERFLOW_INT", ++ .hw_err = ssu_fifo_overflow_int ++ }, { ++ .desc_offset = 0, ++ .data_offset = 2, ++ .msg = "SSU_ETS_TCG_INT", ++ .hw_err = ssu_ets_tcg_int ++ }, { ++ .desc_offset = 1, ++ .data_offset = 0, ++ .msg = "IGU_EGU_TNL_INT_STS", ++ .hw_err = igu_egu_tnl_int ++ }, { ++ .desc_offset = 3, ++ .data_offset = 0, ++ .msg = "PPU_PF_ABNORMAL_INT_ST_RAS", ++ .hw_err = ppu_pf_abnormal_int_ras ++ }, { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = NULL, ++ .hw_err = NULL ++ } + }; + + static const struct hns3_hw_error_desc mpf_msix_err_tbl[] = { +- { .desc_offset = 1, +- .data_offset = 0, +- .msg = "MAC_AFIFO_TNL_INT_R", +- .hw_err = mac_afifo_tnl_int }, +- { .desc_offset = 5, +- .data_offset = 2, +- .msg = "PPU_MPF_ABNORMAL_INT_ST2_MSIX", +- .hw_err = ppu_mpf_abnormal_int_st2_msix }, +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = NULL, +- .hw_err = NULL } ++ { ++ .desc_offset = 1, ++ .data_offset = 0, ++ .msg = "MAC_AFIFO_TNL_INT_R", ++ .hw_err = mac_afifo_tnl_int ++ }, { ++ .desc_offset = 5, ++ .data_offset = 2, ++ .msg = "PPU_MPF_ABNORMAL_INT_ST2_MSIX", ++ .hw_err = ppu_mpf_abnormal_int_st2_msix ++ }, { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = NULL, ++ .hw_err = NULL ++ } + }; + + static const struct hns3_hw_error_desc pf_msix_err_tbl[] = { +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = "SSU_PORT_BASED_ERR_INT_MSIX", +- .hw_err = ssu_port_based_pf_int }, +- { .desc_offset = 2, +- .data_offset = 0, +- .msg = "PPP_PF_ABNORMAL_INT_ST0", +- .hw_err = ppp_pf_abnormal_int }, +- { .desc_offset = 3, +- .data_offset = 0, +- .msg = "PPU_PF_ABNORMAL_INT_ST_MSIX", +- .hw_err = ppu_pf_abnormal_int_msix }, +- { .desc_offset = 0, +- .data_offset = 0, +- .msg = NULL, +- .hw_err = NULL } ++ { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = "SSU_PORT_BASED_ERR_INT_MSIX", ++ .hw_err = ssu_port_based_pf_int ++ }, { ++ .desc_offset = 2, ++ .data_offset = 0, ++ .msg = "PPP_PF_ABNORMAL_INT_ST0", ++ .hw_err = ppp_pf_abnormal_int ++ }, { ++ .desc_offset = 3, ++ .data_offset = 0, ++ .msg = "PPU_PF_ABNORMAL_INT_ST_MSIX", ++ .hw_err = ppu_pf_abnormal_int_msix ++ }, { ++ .desc_offset = 0, ++ .data_offset = 0, ++ .msg = NULL, ++ .hw_err = NULL ++ } + }; + + enum hns3_hw_err_type { +-- +2.7.4 + diff --git a/0062-net-hns3-delete-redundant-xstats-RAS-statistics.patch b/0062-net-hns3-delete-redundant-xstats-RAS-statistics.patch new file mode 100644 index 0000000..d2cc6ad --- /dev/null +++ b/0062-net-hns3-delete-redundant-xstats-RAS-statistics.patch @@ -0,0 +1,287 @@ +From 95824ab5efc3996a682c57af118571fdccc5f677 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Tue, 23 Mar 2021 19:21:03 +0800 +Subject: [PATCH 062/189] net/hns3: delete redundant xstats RAS statistics + +The current RAS code stores the reported RAS statistics in xstats. +This part of statistics is of little use in practice, and because +of the change of RAS scheme on Kunpeng930, the driver can not +obtain the RAS information any more, so this patch delete these +redundant RAS statistics. + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 2 - + drivers/net/hns3/hns3_ethdev.h | 35 --------------- + drivers/net/hns3/hns3_intr.c | 1 - + drivers/net/hns3/hns3_stats.c | 100 +---------------------------------------- + drivers/net/hns3/hns3_stats.h | 1 - + 5 files changed, 1 insertion(+), 138 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 5da00b3..7bdc6f7 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5768,14 +5768,12 @@ hns3_record_imp_error(struct hns3_adapter *hns) + reg_val = hns3_read_dev(hw, HNS3_VECTOR0_OTER_EN_REG); + if (hns3_get_bit(reg_val, HNS3_VECTOR0_IMP_RD_POISON_B)) { + hns3_warn(hw, "Detected IMP RD poison!"); +- hns3_error_int_stats_add(hns, "IMP_RD_POISON_INT_STS"); + hns3_set_bit(reg_val, HNS3_VECTOR0_IMP_RD_POISON_B, 0); + hns3_write_dev(hw, HNS3_VECTOR0_OTER_EN_REG, reg_val); + } + + if (hns3_get_bit(reg_val, HNS3_VECTOR0_IMP_CMDQ_ERR_B)) { + hns3_warn(hw, "Detected IMP CMDQ error!"); +- hns3_error_int_stats_add(hns, "CMDQ_MEM_ECC_INT_STS"); + hns3_set_bit(reg_val, HNS3_VECTOR0_IMP_CMDQ_ERR_B, 0); + hns3_write_dev(hw, HNS3_VECTOR0_OTER_EN_REG, reg_val); + } +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index dc27bb1..dfe0c59 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -561,38 +561,6 @@ struct hns3_hw { + #define HNS3_FLAG_TC_BASE_SCH_MODE 1 + #define HNS3_FLAG_VNET_BASE_SCH_MODE 2 + +-struct hns3_err_msix_intr_stats { +- uint64_t mac_afifo_tnl_int_cnt; +- uint64_t ppu_mpf_abn_int_st2_msix_cnt; +- uint64_t ssu_port_based_pf_int_cnt; +- uint64_t ppp_pf_abnormal_int_cnt; +- uint64_t ppu_pf_abnormal_int_msix_cnt; +- +- uint64_t imp_tcm_ecc_int_cnt; +- uint64_t cmdq_mem_ecc_int_cnt; +- uint64_t imp_rd_poison_int_cnt; +- uint64_t tqp_int_ecc_int_cnt; +- uint64_t msix_ecc_int_cnt; +- uint64_t ssu_ecc_multi_bit_int_0_cnt; +- uint64_t ssu_ecc_multi_bit_int_1_cnt; +- uint64_t ssu_common_ecc_int_cnt; +- uint64_t igu_int_cnt; +- uint64_t ppp_mpf_abnormal_int_st1_cnt; +- uint64_t ppp_mpf_abnormal_int_st3_cnt; +- uint64_t ppu_mpf_abnormal_int_st1_cnt; +- uint64_t ppu_mpf_abn_int_st2_ras_cnt; +- uint64_t ppu_mpf_abnormal_int_st3_cnt; +- uint64_t tm_sch_int_cnt; +- uint64_t qcn_fifo_int_cnt; +- uint64_t qcn_ecc_int_cnt; +- uint64_t ncsi_ecc_int_cnt; +- uint64_t ssu_port_based_err_int_cnt; +- uint64_t ssu_fifo_overflow_int_cnt; +- uint64_t ssu_ets_tcg_int_cnt; +- uint64_t igu_egu_tnl_int_cnt; +- uint64_t ppu_pf_abnormal_int_ras_cnt; +-}; +- + /* vlan entry information. */ + struct hns3_user_vlan_table { + LIST_ENTRY(hns3_user_vlan_table) next; +@@ -738,9 +706,6 @@ struct hns3_pf { + uint16_t max_umv_size; + uint16_t used_umv_size; + +- /* Statistics information for abnormal interrupt */ +- struct hns3_err_msix_intr_stats abn_int_stats; +- + bool support_sfp_query; + uint32_t fec_mode; /* current FEC mode for ethdev */ + +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 265dae8..c259f2e 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -1838,7 +1838,6 @@ hns3_find_highest_level(struct hns3_adapter *hns, const char *reg, + reset_level = err->reset_level; + need_reset = true; + } +- hns3_error_int_stats_add(hns, reg); + } + err++; + } +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 941c75f..7cda36c 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -201,65 +201,6 @@ static const struct hns3_xstats_name_offset hns3_mac_strings[] = { + HNS3_MAC_STATS_OFFSET(mac_rx_send_app_bad_pkt_num)} + }; + +-static const struct hns3_xstats_name_offset hns3_error_int_stats_strings[] = { +- {"MAC_AFIFO_TNL_INT_R", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(mac_afifo_tnl_int_cnt)}, +- {"PPU_MPF_ABNORMAL_INT_ST2_MSIX", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_mpf_abn_int_st2_msix_cnt)}, +- {"SSU_PORT_BASED_ERR_INT_MSIX", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_port_based_pf_int_cnt)}, +- {"PPP_PF_ABNORMAL_INT_ST0", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppp_pf_abnormal_int_cnt)}, +- {"PPU_PF_ABNORMAL_INT_ST_MSIX", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_pf_abnormal_int_msix_cnt)}, +- {"IMP_TCM_ECC_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(imp_tcm_ecc_int_cnt)}, +- {"CMDQ_MEM_ECC_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(cmdq_mem_ecc_int_cnt)}, +- {"IMP_RD_POISON_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(imp_rd_poison_int_cnt)}, +- {"TQP_INT_ECC_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(tqp_int_ecc_int_cnt)}, +- {"MSIX_ECC_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(msix_ecc_int_cnt)}, +- {"SSU_ECC_MULTI_BIT_INT_0", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_ecc_multi_bit_int_0_cnt)}, +- {"SSU_ECC_MULTI_BIT_INT_1", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_ecc_multi_bit_int_1_cnt)}, +- {"SSU_COMMON_ERR_INT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_common_ecc_int_cnt)}, +- {"IGU_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(igu_int_cnt)}, +- {"PPP_MPF_ABNORMAL_INT_ST1", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppp_mpf_abnormal_int_st1_cnt)}, +- {"PPP_MPF_ABNORMAL_INT_ST3", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppp_mpf_abnormal_int_st3_cnt)}, +- {"PPU_MPF_ABNORMAL_INT_ST1", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_mpf_abnormal_int_st1_cnt)}, +- {"PPU_MPF_ABNORMAL_INT_ST2_RAS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_mpf_abn_int_st2_ras_cnt)}, +- {"PPU_MPF_ABNORMAL_INT_ST3", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_mpf_abnormal_int_st3_cnt)}, +- {"TM_SCH_RINT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(tm_sch_int_cnt)}, +- {"QCN_FIFO_RINT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(qcn_fifo_int_cnt)}, +- {"QCN_ECC_RINT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(qcn_ecc_int_cnt)}, +- {"NCSI_ECC_INT_RPT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ncsi_ecc_int_cnt)}, +- {"SSU_PORT_BASED_ERR_INT_RAS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_port_based_err_int_cnt)}, +- {"SSU_FIFO_OVERFLOW_INT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_fifo_overflow_int_cnt)}, +- {"SSU_ETS_TCG_INT", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ssu_ets_tcg_int_cnt)}, +- {"IGU_EGU_TNL_INT_STS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(igu_egu_tnl_int_cnt)}, +- {"PPU_PF_ABNORMAL_INT_ST_RAS", +- HNS3_ERR_INT_STATS_FIELD_OFFSET(ppu_pf_abnormal_int_ras_cnt)}, +-}; +- + /* The statistic of reset */ + static const struct hns3_xstats_name_offset hns3_reset_stats_strings[] = { + {"REQ_RESET_CNT", +@@ -333,9 +274,6 @@ static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = { + #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \ + sizeof(hns3_mac_strings[0])) + +-#define HNS3_NUM_ERROR_INT_XSTATS (sizeof(hns3_error_int_stats_strings) / \ +- sizeof(hns3_error_int_stats_strings[0])) +- + #define HNS3_NUM_RESET_XSTATS (sizeof(hns3_reset_stats_strings) / \ + sizeof(hns3_reset_stats_strings[0])) + +@@ -363,7 +301,7 @@ static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = { + #define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \ + sizeof(hns3_imissed_stats_strings[0])) + +-#define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \ ++#define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + \ + HNS3_NUM_RESET_XSTATS + HNS3_NUM_IMISSED_XSTATS) + + static void hns3_tqp_stats_clear(struct hns3_hw *hw); +@@ -750,23 +688,6 @@ hns3_queue_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + } + } + +-void +-hns3_error_int_stats_add(struct hns3_adapter *hns, const char *err) +-{ +- struct hns3_pf *pf = &hns->pf; +- uint16_t i; +- char *addr; +- +- for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) { +- if (strcmp(hns3_error_int_stats_strings[i].name, err) == 0) { +- addr = (char *)&pf->abn_int_stats + +- hns3_error_int_stats_strings[i].offset; +- *(uint64_t *)addr += 1; +- break; +- } +- } +-} +- + static void + hns3_rxq_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + int *count) +@@ -932,7 +853,6 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + unsigned int n) + { + struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_pf *pf = &hns->pf; + struct hns3_hw *hw = &hns->hw; + struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats; + struct hns3_mac_stats *mac_stats = &hw->mac_stats; +@@ -986,13 +906,6 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + count++; + } + +- for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) { +- addr = (char *)&pf->abn_int_stats + +- hns3_error_int_stats_strings[i].offset; +- xstats[count].value = *(uint64_t *)addr; +- xstats[count].id = count; +- count++; +- } + } + + /* Get the reset stat */ +@@ -1134,13 +1047,6 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev, + "%s", hns3_imissed_stats_strings[i].name); + count++; + } +- +- for (i = 0; i < HNS3_NUM_ERROR_INT_XSTATS; i++) { +- snprintf(xstats_names[count].name, +- sizeof(xstats_names[count].name), +- "%s", hns3_error_int_stats_strings[i].name); +- count++; +- } + } + for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) { + snprintf(xstats_names[count].name, +@@ -1358,7 +1264,6 @@ int + hns3_dev_xstats_reset(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_pf *pf = &hns->pf; + int ret; + + /* Clear tqp stats */ +@@ -1379,9 +1284,6 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) + if (ret) + return ret; + +- /* Clear error stats */ +- memset(&pf->abn_int_stats, 0, sizeof(struct hns3_err_msix_intr_stats)); +- + return 0; + } + +diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h +index 70a9c5b..8ea69b4 100644 +--- a/drivers/net/hns3/hns3_stats.h ++++ b/drivers/net/hns3/hns3_stats.h +@@ -164,7 +164,6 @@ int hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, + const uint64_t *ids, + uint32_t size); + int hns3_stats_reset(struct rte_eth_dev *dev); +-void hns3_error_int_stats_add(struct hns3_adapter *hns, const char *err); + int hns3_tqp_stats_init(struct hns3_hw *hw); + void hns3_tqp_stats_uninit(struct hns3_hw *hw); + int hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear); +-- +2.7.4 + diff --git a/0063-net-hns3-support-imissed-stats-for-PF-VF.patch b/0063-net-hns3-support-imissed-stats-for-PF-VF.patch new file mode 100644 index 0000000..510283c --- /dev/null +++ b/0063-net-hns3-support-imissed-stats-for-PF-VF.patch @@ -0,0 +1,516 @@ +From e8d6fcbfdb76309172f36de8b046c5543a4f4cf1 Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Tue, 23 Mar 2021 19:21:04 +0800 +Subject: [PATCH 063/189] net/hns3: support imissed stats for PF/VF + +This patch added function level imissed stats for PF and VF. In +Kunpeng920, imissed is supported, only including RPU drop stats in PF. +In kunpeng930, imissed is supported,including RPU drop stats and SSU +drop stats in PF. + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.h | 13 +++ + drivers/net/hns3/hns3_ethdev.c | 2 + + drivers/net/hns3/hns3_ethdev.h | 21 ++++ + drivers/net/hns3/hns3_ethdev_vf.c | 9 ++ + drivers/net/hns3/hns3_regs.h | 2 + + drivers/net/hns3/hns3_stats.c | 234 +++++++++++++++++++++++++++++--------- + drivers/net/hns3/hns3_stats.h | 1 + + 7 files changed, 230 insertions(+), 52 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 094bf7e..e704d0c 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -111,6 +111,8 @@ enum hns3_opcode_type { + + HNS3_OPC_QUERY_DEV_SPECS = 0x0050, + ++ HNS3_OPC_SSU_DROP_REG = 0x0065, ++ + /* MAC command */ + HNS3_OPC_CONFIG_MAC_MODE = 0x0301, + HNS3_OPC_QUERY_LINK_STATUS = 0x0307, +@@ -957,6 +959,17 @@ struct hns3_query_rpu_cmd { + uint32_t rsv2[2]; + }; + ++#define HNS3_OPC_SSU_DROP_REG_NUM 2 ++ ++struct hns3_query_ssu_cmd { ++ uint8_t rxtx; ++ uint8_t rsv[3]; ++ uint32_t full_drop_cnt; ++ uint32_t part_drop_cnt; ++ uint32_t oq_drop_cnt; ++ uint32_t rev1[2]; ++}; ++ + #define HNS3_MAX_TQP_NUM_HIP08_PF 64 + #define HNS3_DEFAULT_TX_BUF 0x4000 /* 16k bytes */ + #define HNS3_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7bdc6f7..b5057da 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -3122,6 +3122,7 @@ hns3_get_capability(struct hns3_hw *hw) + hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US; + hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM; + hw->vlan_mode = HNS3_SW_SHIFT_AND_DISCARD_MODE; ++ hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE1; + hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN; + pf->tqp_config_mode = HNS3_FIXED_MAX_TQP_NUM_MODE; + hw->rss_info.ipv6_sctp_offload_supported = false; +@@ -3140,6 +3141,7 @@ hns3_get_capability(struct hns3_hw *hw) + hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US; + hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM; + hw->vlan_mode = HNS3_HW_SHIFT_AND_DISCARD_MODE; ++ hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE2; + hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN; + pf->tqp_config_mode = HNS3_FLEX_MAX_TQP_NUM_MODE; + hw->rss_info.ipv6_sctp_offload_supported = true; +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index dfe0c59..01561cc 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -426,6 +426,9 @@ struct hns3_queue_intr { + #define HNS3_TSO_SW_CAL_PSEUDO_H_CSUM 0 + #define HNS3_TSO_HW_CAL_PSEUDO_H_CSUM 1 + ++#define HNS3_PKTS_DROP_STATS_MODE1 0 ++#define HNS3_PKTS_DROP_STATS_MODE2 1 ++ + struct hns3_hw { + struct rte_eth_dev_data *data; + void *io_base; +@@ -544,6 +547,24 @@ struct hns3_hw { + * port won't be copied to the function which has set promisc mode. + */ + uint8_t promisc_mode; ++ ++ /* ++ * drop_stats_mode mode. ++ * value range: ++ * HNS3_PKTS_DROP_STATS_MODE1/HNS3_PKTS_DROP_STATS_MODE2 ++ * ++ * - HNS3_PKTS_DROP_STATS_MODE1 ++ * This mode for kunpeng920. In this mode, port level imissed stats ++ * is supported. It only includes RPU drop stats. ++ * ++ * - HNS3_PKTS_DROP_STATS_MODE2 ++ * This mode for kunpeng930. In this mode, imissed stats and oerrors ++ * stats is supported. Function level imissed stats is supported. It ++ * includes RPU drop stats in VF, and includes both RPU drop stats ++ * and SSU drop stats in PF. Oerror stats is also supported in PF. ++ */ ++ uint8_t drop_stats_mode; ++ + uint8_t max_non_tso_bd_num; /* max BD number of one non-TSO packet */ + + struct hns3_port_base_vlan_config port_base_vlan_cfg; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 35c42ca..c567dff 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1221,6 +1221,7 @@ hns3vf_get_capability(struct hns3_hw *hw) + hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE; + hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US; + hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM; ++ hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE1; + hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN; + hw->rss_info.ipv6_sctp_offload_supported = false; + hw->promisc_mode = HNS3_UNLIMIT_PROMISC_MODE; +@@ -1238,6 +1239,7 @@ hns3vf_get_capability(struct hns3_hw *hw) + hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_ALL; + hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US; + hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM; ++ hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE2; + hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN; + hw->rss_info.ipv6_sctp_offload_supported = true; + hw->promisc_mode = HNS3_LIMIT_PROMISC_MODE; +@@ -1875,6 +1877,13 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) + if (ret) + goto err_get_config; + ++ /* Hardware statistics of imissed registers cleared. */ ++ ret = hns3_update_imissed_stats(hw, true); ++ if (ret) { ++ hns3_err(hw, "clear imissed stats failed, ret = %d", ret); ++ goto err_set_tc_queue; ++ } ++ + ret = hns3vf_set_tc_queue_mapping(hns, hw->tqps_num, hw->tqps_num); + if (ret) { + PMD_INIT_LOG(ERR, "failed to set tc info, ret = %d.", ret); +diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h +index 0540554..e141fe1 100644 +--- a/drivers/net/hns3/hns3_regs.h ++++ b/drivers/net/hns3/hns3_regs.h +@@ -36,6 +36,8 @@ + #define HNS3_GLOBAL_RESET_REG 0x20A00 + #define HNS3_FUN_RST_ING 0x20C00 + #define HNS3_GRO_EN_REG 0x28000 ++ ++#define HNS3_RPU_DROP_CNT_REG 0x28004 + #define HNS3_RXD_ADV_LAYOUT_EN_REG 0x28008 + + /* Vector0 register bits for reset */ +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 7cda36c..e802c0b 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -269,6 +269,8 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = { + static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = { + {"RPU_DROP_CNT", + HNS3_IMISSED_STATS_FIELD_OFFSET(rpu_rx_drop_cnt)}, ++ {"SSU_DROP_CNT", ++ HNS3_IMISSED_STATS_FIELD_OFFSET(ssu_rx_drop_cnt)}, + }; + + #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \ +@@ -301,8 +303,7 @@ static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = { + #define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \ + sizeof(hns3_imissed_stats_strings[0])) + +-#define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + \ +- HNS3_NUM_RESET_XSTATS + HNS3_NUM_IMISSED_XSTATS) ++#define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_RESET_XSTATS) + + static void hns3_tqp_stats_clear(struct hns3_hw *hw); + +@@ -419,7 +420,7 @@ hns3_query_update_mac_stats(struct rte_eth_dev *dev) + } + + static int +-hns3_update_rpu_drop_stats(struct hns3_hw *hw) ++hns3_update_port_rpu_drop_stats(struct hns3_hw *hw) + { + struct hns3_rx_missed_stats *stats = &hw->imissed_stats; + struct hns3_query_rpu_cmd *req; +@@ -449,11 +450,90 @@ hns3_update_rpu_drop_stats(struct hns3_hw *hw) + return 0; + } + ++static void ++hns3_update_function_rpu_drop_stats(struct hns3_hw *hw) ++{ ++ struct hns3_rx_missed_stats *stats = &hw->imissed_stats; ++ ++ stats->rpu_rx_drop_cnt += hns3_read_dev(hw, HNS3_RPU_DROP_CNT_REG); ++} ++ ++static int ++hns3_update_rpu_drop_stats(struct hns3_hw *hw) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ int ret = 0; ++ ++ if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && !hns->is_vf) ++ ret = hns3_update_port_rpu_drop_stats(hw); ++ else if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2) ++ hns3_update_function_rpu_drop_stats(hw); ++ ++ return ret; ++} ++ ++static int ++hns3_get_ssu_drop_stats(struct hns3_hw *hw, struct hns3_cmd_desc *desc, ++ int bd_num, bool is_rx) ++{ ++ struct hns3_query_ssu_cmd *req; ++ int ret; ++ int i; ++ ++ for (i = 0; i < bd_num - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], ++ HNS3_OPC_SSU_DROP_REG, true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_SSU_DROP_REG, true); ++ req = (struct hns3_query_ssu_cmd *)desc[0].data; ++ req->rxtx = is_rx ? 0 : 1; ++ ret = hns3_cmd_send(hw, desc, bd_num); ++ ++ return ret; ++} ++ ++static int ++hns3_update_port_rx_ssu_drop_stats(struct hns3_hw *hw) ++{ ++ struct hns3_rx_missed_stats *stats = &hw->imissed_stats; ++ struct hns3_cmd_desc desc[HNS3_OPC_SSU_DROP_REG_NUM]; ++ struct hns3_query_ssu_cmd *req; ++ uint64_t cnt; ++ int ret; ++ ++ ret = hns3_get_ssu_drop_stats(hw, desc, HNS3_OPC_SSU_DROP_REG_NUM, ++ true); ++ if (ret) { ++ hns3_err(hw, "failed to get Rx SSU drop stats, ret = %d", ret); ++ return ret; ++ } ++ ++ req = (struct hns3_query_ssu_cmd *)desc[0].data; ++ cnt = rte_le_to_cpu_32(req->oq_drop_cnt) + ++ rte_le_to_cpu_32(req->full_drop_cnt) + ++ rte_le_to_cpu_32(req->part_drop_cnt); ++ ++ stats->ssu_rx_drop_cnt += cnt; ++ ++ return 0; ++} ++ + int + hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + int ret; + ++ if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf) ++ return 0; ++ ++ if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf) { ++ ret = hns3_update_port_rx_ssu_drop_stats(hw); ++ if (ret) ++ return ret; ++ } ++ + ret = hns3_update_rpu_drop_stats(hw); + if (ret) + return ret; +@@ -488,19 +568,17 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + uint16_t i; + int ret; + +- if (!hns->is_vf) { +- /* Update imissed stats */ +- ret = hns3_update_imissed_stats(hw, false); +- if (ret) { +- hns3_err(hw, "update imissed stats failed, ret = %d", +- ret); +- return ret; +- } +- +- rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt; ++ /* Update imissed stats */ ++ ret = hns3_update_imissed_stats(hw, false); ++ if (ret) { ++ hns3_err(hw, "update imissed stats failed, ret = %d", ++ ret); ++ return ret; + } ++ rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt + ++ imissed_stats->ssu_rx_drop_cnt; + +- /* Reads all the stats of a rxq in a loop to keep them synchronized */ ++ /* Get the error stats and bytes of received packets */ + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq == NULL) +@@ -556,17 +634,14 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + uint16_t i; + int ret; + +- if (!hns->is_vf) { +- /* +- * Note: Reading hardware statistics of imissed registers will +- * clear them. +- */ +- ret = hns3_update_imissed_stats(hw, true); +- if (ret) { +- hns3_err(hw, "clear imissed stats failed, ret = %d", +- ret); +- return ret; +- } ++ /* ++ * Note: Reading hardware statistics of imissed registers will ++ * clear them. ++ */ ++ ret = hns3_update_imissed_stats(hw, true); ++ if (ret) { ++ hns3_err(hw, "clear imissed stats failed, ret = %d", ret); ++ return ret; + } + + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { +@@ -630,6 +705,22 @@ hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev) + return 0; + } + ++static int ++hns3_get_imissed_stats_num(struct hns3_adapter *hns) ++{ ++#define NO_IMISSED_STATS_NUM 0 ++#define RPU_STATS_ITEM_NUM 1 ++ struct hns3_hw *hw = &hns->hw; ++ ++ if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf) ++ return NO_IMISSED_STATS_NUM; ++ ++ if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf) ++ return HNS3_NUM_IMISSED_XSTATS; ++ ++ return RPU_STATS_ITEM_NUM; ++} ++ + /* This function calculates the number of xstats based on the current config */ + static int + hns3_xstats_calc_num(struct rte_eth_dev *dev) +@@ -647,13 +738,17 @@ hns3_xstats_calc_num(struct rte_eth_dev *dev) + uint16_t nb_tx_q = dev->data->nb_tx_queues; + int rx_comm_stats_num = nb_rx_q * HNS3_PF_VF_RX_COMM_STATS_NUM; + int tx_comm_stats_num = nb_tx_q * HNS3_PF_VF_TX_COMM_STATS_NUM; ++ int stats_num; ++ ++ stats_num = rx_comm_stats_num + tx_comm_stats_num; ++ stats_num += hns3_get_imissed_stats_num(hns); + + if (hns->is_vf) +- return rx_comm_stats_num + tx_comm_stats_num + +- HNS3_NUM_RESET_XSTATS; ++ stats_num += HNS3_NUM_RESET_XSTATS; + else +- return rx_comm_stats_num + tx_comm_stats_num + +- HNS3_FIX_NUM_STATS; ++ stats_num += HNS3_FIX_NUM_STATS; ++ ++ return stats_num; + } + + static void +@@ -835,6 +930,31 @@ hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + hns3_txq_basic_stats_get(dev, xstats, count); + } + ++static void ++hns3_imissed_stats_get(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; ++ struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats; ++ int imissed_stats_num; ++ int cnt = *count; ++ char *addr; ++ uint16_t i; ++ ++ imissed_stats_num = hns3_get_imissed_stats_num(hns); ++ ++ for (i = 0; i < imissed_stats_num; i++) { ++ addr = (char *)imissed_stats + ++ hns3_imissed_stats_strings[i].offset; ++ xstats[cnt].value = *(uint64_t *)addr; ++ xstats[cnt].id = cnt; ++ cnt++; ++ } ++ ++ *count = cnt; ++} ++ + /* + * Retrieve extended(tqp | Mac) statistics of an Ethernet device. + * @param dev +@@ -854,7 +974,6 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats; + struct hns3_mac_stats *mac_stats = &hw->mac_stats; + struct hns3_reset_stats *reset_stats = &hw->reset.stats; + struct hns3_rx_bd_errors_stats *rx_err_stats; +@@ -890,24 +1009,17 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + xstats[count].id = count; + count++; + } ++ } + +- ret = hns3_update_imissed_stats(hw, false); +- if (ret) { +- hns3_err(hw, "update imissed stats failed, ret = %d", +- ret); +- return ret; +- } +- +- for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) { +- addr = (char *)imissed_stats + +- hns3_imissed_stats_strings[i].offset; +- xstats[count].value = *(uint64_t *)addr; +- xstats[count].id = count; +- count++; +- } +- ++ ret = hns3_update_imissed_stats(hw, false); ++ if (ret) { ++ hns3_err(hw, "update imissed stats failed, ret = %d", ++ ret); ++ return ret; + } + ++ hns3_imissed_stats_get(dev, xstats, &count); ++ + /* Get the reset stat */ + for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) { + addr = (char *)reset_stats + hns3_reset_stats_strings[i].offset; +@@ -992,6 +1104,28 @@ hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev, + } + } + ++static void ++hns3_imissed_stats_name_get(struct rte_eth_dev *dev, ++ struct rte_eth_xstat_name *xstats_names, ++ uint32_t *count) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ uint32_t cnt = *count; ++ int imissed_stats_num; ++ uint16_t i; ++ ++ imissed_stats_num = hns3_get_imissed_stats_num(hns); ++ ++ for (i = 0; i < imissed_stats_num; i++) { ++ snprintf(xstats_names[cnt].name, ++ sizeof(xstats_names[cnt].name), ++ "%s", hns3_imissed_stats_strings[i].name); ++ cnt++; ++ } ++ ++ *count = cnt; ++} ++ + /* + * Retrieve names of extended statistics of an Ethernet device. + * +@@ -1040,14 +1174,10 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev, + "%s", hns3_mac_strings[i].name); + count++; + } +- +- for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) { +- snprintf(xstats_names[count].name, +- sizeof(xstats_names[count].name), +- "%s", hns3_imissed_stats_strings[i].name); +- count++; +- } + } ++ ++ hns3_imissed_stats_name_get(dev, xstats_names, &count); ++ + for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), +diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h +index 8ea69b4..273be42 100644 +--- a/drivers/net/hns3/hns3_stats.h ++++ b/drivers/net/hns3/hns3_stats.h +@@ -112,6 +112,7 @@ struct hns3_mac_stats { + + struct hns3_rx_missed_stats { + uint64_t rpu_rx_drop_cnt; ++ uint64_t ssu_rx_drop_cnt; + }; + + /* store statistics names and its offset in stats structure */ +-- +2.7.4 + diff --git a/0064-net-hns3-support-oerrors-stats-in-PF.patch b/0064-net-hns3-support-oerrors-stats-in-PF.patch new file mode 100644 index 0000000..d92c24d --- /dev/null +++ b/0064-net-hns3-support-oerrors-stats-in-PF.patch @@ -0,0 +1,124 @@ +From afd493a7e66236c538bf9ab7feb332200cbd2e76 Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Tue, 23 Mar 2021 19:21:05 +0800 +Subject: [PATCH 064/189] net/hns3: support oerrors stats in PF + +This patch added oerrors stats for PF in kunpeng930. + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 1 + + drivers/net/hns3/hns3_stats.c | 64 +++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 64 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 01561cc..6800ee0 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -443,6 +443,7 @@ struct hns3_hw { + /* Include Mac stats | Rx stats | Tx stats */ + struct hns3_mac_stats mac_stats; + struct hns3_rx_missed_stats imissed_stats; ++ uint64_t oerror_stats; + uint32_t fw_version; + + uint16_t num_msi; +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index e802c0b..1af689f 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -519,6 +519,31 @@ hns3_update_port_rx_ssu_drop_stats(struct hns3_hw *hw) + return 0; + } + ++static int ++hns3_update_port_tx_ssu_drop_stats(struct hns3_hw *hw) ++{ ++ struct hns3_cmd_desc desc[HNS3_OPC_SSU_DROP_REG_NUM]; ++ struct hns3_query_ssu_cmd *req; ++ uint64_t cnt; ++ int ret; ++ ++ ret = hns3_get_ssu_drop_stats(hw, desc, HNS3_OPC_SSU_DROP_REG_NUM, ++ false); ++ if (ret) { ++ hns3_err(hw, "failed to get Tx SSU drop stats, ret = %d", ret); ++ return ret; ++ } ++ ++ req = (struct hns3_query_ssu_cmd *)desc[0].data; ++ cnt = rte_le_to_cpu_32(req->oq_drop_cnt) + ++ rte_le_to_cpu_32(req->full_drop_cnt) + ++ rte_le_to_cpu_32(req->part_drop_cnt); ++ ++ hw->oerror_stats += cnt; ++ ++ return 0; ++} ++ + int + hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear) + { +@@ -544,6 +569,25 @@ hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear) + return 0; + } + ++static int ++hns3_update_oerror_stats(struct hns3_hw *hw, bool is_clear) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ int ret; ++ ++ if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 || hns->is_vf) ++ return 0; ++ ++ ret = hns3_update_port_tx_ssu_drop_stats(hw); ++ if (ret) ++ return ret; ++ ++ if (is_clear) ++ hw->oerror_stats = 0; ++ ++ return 0; ++} ++ + /* + * Query tqp tx queue statistics ,opcode id: 0x0B03. + * Query tqp rx queue statistics ,opcode id: 0x0B13. +@@ -608,7 +652,14 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats) + rte_stats->obytes += txq->basic_stats.bytes; + } + +- rte_stats->oerrors = 0; ++ ret = hns3_update_oerror_stats(hw, false); ++ if (ret) { ++ hns3_err(hw, "update oerror stats failed, ret = %d", ++ ret); ++ return ret; ++ } ++ rte_stats->oerrors = hw->oerror_stats; ++ + /* + * If HW statistics are reset by stats_reset, but a lot of residual + * packets exist in the hardware queue and these packets are error +@@ -644,6 +695,17 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) + return ret; + } + ++ /* ++ * Note: Reading hardware statistics of oerror registers will ++ * clear them. ++ */ ++ ret = hns3_update_oerror_stats(hw, true); ++ if (ret) { ++ hns3_err(hw, "clear oerror stats failed, ret = %d", ++ ret); ++ return ret; ++ } ++ + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + rxq = eth_dev->data->rx_queues[i]; + if (rxq == NULL) +-- +2.7.4 + diff --git a/0065-net-hns3-support-Tx-descriptor-status-query.patch b/0065-net-hns3-support-Tx-descriptor-status-query.patch new file mode 100644 index 0000000..6ca2ecb --- /dev/null +++ b/0065-net-hns3-support-Tx-descriptor-status-query.patch @@ -0,0 +1,128 @@ +From 71c308ebc61180d6f7a65c9f4dfdfc5e6d1fb782 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Tue, 23 Mar 2021 19:21:06 +0800 +Subject: [PATCH 065/189] net/hns3: support Tx descriptor status query + +Add support for query Tx descriptor status in hns3 driver. Check the +descriptor specified and provide the status information of the +corresponding descriptor. + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/features/hns3.ini | 1 + + doc/guides/nics/features/hns3_vf.ini | 1 + + drivers/net/hns3/hns3_ethdev.c | 1 + + drivers/net/hns3/hns3_ethdev_vf.c | 1 + + drivers/net/hns3/hns3_rxtx.c | 28 ++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx.h | 1 + + 6 files changed, 33 insertions(+) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index 00a26cd..445d391 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -34,6 +34,7 @@ L4 checksum offload = Y + Inner L3 checksum = Y + Inner L4 checksum = Y + Packet type parsing = Y ++Tx descriptor status = Y + Basic stats = Y + Extended stats = Y + Stats per queue = Y +diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini +index f3dd239..eb55b4f 100644 +--- a/doc/guides/nics/features/hns3_vf.ini ++++ b/doc/guides/nics/features/hns3_vf.ini +@@ -32,6 +32,7 @@ L4 checksum offload = Y + Inner L3 checksum = Y + Inner L4 checksum = Y + Packet type parsing = Y ++Tx descriptor status = Y + Basic stats = Y + Extended stats = Y + Stats per queue = Y +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index b5057da..5b07183 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6774,6 +6774,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + eth_dev->tx_pkt_prepare = NULL; ++ eth_dev->tx_descriptor_status = NULL; + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; + return ret; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index c567dff..2688c19 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2917,6 +2917,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + eth_dev->tx_pkt_prepare = NULL; ++ eth_dev->tx_descriptor_status = NULL; + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 404c403..efdb49a 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4044,6 +4044,7 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + eth_dev->rx_pkt_burst = hns3_get_rx_function(eth_dev); + eth_dev->tx_pkt_burst = hns3_get_tx_function(eth_dev, &prep); + eth_dev->tx_pkt_prepare = prep; ++ eth_dev->tx_descriptor_status = hns3_dev_tx_descriptor_status; + } else { + eth_dev->rx_pkt_burst = hns3_dummy_rxtx_burst; + eth_dev->tx_pkt_burst = hns3_dummy_rxtx_burst; +@@ -4256,6 +4257,33 @@ hns3_tx_done_cleanup(void *txq, uint32_t free_cnt) + return -ENOTSUP; + } + ++int ++hns3_dev_tx_descriptor_status(void *tx_queue, uint16_t offset) ++{ ++ volatile struct hns3_desc *txdp; ++ struct hns3_tx_queue *txq; ++ struct rte_eth_dev *dev; ++ uint16_t desc_id; ++ ++ txq = (struct hns3_tx_queue *)tx_queue; ++ if (offset >= txq->nb_tx_desc) ++ return -EINVAL; ++ ++ dev = &rte_eth_devices[txq->port_id]; ++ if (dev->tx_pkt_burst != hns3_xmit_pkts_simple && ++ dev->tx_pkt_burst != hns3_xmit_pkts && ++ dev->tx_pkt_burst != hns3_xmit_pkts_vec_sve && ++ dev->tx_pkt_burst != hns3_xmit_pkts_vec) ++ return RTE_ETH_TX_DESC_UNAVAIL; ++ ++ desc_id = (txq->next_to_use + offset) % txq->nb_tx_desc; ++ txdp = &txq->tx_ring[desc_id]; ++ if (txdp->tx.tp_fe_sc_vld_ra_ri & rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B))) ++ return RTE_ETH_TX_DESC_FULL; ++ else ++ return RTE_ETH_TX_DESC_DONE; ++} ++ + uint32_t + hns3_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) + { +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index cd04200..82d5aa0 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -720,5 +720,6 @@ void hns3_stop_all_txqs(struct rte_eth_dev *dev); + void hns3_restore_tqp_enable_state(struct hns3_hw *hw); + int hns3_tx_done_cleanup(void *txq, uint32_t free_cnt); + void hns3_enable_rxd_adv_layout(struct hns3_hw *hw); ++int hns3_dev_tx_descriptor_status(void *tx_queue, uint16_t offset); + + #endif /* _HNS3_RXTX_H_ */ +-- +2.7.4 + diff --git a/0066-net-hns3-support-Rx-descriptor-status-query.patch b/0066-net-hns3-support-Rx-descriptor-status-query.patch new file mode 100644 index 0000000..792e846 --- /dev/null +++ b/0066-net-hns3-support-Rx-descriptor-status-query.patch @@ -0,0 +1,137 @@ +From d29daf59b08c1314190c6d1cab0e22ee176b6c0f Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Tue, 23 Mar 2021 19:21:07 +0800 +Subject: [PATCH 066/189] net/hns3: support Rx descriptor status query + +Add support for query Rx descriptor status in hns3 driver. Check the +descriptor specified and provide the status information of the +corresponding descriptor. + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/features/hns3.ini | 1 + + doc/guides/nics/features/hns3_vf.ini | 1 + + drivers/net/hns3/hns3_ethdev.c | 1 + + drivers/net/hns3/hns3_ethdev_vf.c | 1 + + drivers/net/hns3/hns3_rxtx.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx.h | 1 + + 6 files changed, 41 insertions(+) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index 445d391..d407b2f 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -34,6 +34,7 @@ L4 checksum offload = Y + Inner L3 checksum = Y + Inner L4 checksum = Y + Packet type parsing = Y ++Rx descriptor status = Y + Tx descriptor status = Y + Basic stats = Y + Extended stats = Y +diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini +index eb55b4f..a0fd56d 100644 +--- a/doc/guides/nics/features/hns3_vf.ini ++++ b/doc/guides/nics/features/hns3_vf.ini +@@ -33,6 +33,7 @@ Inner L3 checksum = Y + Inner L4 checksum = Y + Packet type parsing = Y + Tx descriptor status = Y ++Rx descriptor status = Y + Basic stats = Y + Extended stats = Y + Stats per queue = Y +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 5b07183..12cc3ac 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6772,6 +6772,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + err_mp_init_secondary: + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; ++ eth_dev->rx_descriptor_status = NULL; + eth_dev->tx_pkt_burst = NULL; + eth_dev->tx_pkt_prepare = NULL; + eth_dev->tx_descriptor_status = NULL; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 2688c19..6404264 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2915,6 +2915,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) + err_mp_init_secondary: + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; ++ eth_dev->rx_descriptor_status = NULL; + eth_dev->tx_pkt_burst = NULL; + eth_dev->tx_pkt_prepare = NULL; + eth_dev->tx_descriptor_status = NULL; +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index efdb49a..6a7c360 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4042,6 +4042,7 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + if (hns->hw.adapter_state == HNS3_NIC_STARTED && + __atomic_load_n(&hns->hw.reset.resetting, __ATOMIC_RELAXED) == 0) { + eth_dev->rx_pkt_burst = hns3_get_rx_function(eth_dev); ++ eth_dev->rx_descriptor_status = hns3_dev_rx_descriptor_status; + eth_dev->tx_pkt_burst = hns3_get_tx_function(eth_dev, &prep); + eth_dev->tx_pkt_prepare = prep; + eth_dev->tx_descriptor_status = hns3_dev_tx_descriptor_status; +@@ -4258,6 +4259,41 @@ hns3_tx_done_cleanup(void *txq, uint32_t free_cnt) + } + + int ++hns3_dev_rx_descriptor_status(void *rx_queue, uint16_t offset) ++{ ++ volatile struct hns3_desc *rxdp; ++ struct hns3_rx_queue *rxq; ++ struct rte_eth_dev *dev; ++ uint32_t bd_base_info; ++ uint16_t desc_id; ++ ++ rxq = (struct hns3_rx_queue *)rx_queue; ++ if (offset >= rxq->nb_rx_desc) ++ return -EINVAL; ++ ++ desc_id = (rxq->next_to_use + offset) % rxq->nb_rx_desc; ++ rxdp = &rxq->rx_ring[desc_id]; ++ bd_base_info = rte_le_to_cpu_32(rxdp->rx.bd_base_info); ++ dev = &rte_eth_devices[rxq->port_id]; ++ if (dev->rx_pkt_burst == hns3_recv_pkts || ++ dev->rx_pkt_burst == hns3_recv_scattered_pkts) { ++ if (offset >= rxq->nb_rx_desc - rxq->rx_free_hold) ++ return RTE_ETH_RX_DESC_UNAVAIL; ++ } else if (dev->rx_pkt_burst == hns3_recv_pkts_vec || ++ dev->rx_pkt_burst == hns3_recv_pkts_vec_sve){ ++ if (offset >= rxq->nb_rx_desc - rxq->rx_rearm_nb) ++ return RTE_ETH_RX_DESC_UNAVAIL; ++ } else { ++ return RTE_ETH_RX_DESC_UNAVAIL; ++ } ++ ++ if (!(bd_base_info & BIT(HNS3_RXD_VLD_B))) ++ return RTE_ETH_RX_DESC_AVAIL; ++ else ++ return RTE_ETH_RX_DESC_DONE; ++} ++ ++int + hns3_dev_tx_descriptor_status(void *tx_queue, uint16_t offset) + { + volatile struct hns3_desc *txdp; +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 82d5aa0..f9b3048 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -720,6 +720,7 @@ void hns3_stop_all_txqs(struct rte_eth_dev *dev); + void hns3_restore_tqp_enable_state(struct hns3_hw *hw); + int hns3_tx_done_cleanup(void *txq, uint32_t free_cnt); + void hns3_enable_rxd_adv_layout(struct hns3_hw *hw); ++int hns3_dev_rx_descriptor_status(void *rx_queue, uint16_t offset); + int hns3_dev_tx_descriptor_status(void *tx_queue, uint16_t offset); + + #endif /* _HNS3_RXTX_H_ */ +-- +2.7.4 + diff --git a/0067-net-hns3-fix-reporting-undefined-speed.patch b/0067-net-hns3-fix-reporting-undefined-speed.patch new file mode 100644 index 0000000..7a9d92d --- /dev/null +++ b/0067-net-hns3-fix-reporting-undefined-speed.patch @@ -0,0 +1,57 @@ +From 3a77c6eecf9089843c3f4452139c07ffe5c6823d Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 23 Mar 2021 21:45:51 +0800 +Subject: [PATCH 067/189] net/hns3: fix reporting undefined speed + +There may be a case in future that the speed obtained from firmware +is undefined (such as, 400G or other rate), and link status of device is +up. At this case, PMD driver will reports 100Mbps to the user in the +"hns3_dev_link_update" API, which is unreasonable. Besides, if the +speed from firmware is zero, driver should report zero instead of +100Mbps. + +Fixes: 59fad0f32135 ("net/hns3: support link update operation") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 5 ++++- + drivers/net/hns3/hns3_ethdev_vf.c | 5 ++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 12cc3ac..55e2f07 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2725,7 +2725,10 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, + new_link.link_speed = mac->link_speed; + break; + default: +- new_link.link_speed = ETH_SPEED_NUM_100M; ++ if (mac->link_status) ++ new_link.link_speed = ETH_SPEED_NUM_UNKNOWN; ++ else ++ new_link.link_speed = ETH_SPEED_NUM_NONE; + break; + } + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 6404264..26f0698 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2123,7 +2123,10 @@ hns3vf_dev_link_update(struct rte_eth_dev *eth_dev, + new_link.link_speed = mac->link_speed; + break; + default: +- new_link.link_speed = ETH_SPEED_NUM_100M; ++ if (mac->link_status) ++ new_link.link_speed = ETH_SPEED_NUM_UNKNOWN; ++ else ++ new_link.link_speed = ETH_SPEED_NUM_NONE; + break; + } + +-- +2.7.4 + diff --git a/0068-net-hns3-fix-build-for-SVE-path.patch b/0068-net-hns3-fix-build-for-SVE-path.patch new file mode 100644 index 0000000..3bd8423 --- /dev/null +++ b/0068-net-hns3-fix-build-for-SVE-path.patch @@ -0,0 +1,35 @@ +From 2043f4bf46fe0403c6015da614d0bb3f9f9f4344 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 23 Mar 2021 21:45:52 +0800 +Subject: [PATCH 068/189] net/hns3: fix build for SVE path + +The 'queue_full_cnt' stats have been encapsulated in 'dfx_stats'. +However, the modification in the SVE algorithm is omitted. +As a result, the driver fails to be compiled when the SVE +algorithm is used. + +Fixes: 9b77f1fe303f ("net/hns3: encapsulate DFX stats in datapath") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx_vec_sve.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index f6c6f52..2700e6e 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -439,7 +439,7 @@ hns3_xmit_fixed_burst_vec_sve(void *__restrict tx_queue, + + nb_pkts = RTE_MIN(txq->tx_bd_ready, nb_pkts); + if (unlikely(nb_pkts == 0)) { +- txq->queue_full_cnt++; ++ txq->dfx_stats.queue_full_cnt++; + return 0; + } + +-- +2.7.4 + diff --git a/0069-net-hns3-fix-processing-Tx-offload-flags.patch b/0069-net-hns3-fix-processing-Tx-offload-flags.patch new file mode 100644 index 0000000..96b187d --- /dev/null +++ b/0069-net-hns3-fix-processing-Tx-offload-flags.patch @@ -0,0 +1,34 @@ +From 5233a6a3449ff374def3469b79d98a85e6cfd6f1 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Tue, 23 Mar 2021 21:45:53 +0800 +Subject: [PATCH 069/189] net/hns3: fix processing Tx offload flags + +Currently, if the PKT_TX_TCP_SEG and PKT_TX_TCP_CKSUM offload flags set +in the same time, hns3 PMD can not process the descriptors correctly. + +This patch fixes it by adding the processing of this situation. + +Fixes: fb6eb9009f41 ("net/hns3: fix Tx checksum with fixed header length") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 6a7c360..62c56f6 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -3291,6 +3291,7 @@ hns3_parse_l4_cksum_params(struct rte_mbuf *m, uint32_t *type_cs_vlan_tso_len) + uint32_t tmp; + /* Enable L4 checksum offloads */ + switch (ol_flags & (PKT_TX_L4_MASK | PKT_TX_TCP_SEG)) { ++ case PKT_TX_TCP_CKSUM | PKT_TX_TCP_SEG: + case PKT_TX_TCP_CKSUM: + case PKT_TX_TCP_SEG: + tmp = *type_cs_vlan_tso_len; +-- +2.7.4 + diff --git a/0070-net-hns3-fix-Tx-checksum-for-UDP-packets-with-specia.patch b/0070-net-hns3-fix-Tx-checksum-for-UDP-packets-with-specia.patch new file mode 100644 index 0000000..16e83a9 --- /dev/null +++ b/0070-net-hns3-fix-Tx-checksum-for-UDP-packets-with-specia.patch @@ -0,0 +1,225 @@ +From 77d2a11852ab27e6ac367cc3bf2146b9e1aa2d0c Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Tue, 23 Mar 2021 21:45:54 +0800 +Subject: [PATCH 070/189] net/hns3: fix Tx checksum for UDP packets with + special port + +For Kunpeng920 network engine, UDP packets with destination port 6081, +4789 or 4790 will be identified as tunnel packets. If the UDP CKSUM +offload is set in the mbuf, and the TX tunnel mask is not set, the +CKSUM of these packets will be wrong. In this case, the upper layer +user may not identify the packet as a tunnel packet, and processes it +as non-tunnel packet, and expect to offload the outer UDP CKSUM, so +they may not fill the outer L2/L3 length to mbuf. However, the HW +identifies these packet as tunnel packets and therefore offload the +inner UDP CKSUM. As a result, the inner and outer UDP CKSUM are +incorrect. And for non-tunnel UDP packets with preceding special +destination port will also exist similar checksum error. + +For the new generation Kunpeng930 network engine, the above errata +have been fixed. Therefore, the concept of udp_cksum_mode is +introduced. There are two udp_cksum_mode for hns3 PMD, +HNS3_SPECIAL_PORT_HW_CKSUM_MODE means HW could solve the above +problem. And in HNS3_SPECIAL_PORT_SW_CKSUM_MODE, hns3 PMD will check +packets in the Tx prepare and perform the UDP CKSUM for such packets +to avoid a checksum error. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 2 ++ + drivers/net/hns3/hns3_ethdev.h | 19 ++++++++++++ + drivers/net/hns3/hns3_rxtx.c | 68 ++++++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx.h | 16 ++++++++++ + 4 files changed, 105 insertions(+) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 55e2f07..3e0b28a 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -3129,6 +3129,7 @@ hns3_get_capability(struct hns3_hw *hw) + hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN; + pf->tqp_config_mode = HNS3_FIXED_MAX_TQP_NUM_MODE; + hw->rss_info.ipv6_sctp_offload_supported = false; ++ hw->udp_cksum_mode = HNS3_SPECIAL_PORT_SW_CKSUM_MODE; + return 0; + } + +@@ -3148,6 +3149,7 @@ hns3_get_capability(struct hns3_hw *hw) + hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN; + pf->tqp_config_mode = HNS3_FLEX_MAX_TQP_NUM_MODE; + hw->rss_info.ipv6_sctp_offload_supported = true; ++ hw->udp_cksum_mode = HNS3_SPECIAL_PORT_HW_CKSUM_MODE; + + return 0; + } +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 6800ee0..eb2203c 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -47,6 +47,9 @@ + #define HNS3_UNLIMIT_PROMISC_MODE 0 + #define HNS3_LIMIT_PROMISC_MODE 1 + ++#define HNS3_SPECIAL_PORT_SW_CKSUM_MODE 0 ++#define HNS3_SPECIAL_PORT_HW_CKSUM_MODE 1 ++ + #define HNS3_UC_MACADDR_NUM 128 + #define HNS3_VF_UC_MACADDR_NUM 48 + #define HNS3_MC_MACADDR_NUM 128 +@@ -567,6 +570,22 @@ struct hns3_hw { + uint8_t drop_stats_mode; + + uint8_t max_non_tso_bd_num; /* max BD number of one non-TSO packet */ ++ /* ++ * udp checksum mode. ++ * value range: ++ * HNS3_SPECIAL_PORT_HW_CKSUM_MODE/HNS3_SPECIAL_PORT_SW_CKSUM_MODE ++ * ++ * - HNS3_SPECIAL_PORT_SW_CKSUM_MODE ++ * In this mode, HW can not do checksum for special UDP port like ++ * 4789, 4790, 6081 for non-tunnel UDP packets and UDP tunnel ++ * packets without the PKT_TX_TUNEL_MASK in the mbuf. So, PMD need ++ * do the checksum for these packets to avoid a checksum error. ++ * ++ * - HNS3_SPECIAL_PORT_HW_CKSUM_MODE ++ * In this mode, HW does not have the preceding problems and can ++ * directly calculate the checksum of these UDP packets. ++ */ ++ uint8_t udp_cksum_mode; + + struct hns3_port_base_vlan_config port_base_vlan_cfg; + /* +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 62c56f6..626f91f 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2845,6 +2846,7 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, + HNS3_RING_TX_TAIL_REG); + txq->min_tx_pkt_len = hw->min_tx_pkt_len; + txq->tso_mode = hw->tso_mode; ++ txq->udp_cksum_mode = hw->udp_cksum_mode; + memset(&txq->basic_stats, 0, sizeof(struct hns3_tx_basic_stats)); + memset(&txq->dfx_stats, 0, sizeof(struct hns3_tx_dfx_stats)); + +@@ -3548,6 +3550,69 @@ hns3_vld_vlan_chk(struct hns3_tx_queue *txq, struct rte_mbuf *m) + } + #endif + ++static uint16_t ++hns3_udp_cksum_help(struct rte_mbuf *m) ++{ ++ uint64_t ol_flags = m->ol_flags; ++ uint16_t cksum = 0; ++ uint32_t l4_len; ++ ++ if (ol_flags & PKT_TX_IPV4) { ++ struct rte_ipv4_hdr *ipv4_hdr = rte_pktmbuf_mtod_offset(m, ++ struct rte_ipv4_hdr *, m->l2_len); ++ l4_len = rte_be_to_cpu_16(ipv4_hdr->total_length) - m->l3_len; ++ } else { ++ struct rte_ipv6_hdr *ipv6_hdr = rte_pktmbuf_mtod_offset(m, ++ struct rte_ipv6_hdr *, m->l2_len); ++ l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len); ++ } ++ ++ rte_raw_cksum_mbuf(m, m->l2_len + m->l3_len, l4_len, &cksum); ++ ++ cksum = ~cksum; ++ /* ++ * RFC 768:If the computed checksum is zero for UDP, it is transmitted ++ * as all ones ++ */ ++ if (cksum == 0) ++ cksum = 0xffff; ++ ++ return (uint16_t)cksum; ++} ++ ++static bool ++hns3_validate_tunnel_cksum(struct hns3_tx_queue *tx_queue, struct rte_mbuf *m) ++{ ++ uint64_t ol_flags = m->ol_flags; ++ struct rte_udp_hdr *udp_hdr; ++ uint16_t dst_port; ++ ++ if (tx_queue->udp_cksum_mode == HNS3_SPECIAL_PORT_HW_CKSUM_MODE || ++ ol_flags & PKT_TX_TUNNEL_MASK || ++ (ol_flags & PKT_TX_L4_MASK) != PKT_TX_UDP_CKSUM) ++ return true; ++ /* ++ * A UDP packet with the same dst_port as VXLAN\VXLAN_GPE\GENEVE will ++ * be recognized as a tunnel packet in HW. In this case, if UDP CKSUM ++ * offload is set and the tunnel mask has not been set, the CKSUM will ++ * be wrong since the header length is wrong and driver should complete ++ * the CKSUM to avoid CKSUM error. ++ */ ++ udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *, ++ m->l2_len + m->l3_len); ++ dst_port = rte_be_to_cpu_16(udp_hdr->dst_port); ++ switch (dst_port) { ++ case RTE_VXLAN_DEFAULT_PORT: ++ case RTE_VXLAN_GPE_DEFAULT_PORT: ++ case RTE_GENEVE_DEFAULT_PORT: ++ udp_hdr->dgram_cksum = hns3_udp_cksum_help(m); ++ m->ol_flags = ol_flags & ~PKT_TX_L4_MASK; ++ return false; ++ default: ++ return true; ++ } ++} ++ + static int + hns3_prep_pkt_proc(struct hns3_tx_queue *tx_queue, struct rte_mbuf *m) + { +@@ -3592,6 +3657,9 @@ hns3_prep_pkt_proc(struct hns3_tx_queue *tx_queue, struct rte_mbuf *m) + return ret; + } + ++ if (!hns3_validate_tunnel_cksum(tx_queue, m)) ++ return 0; ++ + hns3_outer_header_cksum_prepare(m); + + return 0; +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index f9b3048..6689397 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -465,6 +465,22 @@ struct hns3_tx_queue { + */ + uint8_t tso_mode; + /* ++ * udp checksum mode. ++ * value range: ++ * HNS3_SPECIAL_PORT_HW_CKSUM_MODE/HNS3_SPECIAL_PORT_SW_CKSUM_MODE ++ * ++ * - HNS3_SPECIAL_PORT_SW_CKSUM_MODE ++ * In this mode, HW can not do checksum for special UDP port like ++ * 4789, 4790, 6081 for non-tunnel UDP packets and UDP tunnel ++ * packets without the PKT_TX_TUNEL_MASK in the mbuf. So, PMD need ++ * do the checksum for these packets to avoid a checksum error. ++ * ++ * - HNS3_SPECIAL_PORT_HW_CKSUM_MODE ++ * In this mode, HW does not have the preceding problems and can ++ * directly calculate the checksum of these UDP packets. ++ */ ++ uint8_t udp_cksum_mode; ++ /* + * The minimum length of the packet supported by hardware in the Tx + * direction. + */ +-- +2.7.4 + diff --git a/0071-net-hns3-fix-link-update-when-failed-to-get-link-inf.patch b/0071-net-hns3-fix-link-update-when-failed-to-get-link-inf.patch new file mode 100644 index 0000000..04b24de --- /dev/null +++ b/0071-net-hns3-fix-link-update-when-failed-to-get-link-inf.patch @@ -0,0 +1,112 @@ +From 46602854722b87761da2e56e6bd95461ddd7b6ea Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 23 Mar 2021 21:45:55 +0800 +Subject: [PATCH 071/189] net/hns3: fix link update when failed to get link + info + +In the "hns3_dev_link_update" API, the link information of the port is +obtained first, and then 'dev_link' in dev->data is updated. When the +driver is resetting or fails to obtain link info, the current driver +still reports the previous link info to the user. This may cause that +the dev->data->dev_link may be inconsistent with the hw link status. + +Therefore, the link status consistency between the hardware, driver, +and framework can be ensured in this interface regardless of whether +the driver is normal or abnormal. + +Fixes: 109e4dd1bd7a ("net/hns3: get link state change through mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 55 +++++++++++++++++++++++++++++------------- + 1 file changed, 38 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 3e0b28a..356c52a 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2698,20 +2698,22 @@ hns3_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version, + } + + static int +-hns3_dev_link_update(struct rte_eth_dev *eth_dev, +- __rte_unused int wait_to_complete) ++hns3_update_port_link_info(struct rte_eth_dev *eth_dev) + { +- struct hns3_adapter *hns = eth_dev->data->dev_private; +- struct hns3_hw *hw = &hns->hw; +- struct hns3_mac *mac = &hw->mac; +- struct rte_eth_link new_link; ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + +- if (!hns3_is_reset_pending(hns)) { +- hns3_update_link_status(hw); +- hns3_update_link_info(eth_dev); +- } ++ (void)hns3_update_link_status(hw); ++ ++ return hns3_update_link_info(eth_dev); ++} ++ ++static void ++hns3_setup_linkstatus(struct rte_eth_dev *eth_dev, ++ struct rte_eth_link *new_link) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); ++ struct hns3_mac *mac = &hw->mac; + +- memset(&new_link, 0, sizeof(new_link)); + switch (mac->link_speed) { + case ETH_SPEED_NUM_10M: + case ETH_SPEED_NUM_100M: +@@ -2722,20 +2724,39 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, + case ETH_SPEED_NUM_50G: + case ETH_SPEED_NUM_100G: + case ETH_SPEED_NUM_200G: +- new_link.link_speed = mac->link_speed; ++ new_link->link_speed = mac->link_speed; + break; + default: + if (mac->link_status) +- new_link.link_speed = ETH_SPEED_NUM_UNKNOWN; ++ new_link->link_speed = ETH_SPEED_NUM_UNKNOWN; + else +- new_link.link_speed = ETH_SPEED_NUM_NONE; ++ new_link->link_speed = ETH_SPEED_NUM_NONE; + break; + } + +- new_link.link_duplex = mac->link_duplex; +- new_link.link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN; +- new_link.link_autoneg = ++ new_link->link_duplex = mac->link_duplex; ++ new_link->link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN; ++ new_link->link_autoneg = + !(eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED); ++} ++ ++static int ++hns3_dev_link_update(struct rte_eth_dev *eth_dev, ++ __rte_unused int wait_to_complete) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); ++ struct hns3_mac *mac = &hw->mac; ++ struct rte_eth_link new_link; ++ int ret; ++ ++ ret = hns3_update_port_link_info(eth_dev); ++ if (ret) { ++ mac->link_status = ETH_LINK_DOWN; ++ hns3_err(hw, "failed to get port link info, ret = %d.", ret); ++ } ++ ++ memset(&new_link, 0, sizeof(new_link)); ++ hns3_setup_linkstatus(eth_dev, &new_link); + + return rte_eth_linkstatus_set(eth_dev, &new_link); + } +-- +2.7.4 + diff --git a/0072-net-hns3-fix-long-task-queue-pairs-reset-time.patch b/0072-net-hns3-fix-long-task-queue-pairs-reset-time.patch new file mode 100644 index 0000000..4fb6c5a --- /dev/null +++ b/0072-net-hns3-fix-long-task-queue-pairs-reset-time.patch @@ -0,0 +1,211 @@ +From 081a3335ccdc6cce70ab9cde9e5df87e2dcd591f Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Tue, 23 Mar 2021 21:45:56 +0800 +Subject: [PATCH 072/189] net/hns3: fix long task queue pairs reset time + +Currently, the queue reset process needs to be performed one by one, +which is inefficient. However, the queues reset in the same function is +almost at the same stage. To optimize the queue reset process, a new +function has been added to the firmware command HNS3_OPC_CFG_RST_TRIGGER +to reset all queues in the same function at a time. And the related +queue reset MBX message is adjusted in the same way too. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.h | 8 ++- + drivers/net/hns3/hns3_rxtx.c | 125 ++++++++++++++++++++++++++++++++++++------- + 2 files changed, 114 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index e704d0c..30aca82 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -933,10 +933,16 @@ struct hns3_reset_tqp_queue_cmd { + + #define HNS3_CFG_RESET_MAC_B 3 + #define HNS3_CFG_RESET_FUNC_B 7 ++#define HNS3_CFG_RESET_RCB_B 1 + struct hns3_reset_cmd { + uint8_t mac_func_reset; + uint8_t fun_reset_vfid; +- uint8_t rsv[22]; ++ uint8_t fun_reset_rcb; ++ uint8_t rsv1; ++ uint16_t fun_reset_rcb_vqid_start; ++ uint16_t fun_reset_rcb_vqid_num; ++ uint8_t fun_reset_rcb_return_status; ++ uint8_t rsv2[15]; + }; + + #define HNS3_QUERY_DEV_SPECS_BD_NUM 4 +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 626f91f..0596c9c 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -629,10 +629,6 @@ hns3pf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) + uint64_t end; + int ret; + +- ret = hns3_tqp_enable(hw, queue_id, false); +- if (ret) +- return ret; +- + /* + * In current version VF is not supported when PF is driven by DPDK + * driver, all task queue pairs are mapped to PF function, so PF's queue +@@ -679,11 +675,6 @@ hns3vf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) + uint8_t msg_data[2]; + int ret; + +- /* Disable VF's queue before send queue reset msg to PF */ +- ret = hns3_tqp_enable(hw, queue_id, false); +- if (ret) +- return ret; +- + memcpy(msg_data, &queue_id, sizeof(uint16_t)); + + ret = hns3_send_mbx_msg(hw, HNS3_MBX_QUEUE_RESET, 0, msg_data, +@@ -695,14 +686,105 @@ hns3vf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) + } + + static int +-hns3_reset_tqp(struct hns3_adapter *hns, uint16_t queue_id) ++hns3_reset_rcb_cmd(struct hns3_hw *hw, uint8_t *reset_status) + { +- struct hns3_hw *hw = &hns->hw; ++ struct hns3_reset_cmd *req; ++ struct hns3_cmd_desc desc; ++ int ret; + +- if (hns->is_vf) +- return hns3vf_reset_tqp(hw, queue_id); +- else +- return hns3pf_reset_tqp(hw, queue_id); ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CFG_RST_TRIGGER, false); ++ req = (struct hns3_reset_cmd *)desc.data; ++ hns3_set_bit(req->mac_func_reset, HNS3_CFG_RESET_RCB_B, 1); ++ ++ /* ++ * The start qid should be the global qid of the first tqp of the ++ * function which should be reset in this port. Since our PF not ++ * support take over of VFs, so we only need to reset function 0, ++ * and its start qid is always 0. ++ */ ++ req->fun_reset_rcb_vqid_start = rte_cpu_to_le_16(0); ++ req->fun_reset_rcb_vqid_num = rte_cpu_to_le_16(hw->cfg_max_queues); ++ ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "fail to send rcb reset cmd, ret = %d.", ret); ++ return ret; ++ } ++ ++ *reset_status = req->fun_reset_rcb_return_status; ++ return 0; ++} ++ ++static int ++hns3pf_reset_all_tqps(struct hns3_hw *hw) ++{ ++#define HNS3_RESET_RCB_NOT_SUPPORT 0U ++#define HNS3_RESET_ALL_TQP_SUCCESS 1U ++ uint8_t reset_status; ++ int ret; ++ int i; ++ ++ ret = hns3_reset_rcb_cmd(hw, &reset_status); ++ if (ret) ++ return ret; ++ ++ /* ++ * If the firmware version is low, it may not support the rcb reset ++ * which means reset all the tqps at a time. In this case, we should ++ * reset tqps one by one. ++ */ ++ if (reset_status == HNS3_RESET_RCB_NOT_SUPPORT) { ++ for (i = 0; i < hw->cfg_max_queues; i++) { ++ ret = hns3pf_reset_tqp(hw, i); ++ if (ret) { ++ hns3_err(hw, ++ "fail to reset tqp, queue_id = %d, ret = %d.", ++ i, ret); ++ return ret; ++ } ++ } ++ } else if (reset_status != HNS3_RESET_ALL_TQP_SUCCESS) { ++ hns3_err(hw, "fail to reset all tqps, reset_status = %u.", ++ reset_status); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3vf_reset_all_tqps(struct hns3_hw *hw) ++{ ++#define HNS3VF_RESET_ALL_TQP_DONE 1U ++ uint8_t reset_status; ++ uint8_t msg_data[2]; ++ int ret; ++ int i; ++ ++ memset(msg_data, 0, sizeof(uint16_t)); ++ ret = hns3_send_mbx_msg(hw, HNS3_MBX_QUEUE_RESET, 0, msg_data, ++ sizeof(msg_data), true, &reset_status, ++ sizeof(reset_status)); ++ if (ret) { ++ hns3_err(hw, "fail to send rcb reset mbx, ret = %d.", ret); ++ return ret; ++ } ++ ++ if (reset_status == HNS3VF_RESET_ALL_TQP_DONE) ++ return 0; ++ ++ /* ++ * If the firmware version or kernel PF version is low, it may not ++ * support the rcb reset which means reset all the tqps at a time. ++ * In this case, we should reset tqps one by one. ++ */ ++ for (i = 1; i < hw->cfg_max_queues; i++) { ++ ret = hns3vf_reset_tqp(hw, i); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; + } + + int +@@ -711,14 +793,21 @@ hns3_reset_all_tqps(struct hns3_adapter *hns) + struct hns3_hw *hw = &hns->hw; + int ret, i; + ++ /* Disable all queues before reset all queues */ + for (i = 0; i < hw->cfg_max_queues; i++) { +- ret = hns3_reset_tqp(hns, i); ++ ret = hns3_tqp_enable(hw, i, false); + if (ret) { +- hns3_err(hw, "Failed to reset No.%d queue: %d", i, ret); ++ hns3_err(hw, ++ "fail to disable tqps before tqps reset, ret = %d.", ++ ret); + return ret; + } + } +- return 0; ++ ++ if (hns->is_vf) ++ return hns3vf_reset_all_tqps(hw); ++ else ++ return hns3pf_reset_all_tqps(hw); + } + + static int +-- +2.7.4 + diff --git a/0073-net-hns3-fix-MTU-config-complexity.patch b/0073-net-hns3-fix-MTU-config-complexity.patch new file mode 100644 index 0000000..de928dd --- /dev/null +++ b/0073-net-hns3-fix-MTU-config-complexity.patch @@ -0,0 +1,106 @@ +From 85c88060616e97d475df4b2321843a57218b80d9 Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 1 Apr 2021 21:38:03 +0800 +Subject: [PATCH 073/189] net/hns3: fix MTU config complexity + +This patch fixed cyclomatic complexity about MTU +in device configure process. + +Fixes: 1f5ca0b460cd ("net/hns3: support some device operations") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 62 ++++++++++++++++++++++++++---------------- + 1 file changed, 38 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 356c52a..ffdf019 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2373,6 +2373,41 @@ hns3_init_ring_with_vector(struct hns3_hw *hw) + } + + static int ++hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ uint32_t max_rx_pkt_len; ++ uint16_t mtu; ++ int ret; ++ ++ if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)) ++ return 0; ++ ++ /* ++ * If jumbo frames are enabled, MTU needs to be refreshed ++ * according to the maximum RX packet length. ++ */ ++ max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; ++ if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || ++ max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { ++ hns3_err(hw, "maximum Rx packet length must be greater than %u " ++ "and no more than %u when jumbo frame enabled.", ++ (uint16_t)HNS3_DEFAULT_FRAME_LEN, ++ (uint16_t)HNS3_MAX_FRAME_LEN); ++ return -EINVAL; ++ } ++ ++ mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); ++ ret = hns3_dev_mtu_set(dev, mtu); ++ if (ret) ++ return ret; ++ dev->data->mtu = mtu; ++ ++ return 0; ++} ++ ++static int + hns3_dev_configure(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; +@@ -2382,8 +2417,6 @@ hns3_dev_configure(struct rte_eth_dev *dev) + uint16_t nb_rx_q = dev->data->nb_rx_queues; + uint16_t nb_tx_q = dev->data->nb_tx_queues; + struct rte_eth_rss_conf rss_conf; +- uint32_t max_rx_pkt_len; +- uint16_t mtu; + bool gro_en; + int ret; + +@@ -2431,28 +2464,9 @@ hns3_dev_configure(struct rte_eth_dev *dev) + goto cfg_err; + } + +- /* +- * If jumbo frames are enabled, MTU needs to be refreshed +- * according to the maximum RX packet length. +- */ +- if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { +- max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; +- if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || +- max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { +- hns3_err(hw, "maximum Rx packet length must be greater " +- "than %u and less than %u when jumbo frame enabled.", +- (uint16_t)HNS3_DEFAULT_FRAME_LEN, +- (uint16_t)HNS3_MAX_FRAME_LEN); +- ret = -EINVAL; +- goto cfg_err; +- } +- +- mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); +- ret = hns3_dev_mtu_set(dev, mtu); +- if (ret) +- goto cfg_err; +- dev->data->mtu = mtu; +- } ++ ret = hns3_refresh_mtu(dev, conf); ++ if (ret) ++ goto cfg_err; + + ret = hns3_dev_configure_vlan(dev); + if (ret) +-- +2.7.4 + diff --git a/0074-net-hns3-support-IEEE-1588-PTP.patch b/0074-net-hns3-support-IEEE-1588-PTP.patch new file mode 100644 index 0000000..7e227f1 --- /dev/null +++ b/0074-net-hns3-support-IEEE-1588-PTP.patch @@ -0,0 +1,793 @@ +From 95a068d7af10549d1a084b94b86fbffd03c0e3bd Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 1 Apr 2021 21:38:04 +0800 +Subject: [PATCH 074/189] net/hns3: support IEEE 1588 PTP + +Add hns3 support for new ethdev APIs to enable and read IEEE1588/ +802.1AS PTP timestamps. + +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/features/hns3.ini | 2 + + doc/guides/nics/hns3.rst | 1 + + drivers/net/hns3/hns3_cmd.h | 30 ++++ + drivers/net/hns3/hns3_ethdev.c | 41 +++++- + drivers/net/hns3/hns3_ethdev.h | 20 +++ + drivers/net/hns3/hns3_ptp.c | 292 ++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_regs.h | 23 +++ + drivers/net/hns3/hns3_rxtx.c | 47 +++++- + drivers/net/hns3/hns3_rxtx.h | 7 + + drivers/net/hns3/hns3_rxtx_vec.c | 15 +- + drivers/net/hns3/meson.build | 3 +- + 11 files changed, 468 insertions(+), 13 deletions(-) + create mode 100644 drivers/net/hns3/hns3_ptp.c + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index d407b2f..cc1ad0f 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -42,6 +42,8 @@ Stats per queue = Y + FW version = Y + Registers dump = Y + Module EEPROM dump = Y ++Timesync = Y ++Timestamp offload = Y + Multiprocess aware = Y + Linux UIO = Y + Linux VFIO = Y +diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst +index e8abd07..d722509 100644 +--- a/doc/guides/nics/hns3.rst ++++ b/doc/guides/nics/hns3.rst +@@ -37,6 +37,7 @@ Features of the HNS3 PMD are: + - MTU update + - NUMA support + - Generic flow API ++- IEEE1588/802.1AS timestamping + + Prerequisites + ------------- +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 30aca82..5d1fb67 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -123,6 +123,10 @@ enum hns3_opcode_type { + HNS3_OPC_CLEAR_MAC_TNL_INT = 0x0312, + HNS3_OPC_CONFIG_FEC_MODE = 0x031A, + ++ /* PTP command */ ++ HNS3_OPC_PTP_INT_EN = 0x0501, ++ HNS3_OPC_CFG_PTP_MODE = 0x0507, ++ + /* PFC/Pause commands */ + HNS3_OPC_CFG_MAC_PAUSE_EN = 0x0701, + HNS3_OPC_CFG_PFC_PAUSE_EN = 0x0702, +@@ -976,6 +980,32 @@ struct hns3_query_ssu_cmd { + uint32_t rev1[2]; + }; + ++#define HNS3_PTP_ENABLE_B 0 ++#define HNS3_PTP_TX_ENABLE_B 1 ++#define HNS3_PTP_RX_ENABLE_B 2 ++ ++#define HNS3_PTP_TYPE_S 0 ++#define HNS3_PTP_TYPE_M (0x3 << HNS3_PTP_TYPE_S) ++ ++#define ALL_PTP_V2_TYPE 0xF ++#define HNS3_PTP_MESSAGE_TYPE_S 0 ++#define HNS3_PTP_MESSAGE_TYPE_M (0xF << HNS3_PTP_MESSAGE_TYPE_S) ++ ++#define PTP_TYPE_L2_V2_TYPE 0 ++ ++struct hns3_ptp_mode_cfg_cmd { ++ uint8_t enable; ++ uint8_t ptp_type; ++ uint8_t v2_message_type_1; ++ uint8_t v2_message_type_0; ++ uint8_t rsv[20]; ++}; ++ ++struct hns3_ptp_int_cmd { ++ uint8_t int_en; ++ uint8_t rsvd[23]; ++}; ++ + #define HNS3_MAX_TQP_NUM_HIP08_PF 64 + #define HNS3_DEFAULT_TX_BUF 0x4000 /* 16k bytes */ + #define HNS3_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index ffdf019..aef1ebf 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -58,6 +58,7 @@ enum hns3_evt_cause { + HNS3_VECTOR0_EVENT_RST, + HNS3_VECTOR0_EVENT_MBX, + HNS3_VECTOR0_EVENT_ERR, ++ HNS3_VECTOR0_EVENT_PTP, + HNS3_VECTOR0_EVENT_OTHER, + }; + +@@ -202,6 +203,13 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + goto out; + } + ++ /* Check for vector0 1588 event source */ ++ if (BIT(HNS3_VECTOR0_1588_INT_B) & vector0_int_stats) { ++ val = BIT(HNS3_VECTOR0_1588_INT_B); ++ ret = HNS3_VECTOR0_EVENT_PTP; ++ goto out; ++ } ++ + /* check for vector0 msix event source */ + if (vector0_int_stats & HNS3_VECTOR0_REG_MSIX_MASK || + hw_err_src_reg & HNS3_RAS_REG_NFE_MASK) { +@@ -227,10 +235,17 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + return ret; + } + ++static bool ++hns3_is_1588_event_type(uint32_t event_type) ++{ ++ return (event_type == HNS3_VECTOR0_EVENT_PTP); ++} ++ + static void + hns3_clear_event_cause(struct hns3_hw *hw, uint32_t event_type, uint32_t regclr) + { +- if (event_type == HNS3_VECTOR0_EVENT_RST) ++ if (event_type == HNS3_VECTOR0_EVENT_RST || ++ hns3_is_1588_event_type(event_type)) + hns3_write_dev(hw, HNS3_MISC_RESET_STS_REG, regclr); + else if (event_type == HNS3_VECTOR0_EVENT_MBX) + hns3_write_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG, regclr); +@@ -253,6 +268,8 @@ hns3_clear_all_event_cause(struct hns3_hw *hw) + BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) | + BIT(HNS3_VECTOR0_CORERESET_INT_B)); + hns3_clear_event_cause(hw, HNS3_VECTOR0_EVENT_MBX, 0); ++ hns3_clear_event_cause(hw, HNS3_VECTOR0_EVENT_PTP, ++ BIT(HNS3_VECTOR0_1588_INT_B)); + } + + static void +@@ -2468,6 +2485,10 @@ hns3_dev_configure(struct rte_eth_dev *dev) + if (ret) + goto cfg_err; + ++ ret = hns3_mbuf_dyn_rx_timestamp_register(dev, conf); ++ if (ret) ++ goto cfg_err; ++ + ret = hns3_dev_configure_vlan(dev); + if (ret) + goto cfg_err; +@@ -2641,6 +2662,9 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + ++ if (hns3_dev_ptp_supported(hw)) ++ info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP; ++ + info->rx_desc_lim = (struct rte_eth_desc_lim) { + .nb_max = HNS3_MAX_RING_DESC, + .nb_min = HNS3_MIN_RING_DESC, +@@ -4960,6 +4984,10 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + goto err_intr_callback_register; + } + ++ ret = hns3_ptp_init(hw); ++ if (ret) ++ goto err_get_config; ++ + /* Enable interrupt */ + rte_intr_enable(&pci_dev->intr_handle); + hns3_pf_enable_irq0(hw); +@@ -5977,6 +6005,10 @@ hns3_restore_conf(struct hns3_adapter *hns) + if (ret) + goto err_promisc; + ++ ret = hns3_restore_ptp(hns); ++ if (ret) ++ goto err_promisc; ++ + ret = hns3_restore_rx_interrupt(hw); + if (ret) + goto err_promisc; +@@ -6681,6 +6713,13 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { + .fec_set = hns3_fec_set, + .tm_ops_get = hns3_tm_ops_get, + .tx_done_cleanup = hns3_tx_done_cleanup, ++ .timesync_enable = hns3_timesync_enable, ++ .timesync_disable = hns3_timesync_disable, ++ .timesync_read_rx_timestamp = hns3_timesync_read_rx_timestamp, ++ .timesync_read_tx_timestamp = hns3_timesync_read_tx_timestamp, ++ .timesync_adjust_time = hns3_timesync_adjust_time, ++ .timesync_read_time = hns3_timesync_read_time, ++ .timesync_write_time = hns3_timesync_write_time, + }; + + static const struct hns3_reset_ops hns3_reset_ops = { +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index eb2203c..25cb5e2 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -750,6 +750,11 @@ struct hns3_pf { + bool support_sfp_query; + uint32_t fec_mode; /* current FEC mode for ethdev */ + ++ bool ptp_enable; ++ ++ /* Stores timestamp of last received packet on dev */ ++ uint64_t rx_timestamp; ++ + struct hns3_vtag_cfg vtag_config; + LIST_HEAD(vlan_tbl, hns3_user_vlan_table) vlan_list; + +@@ -1000,6 +1005,21 @@ int hns3_dev_infos_get(struct rte_eth_dev *eth_dev, + void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status, + uint32_t link_speed, uint8_t link_duplex); + void hns3_parse_devargs(struct rte_eth_dev *dev); ++int hns3_restore_ptp(struct hns3_adapter *hns); ++int hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev, ++ struct rte_eth_conf *conf); ++int hns3_ptp_init(struct hns3_hw *hw); ++int hns3_timesync_enable(struct rte_eth_dev *dev); ++int hns3_timesync_disable(struct rte_eth_dev *dev); ++int hns3_timesync_read_rx_timestamp(struct rte_eth_dev *dev, ++ struct timespec *timestamp, ++ uint32_t flags __rte_unused); ++int hns3_timesync_read_tx_timestamp(struct rte_eth_dev *dev, ++ struct timespec *timestamp); ++int hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts); ++int hns3_timesync_write_time(struct rte_eth_dev *dev, ++ const struct timespec *ts); ++int hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta); + + static inline bool + is_reset_pending(struct hns3_adapter *hns) +diff --git a/drivers/net/hns3/hns3_ptp.c b/drivers/net/hns3/hns3_ptp.c +new file mode 100644 +index 0000000..146b69d +--- /dev/null ++++ b/drivers/net/hns3/hns3_ptp.c +@@ -0,0 +1,292 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2021-2021 Hisilicon Limited. ++ */ ++ ++#include ++#include ++#include ++ ++#include "hns3_ethdev.h" ++#include "hns3_regs.h" ++#include "hns3_logs.h" ++ ++uint64_t hns3_timestamp_rx_dynflag; ++int hns3_timestamp_dynfield_offset = -1; ++ ++int ++hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev, ++ struct rte_eth_conf *conf) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ int ret; ++ ++ if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_TIMESTAMP)) ++ return 0; ++ ++ ret = rte_mbuf_dyn_rx_timestamp_register ++ (&hns3_timestamp_dynfield_offset, ++ &hns3_timestamp_rx_dynflag); ++ if (ret) { ++ hns3_err(hw, ++ "failed to register Rx timestamp field/flag"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_ptp_int_en(struct hns3_hw *hw, bool en) ++{ ++ struct hns3_ptp_int_cmd *req; ++ struct hns3_cmd_desc desc; ++ int ret; ++ ++ req = (struct hns3_ptp_int_cmd *)desc.data; ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_PTP_INT_EN, false); ++ req->int_en = en ? 1 : 0; ++ ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) ++ hns3_err(hw, ++ "failed to %s ptp interrupt, ret = %d\n", ++ en ? "enable" : "disable", ret); ++ ++ return ret; ++} ++ ++int ++hns3_ptp_init(struct hns3_hw *hw) ++{ ++ int ret; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return 0; ++ ++ ret = hns3_ptp_int_en(hw, true); ++ if (ret) ++ return ret; ++ ++ /* Start PTP timer */ ++ hns3_write_dev(hw, HNS3_CFG_TIME_CYC_EN, 1); ++ ++ return 0; ++} ++ ++static int ++hns3_timesync_configure(struct hns3_adapter *hns, bool en) ++{ ++ struct hns3_ptp_mode_cfg_cmd *req; ++ struct hns3_hw *hw = &hns->hw; ++ struct hns3_pf *pf = &hns->pf; ++ struct hns3_cmd_desc desc; ++ int val; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CFG_PTP_MODE, false); ++ ++ req = (struct hns3_ptp_mode_cfg_cmd *)desc.data; ++ ++ val = en ? 1 : 0; ++ hns3_set_bit(req->enable, HNS3_PTP_ENABLE_B, val); ++ hns3_set_bit(req->enable, HNS3_PTP_TX_ENABLE_B, val); ++ hns3_set_bit(req->enable, HNS3_PTP_RX_ENABLE_B, val); ++ ++ if (en) { ++ hns3_set_field(req->ptp_type, HNS3_PTP_TYPE_M, HNS3_PTP_TYPE_S, ++ PTP_TYPE_L2_V2_TYPE); ++ hns3_set_field(req->v2_message_type_1, HNS3_PTP_MESSAGE_TYPE_M, ++ HNS3_PTP_MESSAGE_TYPE_S, ALL_PTP_V2_TYPE); ++ } ++ ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "configure PTP time failed, en = %d, ret = %d", ++ en, ret); ++ return ret; ++ } ++ ++ pf->ptp_enable = en; ++ ++ return 0; ++} ++ ++int ++hns3_timesync_enable(struct rte_eth_dev *dev) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ struct hns3_pf *pf = &hns->pf; ++ int ret; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ if (pf->ptp_enable) ++ return 0; ++ ++ rte_spinlock_lock(&hw->lock); ++ ret = hns3_timesync_configure(hns, true); ++ rte_spinlock_unlock(&hw->lock); ++ return ret; ++} ++ ++int ++hns3_timesync_disable(struct rte_eth_dev *dev) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ struct hns3_pf *pf = &hns->pf; ++ int ret; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ if (!pf->ptp_enable) ++ return 0; ++ ++ rte_spinlock_lock(&hw->lock); ++ ret = hns3_timesync_configure(hns, false); ++ rte_spinlock_unlock(&hw->lock); ++ ++ return ret; ++} ++ ++int ++hns3_timesync_read_rx_timestamp(struct rte_eth_dev *dev, ++ struct timespec *timestamp, ++ uint32_t flags __rte_unused) ++{ ++#define TIME_RX_STAMP_NS_MASK 0x3FFFFFFF ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ struct hns3_pf *pf = &hns->pf; ++ uint64_t ns, sec; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ ns = pf->rx_timestamp & TIME_RX_STAMP_NS_MASK; ++ sec = upper_32_bits(pf->rx_timestamp); ++ ++ ns += sec * NSEC_PER_SEC; ++ *timestamp = rte_ns_to_timespec(ns); ++ ++ return 0; ++} ++ ++int ++hns3_timesync_read_tx_timestamp(struct rte_eth_dev *dev, ++ struct timespec *timestamp) ++{ ++#define TIME_TX_STAMP_NS_MASK 0x3FFFFFFF ++#define TIME_TX_STAMP_VALID 24 ++#define TIME_TX_STAMP_CNT_MASK 0x7 ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ uint64_t sec; ++ uint64_t tmp; ++ uint64_t ns; ++ int ts_cnt; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ ts_cnt = hns3_read_dev(hw, HNS3_TX_1588_BACK_TSP_CNT) & ++ TIME_TX_STAMP_CNT_MASK; ++ if (ts_cnt == 0) ++ return -EINVAL; ++ ++ ns = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_0) & TIME_TX_STAMP_NS_MASK; ++ sec = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_1); ++ tmp = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_2) & 0xFFFF; ++ sec = (tmp << 32) | sec; ++ ++ ns += sec * NSEC_PER_SEC; ++ ++ *timestamp = rte_ns_to_timespec(ns); ++ ++ /* Clear current timestamp hardware stores */ ++ hns3_read_dev(hw, HNS3_TX_1588_SEQID_BACK); ++ ++ return 0; ++} ++ ++int ++hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ uint64_t ns, sec; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ sec = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_L); ++ sec |= (uint64_t)(hns3_read_dev(hw, HNS3_CURR_TIME_OUT_H) & 0xFFFF) ++ << 32; ++ ++ ns = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_NS); ++ ns += sec * NSEC_PER_SEC; ++ *ts = rte_ns_to_timespec(ns); ++ ++ return 0; ++} ++ ++int ++hns3_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ uint64_t sec = ts->tv_sec; ++ uint64_t ns = ts->tv_nsec; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ /* Set the timecounters to a new value. */ ++ hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_H, upper_32_bits(sec)); ++ hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_M, lower_32_bits(sec)); ++ hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_L, lower_32_bits(ns)); ++ hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_RDY, 1); ++ ++ return 0; ++} ++ ++int ++hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) ++{ ++#define TIME_SYNC_L_MASK 0x7FFFFFFF ++#define SYMBOL_BIT_OFFSET 31 ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct timespec cur_time; ++ uint64_t ns; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ ++ (void)hns3_timesync_read_time(dev, &cur_time); ++ ns = rte_timespec_to_ns((const struct timespec *)&cur_time); ++ cur_time = rte_ns_to_timespec(ns + delta); ++ (void)hns3_timesync_write_time(dev, (const struct timespec *)&cur_time); ++ ++ return 0; ++} ++ ++int ++hns3_restore_ptp(struct hns3_adapter *hns) ++{ ++ struct hns3_pf *pf = &hns->pf; ++ struct hns3_hw *hw = &hns->hw; ++ bool en = pf->ptp_enable; ++ int ret; ++ ++ if (!hns3_dev_ptp_supported(hw)) ++ return 0; ++ ++ ret = hns3_timesync_configure(hns, en); ++ if (ret) ++ hns3_err(hw, "restore PTP enable state(%d) failed, ret = %d", ++ en, ret); ++ ++ return ret; ++} +diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h +index e141fe1..c9e10be 100644 +--- a/drivers/net/hns3/hns3_regs.h ++++ b/drivers/net/hns3/hns3_regs.h +@@ -121,6 +121,29 @@ + #define HNS3_TQP_INTR_RL_DEFAULT 0 + #define HNS3_TQP_INTR_QL_DEFAULT 0 + ++/* Register bit for 1588 event */ ++#define HNS3_VECTOR0_1588_INT_B 0 ++ ++#define HNS3_PTP_BASE_ADDRESS 0x29000 ++ ++#define HNS3_TX_1588_SEQID_BACK (HNS3_PTP_BASE_ADDRESS + 0x0) ++#define HNS3_TX_1588_TSP_BACK_0 (HNS3_PTP_BASE_ADDRESS + 0x4) ++#define HNS3_TX_1588_TSP_BACK_1 (HNS3_PTP_BASE_ADDRESS + 0x8) ++#define HNS3_TX_1588_TSP_BACK_2 (HNS3_PTP_BASE_ADDRESS + 0xc) ++ ++#define HNS3_TX_1588_BACK_TSP_CNT (HNS3_PTP_BASE_ADDRESS + 0x30) ++ ++#define HNS3_CFG_TIME_SYNC_H (HNS3_PTP_BASE_ADDRESS + 0x50) ++#define HNS3_CFG_TIME_SYNC_M (HNS3_PTP_BASE_ADDRESS + 0x54) ++#define HNS3_CFG_TIME_SYNC_L (HNS3_PTP_BASE_ADDRESS + 0x58) ++#define HNS3_CFG_TIME_SYNC_RDY (HNS3_PTP_BASE_ADDRESS + 0x5c) ++ ++#define HNS3_CFG_TIME_CYC_EN (HNS3_PTP_BASE_ADDRESS + 0x70) ++ ++#define HNS3_CURR_TIME_OUT_H (HNS3_PTP_BASE_ADDRESS + 0x74) ++#define HNS3_CURR_TIME_OUT_L (HNS3_PTP_BASE_ADDRESS + 0x78) ++#define HNS3_CURR_TIME_OUT_NS (HNS3_PTP_BASE_ADDRESS + 0x7c) ++ + /* gl_usec convert to hardware count, as writing each 1 represents 2us */ + #define HNS3_GL_USEC_TO_REG(gl_usec) ((gl_usec) >> 1) + /* rl_usec convert to hardware count, as writing each 1 represents 4us */ +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 0596c9c..c41cccb 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2365,6 +2365,23 @@ hns3_rx_alloc_buffer(struct hns3_rx_queue *rxq) + return rte_mbuf_raw_alloc(rxq->mb_pool); + } + ++static inline void ++hns3_rx_ptp_timestamp_handle(struct hns3_rx_queue *rxq, struct rte_mbuf *mbuf, ++ volatile struct hns3_desc *rxd) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(rxq->hns); ++ uint64_t timestamp = rte_le_to_cpu_64(rxd->timestamp); ++ ++ mbuf->ol_flags |= PKT_RX_IEEE1588_PTP | PKT_RX_IEEE1588_TMST; ++ if (hns3_timestamp_rx_dynflag > 0) { ++ *RTE_MBUF_DYNFIELD(mbuf, hns3_timestamp_dynfield_offset, ++ rte_mbuf_timestamp_t *) = timestamp; ++ mbuf->ol_flags |= hns3_timestamp_rx_dynflag; ++ } ++ ++ pf->rx_timestamp = timestamp; ++} ++ + uint16_t + hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + { +@@ -2424,8 +2441,12 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + } + + rxm = rxe->mbuf; ++ rxm->ol_flags = 0; + rxe->mbuf = nmb; + ++ if (unlikely(bd_base_info & BIT(HNS3_RXD_TS_VLD_B))) ++ hns3_rx_ptp_timestamp_handle(rxq, rxm, rxdp); ++ + dma_addr = rte_mbuf_data_iova_default(nmb); + rxdp->addr = rte_cpu_to_le_64(dma_addr); + rxdp->rx.bd_base_info = 0; +@@ -2436,7 +2457,7 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + rxm->data_len = rxm->pkt_len; + rxm->port = rxq->port_id; + rxm->hash.rss = rte_le_to_cpu_32(rxd.rx.rss_hash); +- rxm->ol_flags = PKT_RX_RSS_HASH; ++ rxm->ol_flags |= PKT_RX_RSS_HASH; + if (unlikely(bd_base_info & BIT(HNS3_RXD_LUM_B))) { + rxm->hash.fdir.hi = + rte_le_to_cpu_16(rxd.rx.fd_id); +@@ -2455,6 +2476,9 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + + rxm->packet_type = hns3_rx_calc_ptype(rxq, l234_info, ol_info); + ++ if (rxm->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) ++ rxm->ol_flags |= PKT_RX_IEEE1588_PTP; ++ + if (likely(bd_base_info & BIT(HNS3_RXD_L3L4P_B))) + hns3_rx_set_cksum_flag(rxm, rxm->packet_type, + cksum_err); +@@ -3043,7 +3067,7 @@ 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)); ++ desc->tx.tp_fe_sc_vld_ra_ri |= rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B)); + } + + static void +@@ -3091,6 +3115,10 @@ hns3_fill_first_desc(struct hns3_tx_queue *txq, struct hns3_desc *desc, + rte_cpu_to_le_32(BIT(HNS3_TXD_VLAN_B)); + desc->tx.vlan_tag = rte_cpu_to_le_16(rxm->vlan_tci); + } ++ ++ if (ol_flags & PKT_TX_IEEE1588_TMST) ++ desc->tx.tp_fe_sc_vld_ra_ri |= ++ rte_cpu_to_le_16(BIT(HNS3_TXD_TSYN_B)); + } + + static inline int +@@ -4149,10 +4177,21 @@ hns3_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, + return 0; + } + ++static bool ++hns3_tx_check_simple_support(struct rte_eth_dev *dev) ++{ ++ uint64_t offloads = dev->data->dev_conf.txmode.offloads; ++ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ if (hns3_dev_ptp_supported(hw)) ++ return false; ++ ++ return (offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE)); ++} ++ + static eth_tx_burst_t + hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + { +- uint64_t offloads = dev->data->dev_conf.txmode.offloads; + struct hns3_adapter *hns = dev->data->dev_private; + bool vec_allowed, sve_allowed, simple_allowed; + +@@ -4160,7 +4199,7 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + hns3_tx_check_vec_support(dev) == 0; + sve_allowed = vec_allowed && hns3_check_sve_support(); + simple_allowed = hns->tx_simple_allowed && +- offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE); ++ hns3_tx_check_simple_support(dev); + + *prep = NULL; + +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 6689397..eebbebf 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -106,6 +106,8 @@ + #define HNS3_RXD_L3L4P_B 11 + #define HNS3_RXD_TSIND_S 12 + #define HNS3_RXD_TSIND_M (0x7 << HNS3_RXD_TSIND_S) ++ ++#define HNS3_RXD_TS_VLD_B 14 + #define HNS3_RXD_LKBK_B 15 + #define HNS3_RXD_GRO_SIZE_S 16 + #define HNS3_RXD_GRO_SIZE_M (0x3fff << HNS3_RXD_GRO_SIZE_S) +@@ -200,6 +202,8 @@ enum hns3_pkt_tun_type { + struct hns3_desc { + union { + uint64_t addr; ++ uint64_t timestamp; ++ + struct { + uint32_t addr0; + uint32_t addr1; +@@ -534,6 +538,9 @@ enum hns3_cksum_status { + HNS3_OUTER_L4_CKSUM_ERR = 8 + }; + ++extern uint64_t hns3_timestamp_rx_dynflag; ++extern int hns3_timestamp_dynfield_offset; ++ + static inline int + hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm, + uint32_t bd_base_info, uint32_t l234_info, +diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c +index a26c83d..fd7b272 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.c ++++ b/drivers/net/hns3/hns3_rxtx_vec.c +@@ -18,6 +18,10 @@ hns3_tx_check_vec_support(struct rte_eth_dev *dev) + { + struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode; + ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ if (hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ + /* Only support DEV_TX_OFFLOAD_MBUF_FAST_FREE */ + if (txmode->offloads != DEV_TX_OFFLOAD_MBUF_FAST_FREE) + return -ENOTSUP; +@@ -167,7 +171,6 @@ hns3_rxq_vec_setup(struct hns3_rx_queue *rxq) + memset(rxq->offset_table, 0, sizeof(rxq->offset_table)); + } + +-#ifndef RTE_LIBRTE_IEEE1588 + static int + hns3_rxq_vec_check(struct hns3_rx_queue *rxq, void *arg) + { +@@ -183,17 +186,19 @@ hns3_rxq_vec_check(struct hns3_rx_queue *rxq, void *arg) + RTE_SET_USED(arg); + return 0; + } +-#endif + + int + hns3_rx_check_vec_support(struct rte_eth_dev *dev) + { +-#ifndef RTE_LIBRTE_IEEE1588 + struct rte_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf; + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + uint64_t offloads_mask = DEV_RX_OFFLOAD_TCP_LRO | + DEV_RX_OFFLOAD_VLAN; + ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ if (hns3_dev_ptp_supported(hw)) ++ return -ENOTSUP; ++ + if (dev->data->scattered_rx) + return -ENOTSUP; + +@@ -207,8 +212,4 @@ hns3_rx_check_vec_support(struct rte_eth_dev *dev) + return -ENOTSUP; + + return 0; +-#else +- RTE_SET_USED(dev); +- return -ENOTSUP; +-#endif + } +diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build +index f6aac69..6d78c33 100644 +--- a/drivers/net/hns3/meson.build ++++ b/drivers/net/hns3/meson.build +@@ -26,7 +26,8 @@ sources = files('hns3_cmd.c', + 'hns3_rxtx.c', + 'hns3_stats.c', + 'hns3_mp.c', +- 'hns3_tm.c') ++ 'hns3_tm.c', ++ 'hns3_ptp.c') + + deps += ['hash'] + +-- +2.7.4 + diff --git a/0075-ethdev-validate-input-in-register-info.patch b/0075-ethdev-validate-input-in-register-info.patch new file mode 100644 index 0000000..98edcae --- /dev/null +++ b/0075-ethdev-validate-input-in-register-info.patch @@ -0,0 +1,64 @@ +From 94240428064fc641a78c2189329094acb4059eb8 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Fri, 2 Apr 2021 10:58:49 +0800 +Subject: [PATCH 075/189] ethdev: validate input in register info + +This patch adds validity check of input pointer in regs dump API. + +Fixes: 7a3f27cbf59b ("ethdev: add access to specific device info") +Fixes: 936eda25e8da ("net/hns3: support dump register") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +Reviewed-by: Ferruh Yigit +--- + drivers/net/hns3/hns3_regs.c | 5 ----- + lib/librte_ethdev/rte_ethdev.c | 2 ++ + lib/librte_ethdev/rte_ethdev.h | 1 + + 3 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 5b14727..93055a4 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -484,11 +484,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + uint32_t *data; + int ret; + +- if (regs == NULL) { +- hns3_err(hw, "the input parameter regs is NULL!"); +- return -EINVAL; +- } +- + ret = hns3_get_regs_length(hw, &length); + if (ret) + return ret; +diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c +index 17ddacc..f311868 100644 +--- a/lib/librte_ethdev/rte_ethdev.c ++++ b/lib/librte_ethdev/rte_ethdev.c +@@ -5239,6 +5239,8 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); ++ if (info == NULL) ++ return -EINVAL; + + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP); +diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h +index f5f8919..e89fc50 100644 +--- a/lib/librte_ethdev/rte_ethdev.h ++++ b/lib/librte_ethdev/rte_ethdev.h +@@ -4395,6 +4395,7 @@ int rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info); + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. ++ * - (-EINVAL) if bad parameter. + * - (-ENODEV) if *port_id* invalid. + * - (-EIO) if device is removed. + * - others depends on the specific operations implementation. +-- +2.7.4 + diff --git a/0076-net-hns3-support-wait-in-link-update.patch b/0076-net-hns3-support-wait-in-link-update.patch new file mode 100644 index 0000000..91ec8ba --- /dev/null +++ b/0076-net-hns3-support-wait-in-link-update.patch @@ -0,0 +1,64 @@ +From ee9d7f7372170853e7538256c5e764bf154f3132 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 30 Mar 2021 20:53:25 +0800 +Subject: [PATCH 076/189] net/hns3: support wait in link update + +There are two APIs in ethdev layer to get link status of device, namely, +"rte_eth_link_get" and "rte_eth_link_get_nowait". When the device link +is unstable or auto-negotiation is in progress, the first API supports +the function of waiting for the NIC to link up, and the maximum waiting +time is 9 seconds based on DPDK Documentation. For the hns3 PMD driver, +the link can be established within 2 seconds. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index aef1ebf..05f199e 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2779,19 +2779,31 @@ hns3_setup_linkstatus(struct rte_eth_dev *eth_dev, + } + + static int +-hns3_dev_link_update(struct rte_eth_dev *eth_dev, +- __rte_unused int wait_to_complete) ++hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) + { ++#define HNS3_LINK_CHECK_INTERVAL 100 /* 100ms */ ++#define HNS3_MAX_LINK_CHECK_TIMES 20 /* 2s (100 * 20ms) in total */ ++ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); ++ uint32_t retry_cnt = HNS3_MAX_LINK_CHECK_TIMES; + struct hns3_mac *mac = &hw->mac; + struct rte_eth_link new_link; + int ret; + +- ret = hns3_update_port_link_info(eth_dev); +- if (ret) { +- mac->link_status = ETH_LINK_DOWN; +- hns3_err(hw, "failed to get port link info, ret = %d.", ret); +- } ++ do { ++ ret = hns3_update_port_link_info(eth_dev); ++ if (ret) { ++ mac->link_status = ETH_LINK_DOWN; ++ hns3_err(hw, "failed to get port link info, ret = %d.", ++ ret); ++ break; ++ } ++ ++ if (!wait_to_complete || mac->link_status == ETH_LINK_UP) ++ break; ++ ++ rte_delay_ms(HNS3_LINK_CHECK_INTERVAL); ++ } while (retry_cnt--); + + memset(&new_link, 0, sizeof(new_link)); + hns3_setup_linkstatus(eth_dev, &new_link); +-- +2.7.4 + diff --git a/0077-net-hns3-fix-some-function-names-for-copper-media-ty.patch b/0077-net-hns3-fix-some-function-names-for-copper-media-ty.patch new file mode 100644 index 0000000..d1e58a2 --- /dev/null +++ b/0077-net-hns3-fix-some-function-names-for-copper-media-ty.patch @@ -0,0 +1,76 @@ +From 45da720c44c7a7758cc811bea609116088168f25 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 31 Mar 2021 18:01:35 +0800 +Subject: [PATCH 077/189] net/hns3: fix some function names for copper media + type + +PHY is a common concept for the copper and optical media type interface. +There are some inappropriate function names for copper ports, which +needs to be adjusted. + +Fixes: 2e4859f3b362 ("net/hns3: support PF device with copper PHYs") + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 05f199e..4dff016 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4597,7 +4597,7 @@ hns3_update_fiber_link_info(struct hns3_hw *hw) + } + + static void +-hns3_parse_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac) ++hns3_parse_copper_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac) + { + struct hns3_phy_params_bd0_cmd *req; + +@@ -4615,7 +4615,7 @@ hns3_parse_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac) + } + + static int +-hns3_get_phy_params(struct hns3_hw *hw, struct hns3_mac *mac) ++hns3_get_copper_phy_params(struct hns3_hw *hw, struct hns3_mac *mac) + { + struct hns3_cmd_desc desc[HNS3_PHY_PARAM_CFG_BD_NUM]; + uint16_t i; +@@ -4634,20 +4634,20 @@ hns3_get_phy_params(struct hns3_hw *hw, struct hns3_mac *mac) + return ret; + } + +- hns3_parse_phy_params(desc, mac); ++ hns3_parse_copper_phy_params(desc, mac); + + return 0; + } + + static int +-hns3_update_phy_link_info(struct hns3_hw *hw) ++hns3_update_copper_link_info(struct hns3_hw *hw) + { + struct hns3_mac *mac = &hw->mac; + struct hns3_mac mac_info; + int ret; + + memset(&mac_info, 0, sizeof(struct hns3_mac)); +- ret = hns3_get_phy_params(hw, &mac_info); ++ ret = hns3_get_copper_phy_params(hw, &mac_info); + if (ret) + return ret; + +@@ -4676,7 +4676,7 @@ hns3_update_link_info(struct rte_eth_dev *eth_dev) + int ret = 0; + + if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) +- ret = hns3_update_phy_link_info(hw); ++ ret = hns3_update_copper_link_info(hw); + else if (hw->mac.media_type == HNS3_MEDIA_TYPE_FIBER) + ret = hns3_update_fiber_link_info(hw); + +-- +2.7.4 + diff --git a/0078-net-hns3-fix-setting-default-MAC-address-in-bonding-.patch b/0078-net-hns3-fix-setting-default-MAC-address-in-bonding-.patch new file mode 100644 index 0000000..6d5ee19 --- /dev/null +++ b/0078-net-hns3-fix-setting-default-MAC-address-in-bonding-.patch @@ -0,0 +1,187 @@ +From 3429fe6859a5524353d748e4011f4610aeea781c Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 31 Mar 2021 18:01:36 +0800 +Subject: [PATCH 078/189] net/hns3: fix setting default MAC address in bonding + of VF + +When start testpmd with two hns3 VFs(0000:bd:01.0, 0000:bd:01.7), and +then execute the following commands: + testpmd> create bonded device 1 0 + testpmd> set bonding mac_addr 2 3c:12:34:56:78:9a + testpmd> add bonding slave 0 2 + testpmd> add bonding slave 1 2 + testpmd> set portmask 0x4 + testpmd> port start 2 + +It will occurs the following error in a low probability: + 0000:bd:01.0 hns3_get_mbx_resp(): VF could not get mbx(3,0) + head(16) tail(15) lost(1) from PF in_irq:0 + 0000:bd:01.0 hns3vf_set_default_mac_addr(): Failed to set mac + addr(3C:**:**:**:78:9A) for vf: -62 + mac_address_slaves_update(1541) - Failed to update port Id 0 + MAC address + +The problem replay: +1. The 'port start 2' command will start slave ports and then set slave + mac address, the function call flow: bond_ethdev_start -> + mac_address_slaves_update. +2. There are also a monitor task which running in intr thread will check + slave ports link status and update slave ports mac address, the + function call flow: bond_ethdev_slave_link_status_change_monitor -> + bond_ethdev_lsc_event_callback -> mac_address_slaves_update. +3. Because the above step1&2 running on different threads, they may both + call drivers ops mac_addr_set which is hns3vf_set_default_mac_addr. +4. hns3vf_set_default_mac_addr will first acquire hw.lock and then send + mailbox to PF and wait PF's response message. Note: the PF's + response is an independent message which will received in hw.cmq.crq, + the receiving operation can only performed in intr thread. +5. So if the step1 operation hold the hw.lock and try get response + message, and step2 operation try acquire the hw.lock and so it can't + process the response message, this will lead to step1 fail. + +The solution: +1. make all threads could process the mailbox response message, which + protected by the hw.cmq.crq.lock. +2. use the following rules to avoid deadlock: +2.1. ensure use the correct locking sequence: hw.lock > + hw.mbx_resp.lock > hw.cmq.crq.lock. +2.2. make sure don't acquire such as hw.lock & hw.mbx_resp.lock again + when process mailbox response message. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 1 - + drivers/net/hns3/hns3_ethdev_vf.c | 3 --- + drivers/net/hns3/hns3_mbx.c | 51 +++++++++++---------------------------- + 3 files changed, 14 insertions(+), 41 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 25cb5e2..fc0dc37 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -439,7 +439,6 @@ struct hns3_hw { + struct hns3_cmq cmq; + struct hns3_mbx_resp_status mbx_resp; /* mailbox response */ + struct hns3_mbx_arq_ring arq; /* mailbox async rx queue */ +- pthread_t irq_thread_id; + struct hns3_mac mac; + unsigned int secondary_cnt; /* Number of secondary processes init'd. */ + struct hns3_tqp_stats tqp_stats; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 26f0698..22281c8 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1109,9 +1109,6 @@ hns3vf_interrupt_handler(void *param) + enum hns3vf_evt_cause event_cause; + uint32_t clearval; + +- if (hw->irq_thread_id == 0) +- hw->irq_thread_id = pthread_self(); +- + /* Disable interrupt */ + hns3vf_disable_irq0(hw); + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index e745843..b9190a1 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -40,36 +40,14 @@ hns3_resp_to_errno(uint16_t resp_code) + return -EIO; + } + +-static void +-hns3_poll_all_sync_msg(void) +-{ +- struct rte_eth_dev *eth_dev; +- struct hns3_adapter *adapter; +- const char *name; +- uint16_t port_id; +- +- RTE_ETH_FOREACH_DEV(port_id) { +- eth_dev = &rte_eth_devices[port_id]; +- name = eth_dev->device->driver->name; +- if (strcmp(name, "net_hns3") && strcmp(name, "net_hns3_vf")) +- continue; +- adapter = eth_dev->data->dev_private; +- if (!adapter || adapter->hw.adapter_state == HNS3_NIC_CLOSED) +- continue; +- /* Synchronous msg, the mbx_resp.req_msg_data is non-zero */ +- if (adapter->hw.mbx_resp.req_msg_data) +- hns3_dev_handle_mbx_msg(&adapter->hw); +- } +-} +- + static int + hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, + uint8_t *resp_data, uint16_t resp_len) + { + #define HNS3_MAX_RETRY_MS 500 ++#define HNS3_WAIT_RESP_US 100 + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_mbx_resp_status *mbx_resp; +- bool in_irq = false; + uint64_t now; + uint64_t end; + +@@ -96,26 +74,19 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, + return -EIO; + } + +- /* +- * The mbox response is running on the interrupt thread. +- * Sending mbox in the interrupt thread cannot wait for the +- * response, so polling the mbox response on the irq thread. +- */ +- if (pthread_equal(hw->irq_thread_id, pthread_self())) { +- in_irq = true; +- hns3_poll_all_sync_msg(); +- } else { +- rte_delay_ms(HNS3_POLL_RESPONE_MS); +- } ++ hns3_dev_handle_mbx_msg(hw); ++ rte_delay_us(HNS3_WAIT_RESP_US); ++ + now = get_timeofday_ms(); + } + hw->mbx_resp.req_msg_data = 0; + if (now >= end) { + hw->mbx_resp.lost++; + hns3_err(hw, +- "VF could not get mbx(%u,%u) head(%u) tail(%u) lost(%u) from PF in_irq:%d", ++ "VF could not get mbx(%u,%u) head(%u) tail(%u) " ++ "lost(%u) from PF", + code0, code1, hw->mbx_resp.head, hw->mbx_resp.tail, +- hw->mbx_resp.lost, in_irq); ++ hw->mbx_resp.lost); + return -ETIME; + } + rte_io_rmb(); +@@ -368,9 +339,13 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + uint8_t *temp; + int i; + ++ rte_spinlock_lock(&hw->cmq.crq.lock); ++ + while (!hns3_cmd_crq_empty(hw)) { +- if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) ++ if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) { ++ rte_spinlock_unlock(&hw->cmq.crq.lock); + return; ++ } + + desc = &crq->desc[crq->next_to_use]; + req = (struct hns3_mbx_pf_to_vf_cmd *)desc->data; +@@ -441,4 +416,6 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + + /* Write back CMDQ_RQ header pointer, IMP need this pointer */ + hns3_write_dev(hw, HNS3_CMDQ_RX_HEAD_REG, crq->next_to_use); ++ ++ rte_spinlock_unlock(&hw->cmq.crq.lock); + } +-- +2.7.4 + diff --git a/0079-net-hns3-fix-FLR-miss-detection.patch b/0079-net-hns3-fix-FLR-miss-detection.patch new file mode 100644 index 0000000..22aba55 --- /dev/null +++ b/0079-net-hns3-fix-FLR-miss-detection.patch @@ -0,0 +1,57 @@ +From f66e027f9088852b8047f3e6c0e6ff3535c4c172 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Wed, 31 Mar 2021 18:01:37 +0800 +Subject: [PATCH 079/189] net/hns3: fix FLR miss detection + +When FLR occurs, the head pointer register of +the command queue will be cleared, resulting in +abnormal detection of the head pointer register +of the command queue. At present, FLR is detected +in this way, and the reset recovery process is +executed. + +However, when FLR occurs, the header pointer +register of the command queue is not necessarily +abnormal. For example, when the driver runs +normally, the value of the header pointer register +of the command queue may also be 0, which will +lead to the miss detection of FLR. + +Therefore, the judgment that whether the base +address register of command queue is 0 is added +to ensure that FLR not miss detection. + +Fixes: 2790c6464725 ("net/hns3: support device reset") +Cc: stable@dpdk.org + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index f8d8b0a..1bf1c32 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -195,12 +195,14 @@ hns3_cmd_csq_clean(struct hns3_hw *hw) + { + struct hns3_cmq_ring *csq = &hw->cmq.csq; + uint32_t head; ++ uint32_t addr; + int clean; + + head = hns3_read_dev(hw, HNS3_CMDQ_TX_HEAD_REG); +- if (!is_valid_csq_clean_head(csq, head)) { +- hns3_err(hw, "wrong cmd head (%u, %u-%u)", head, +- csq->next_to_use, csq->next_to_clean); ++ addr = hns3_read_dev(hw, HNS3_CMDQ_TX_ADDR_L_REG); ++ if (!is_valid_csq_clean_head(csq, head) || addr == 0) { ++ hns3_err(hw, "wrong cmd addr(%0x) head (%u, %u-%u)", addr, head, ++ csq->next_to_use, csq->next_to_clean); + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + __atomic_store_n(&hw->reset.disable_cmd, 1, + __ATOMIC_RELAXED); +-- +2.7.4 + diff --git a/0080-net-hns3-fix-rollback-after-setting-PVID-failure.patch b/0080-net-hns3-fix-rollback-after-setting-PVID-failure.patch new file mode 100644 index 0000000..5e0b410 --- /dev/null +++ b/0080-net-hns3-fix-rollback-after-setting-PVID-failure.patch @@ -0,0 +1,75 @@ +From cb332ad8f8abb2973606f877024867deba6a6ec3 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Wed, 31 Mar 2021 18:01:38 +0800 +Subject: [PATCH 080/189] net/hns3: fix rollback after setting PVID failure + +Currently, three hardware operations are involved in setting the PVID. +If any operation fails, a failure will be returned. And there may be +residual hardware configurations because no rollback is performed. + +This patch adds rollback operation for setting PVID to avoid residual +hardware configuration after the PVID fails to be configured. + +Fixes: 411d23b9eafb ("net/hns3: support VLAN") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 4dff016..4984ff9 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -981,7 +981,7 @@ hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) + { + struct hns3_hw *hw = &hns->hw; + uint16_t port_base_vlan_state; +- int ret; ++ int ret, err; + + if (on == 0 && pvid != hw->port_base_vlan_cfg.pvid) { + if (hw->port_base_vlan_cfg.pvid != HNS3_INVALID_PVID) +@@ -1004,7 +1004,7 @@ hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) + if (ret) { + hns3_err(hw, "failed to config rx vlan strip for pvid, " + "ret = %d", ret); +- return ret; ++ goto pvid_vlan_strip_fail; + } + + if (pvid == HNS3_INVALID_PVID) +@@ -1013,13 +1013,27 @@ hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) + if (ret) { + hns3_err(hw, "failed to update vlan filter entries, ret = %d", + ret); +- return ret; ++ goto vlan_filter_set_fail; + } + + out: + hw->port_base_vlan_cfg.state = port_base_vlan_state; + hw->port_base_vlan_cfg.pvid = on ? pvid : HNS3_INVALID_PVID; + return ret; ++ ++vlan_filter_set_fail: ++ err = hns3_en_pvid_strip(hns, hw->port_base_vlan_cfg.state == ++ HNS3_PORT_BASE_VLAN_ENABLE); ++ if (err) ++ hns3_err(hw, "fail to rollback pvid strip, ret = %d", err); ++ ++pvid_vlan_strip_fail: ++ err = hns3_vlan_txvlan_cfg(hns, hw->port_base_vlan_cfg.state, ++ hw->port_base_vlan_cfg.pvid); ++ if (err) ++ hns3_err(hw, "fail to rollback txvlan status, ret = %d", err); ++ ++ return ret; + } + + static int +-- +2.7.4 + diff --git a/0081-net-hns3-fix-flow-control-exception.patch b/0081-net-hns3-fix-flow-control-exception.patch new file mode 100644 index 0000000..e26359c --- /dev/null +++ b/0081-net-hns3-fix-flow-control-exception.patch @@ -0,0 +1,37 @@ +From 21b64900224a9d81aee3ee20349073f18c5c927f Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 31 Mar 2021 18:01:39 +0800 +Subject: [PATCH 081/189] net/hns3: fix flow control exception + +In multi-TC scenarios, MAC pause is not supported. Otherwise, only +TC0 can trigger pause frames, and other TCs cannot trigger pause +frames. In this case, flow control does not meet the expectation. + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 4984ff9..6f3502f 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5554,6 +5554,11 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return -EOPNOTSUPP; + } + ++ if (hw->num_tc > 1) { ++ hns3_err(hw, "in multi-TC scenarios, MAC pause is not supported."); ++ return -EOPNOTSUPP; ++ } ++ + hns3_get_fc_mode(hw, fc_conf->mode); + if (hw->requested_mode == hw->current_mode && + pf->pause_time == fc_conf->pause_time) +-- +2.7.4 + diff --git a/0082-net-hns3-fix-flow-counter-value.patch b/0082-net-hns3-fix-flow-counter-value.patch new file mode 100644 index 0000000..eb18115 --- /dev/null +++ b/0082-net-hns3-fix-flow-counter-value.patch @@ -0,0 +1,53 @@ +From c75bc1ba60e3af6a8751048a912a01175d940833 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 31 Mar 2021 18:01:40 +0800 +Subject: [PATCH 082/189] net/hns3: fix flow counter value + +User could create flow rules with specified counter by the action of +RTE_FLOW_ACTION_TYPE_COUNT, but the counter may retain the original +value when create. + +This patch fix the bug by read the counter when creating the rule +because the counter is read-clear. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_flow.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index a016857..3cca416 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -158,7 +158,10 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_pf *pf = &hns->pf; ++ struct hns3_hw *hw = &hns->hw; + struct hns3_flow_counter *cnt; ++ uint64_t value; ++ int ret; + + cnt = hns3_counter_lookup(dev, id); + if (cnt) { +@@ -171,6 +174,13 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, + return 0; + } + ++ /* Clear the counter by read ops because the counter is read-clear */ ++ ret = hns3_get_count(hw, id, &value); ++ if (ret) ++ return rte_flow_error_set(error, EIO, ++ RTE_FLOW_ERROR_TYPE_HANDLE, NULL, ++ "Clear counter failed!"); ++ + cnt = rte_zmalloc("hns3 counter", sizeof(*cnt), 0); + if (cnt == NULL) + return rte_flow_error_set(error, ENOMEM, +-- +2.7.4 + diff --git a/0083-net-hns3-fix-VF-mailbox-head-field.patch b/0083-net-hns3-fix-VF-mailbox-head-field.patch new file mode 100644 index 0000000..3e1642d --- /dev/null +++ b/0083-net-hns3-fix-VF-mailbox-head-field.patch @@ -0,0 +1,39 @@ +From 4c2dcb5bd22a65d3b30ca64e5c96f67c3b9f5e7e Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 31 Mar 2021 18:01:41 +0800 +Subject: [PATCH 083/189] net/hns3: fix VF mailbox head field + +Currently, the VF mailbox synchronization communication is based on +three fields: head/tail/lost, when head equals tail plus lost, it +means the response is received successfully. + +The head field indicates the number of requests that are successfully +sent. If the request sending fails, it should not be updated. + +This patch fix the above bug by roll back updates when the sending +fails. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index b9190a1..7357d7f 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -142,6 +142,7 @@ hns3_send_mbx_msg(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + hw->mbx_resp.head++; + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { ++ hw->mbx_resp.head--; + rte_spinlock_unlock(&hw->mbx_resp.lock); + hns3_err(hw, "VF failed(=%d) to send mbx message to PF", + ret); +-- +2.7.4 + diff --git a/0084-net-hns3-support-get-device-version-when-dump-regist.patch b/0084-net-hns3-support-get-device-version-when-dump-regist.patch new file mode 100644 index 0000000..074bdd7 --- /dev/null +++ b/0084-net-hns3-support-get-device-version-when-dump-regist.patch @@ -0,0 +1,34 @@ +From 07e64207da01090076fc5066fed401caf89fc20e Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 31 Mar 2021 18:01:42 +0800 +Subject: [PATCH 084/189] net/hns3: support get device version when dump + register + +Support get device version which is equal to the firmware version +when dump register. + +Fixes: 936eda25e8da ("net/hns3: support dump register") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_regs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 93055a4..374b9ea 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -499,6 +499,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + if (regs->length && regs->length != length) + return -ENOTSUP; + ++ regs->version = hw->fw_version; ++ + /* fetching per-PF registers values from PF PCIe register space */ + data += hns3_direct_access_regs(hw, data); + +-- +2.7.4 + diff --git a/0085-net-hns3-delete-redundant-blank-line.patch b/0085-net-hns3-delete-redundant-blank-line.patch new file mode 100644 index 0000000..1c2ebab --- /dev/null +++ b/0085-net-hns3-delete-redundant-blank-line.patch @@ -0,0 +1,32 @@ +From 59aed028f457ad2f029b85d48bcdf9c9678b3b07 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Wed, 31 Mar 2021 18:01:43 +0800 +Subject: [PATCH 085/189] net/hns3: delete redundant blank line + +Delete redundant blank line in "hns3vf_check_event_cause" to +solve the static warning. + +Fixes: a5475d61fa34 ("net/hns3: support VF") +Cc: stable@dpdk.org + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev_vf.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 22281c8..2a302e5 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1064,7 +1064,6 @@ hns3vf_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + + /* Fetch the events from their corresponding regs */ + cmdq_stat_reg = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_STAT_REG); +- + if (BIT(HNS3_VECTOR0_RST_INT_B) & cmdq_stat_reg) { + rst_ing_reg = hns3_read_dev(hw, HNS3_FUN_RST_ING); + hns3_warn(hw, "resetting reg: 0x%x", rst_ing_reg); +-- +2.7.4 + diff --git a/0086-net-hns3-fix-code-style.patch b/0086-net-hns3-fix-code-style.patch new file mode 100644 index 0000000..1f215e6 --- /dev/null +++ b/0086-net-hns3-fix-code-style.patch @@ -0,0 +1,31 @@ +From 65df0c1e556bfcbb39382da267141676a894decd Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Wed, 31 Mar 2021 18:01:44 +0800 +Subject: [PATCH 086/189] net/hns3: fix code style + +Add one space before the left brace to solve the static warning. + +Fixes: 63e05f19b82b ("net/hns3: support Rx descriptor status query") + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index c41cccb..b06b723 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4477,7 +4477,7 @@ hns3_dev_rx_descriptor_status(void *rx_queue, uint16_t offset) + if (offset >= rxq->nb_rx_desc - rxq->rx_free_hold) + return RTE_ETH_RX_DESC_UNAVAIL; + } else if (dev->rx_pkt_burst == hns3_recv_pkts_vec || +- dev->rx_pkt_burst == hns3_recv_pkts_vec_sve){ ++ dev->rx_pkt_burst == hns3_recv_pkts_vec_sve) { + if (offset >= rxq->nb_rx_desc - rxq->rx_rearm_nb) + return RTE_ETH_RX_DESC_UNAVAIL; + } else { +-- +2.7.4 + diff --git a/0087-net-hns3-refactor-VF-LSC-event-report.patch b/0087-net-hns3-refactor-VF-LSC-event-report.patch new file mode 100644 index 0000000..7dd6c79 --- /dev/null +++ b/0087-net-hns3-refactor-VF-LSC-event-report.patch @@ -0,0 +1,464 @@ +From 053fca7a826300094e247e01c6376ba72f611673 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 9 Apr 2021 12:45:21 +0800 +Subject: [PATCH 087/189] net/hns3: refactor VF LSC event report + +Currently, VF driver periodically obtains link status from PF kernel +driver, and reports lsc event when detects link status change. Because +the period is 1 second, it's probably too late to report especially +in such as bonding scenario. + +To solve this problem we use the following scheme: +1. PF kernel driver support immediate push link status to all VFs when + it detects the link status changes. +2. VF driver will detect PF kernel driver whether support push link + status in device init stage by sending request link info mailbox + message to PF, PF then tell VF the push capability by extend + HNS3_MBX_LINK_STAT_CHANGE mailbox message. +3. VF driver marks RTE_PCI_DRV_INTR_LSC in rte_pci_driver by default, + when it detects PF doesn't support push link status then it will clear + RTE_ETH_DEV_INTR_LSC flag. + +So if PF kernel driver supports push link status to VF, then VF driver +will have RTE_ETH_DEV_INTR_LSC capability. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/features/hns3_vf.ini | 1 + + drivers/net/hns3/hns3_ethdev.h | 27 ++++++ + drivers/net/hns3/hns3_ethdev_vf.c | 171 ++++++++++++++++++++++++++++------- + drivers/net/hns3/hns3_intr.c | 30 ++++++ + drivers/net/hns3/hns3_intr.h | 2 + + drivers/net/hns3/hns3_mbx.c | 3 + + 6 files changed, 199 insertions(+), 35 deletions(-) + +diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini +index a0fd56d..22bb890 100644 +--- a/doc/guides/nics/features/hns3_vf.ini ++++ b/doc/guides/nics/features/hns3_vf.ini +@@ -5,6 +5,7 @@ + ; + [Features] + Link status = Y ++Link status event = Y + Rx interrupt = Y + Queue start/stop = Y + Runtime Rx queue setup = Y +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index fc0dc37..dcf14d6 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -763,8 +763,26 @@ struct hns3_pf { + struct hns3_tm_conf tm_conf; + }; + ++enum { ++ HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED, ++ HNS3_PF_PUSH_LSC_CAP_SUPPORTED, ++ HNS3_PF_PUSH_LSC_CAP_UNKNOWN ++}; ++ + struct hns3_vf { + struct hns3_adapter *adapter; ++ ++ /* Whether PF support push link status change to VF */ ++ uint16_t pf_push_lsc_cap; ++ ++ /* ++ * If PF support push link status change, VF still need send request to ++ * get link status in some cases (such as reset recover stage), so use ++ * the req_link_info_cnt to control max request count. ++ */ ++ uint16_t req_link_info_cnt; ++ ++ uint16_t poll_job_started; /* whether poll job is started */ + }; + + struct hns3_adapter { +@@ -849,6 +867,8 @@ enum { + (&((struct hns3_adapter *)adapter)->hw) + #define HNS3_DEV_PRIVATE_TO_PF(adapter) \ + (&((struct hns3_adapter *)adapter)->pf) ++#define HNS3_DEV_PRIVATE_TO_VF(adapter) \ ++ (&((struct hns3_adapter *)adapter)->vf) + #define HNS3_DEV_HW_TO_ADAPTER(hw) \ + container_of(hw, struct hns3_adapter, hw) + +@@ -858,6 +878,12 @@ static inline struct hns3_pf *HNS3_DEV_HW_TO_PF(struct hns3_hw *hw) + return &adapter->pf; + } + ++static inline struct hns3_vf *HNS3_DEV_HW_TO_VF(struct hns3_hw *hw) ++{ ++ struct hns3_adapter *adapter = HNS3_DEV_HW_TO_ADAPTER(hw); ++ return &adapter->vf; ++} ++ + #define hns3_set_field(origin, mask, shift, val) \ + do { \ + (origin) &= (~(mask)); \ +@@ -1004,6 +1030,7 @@ int hns3_dev_infos_get(struct rte_eth_dev *eth_dev, + void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status, + uint32_t link_speed, uint8_t link_duplex); + void hns3_parse_devargs(struct rte_eth_dev *dev); ++void hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported); + int hns3_restore_ptp(struct hns3_adapter *hns); + int hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev, + struct rte_eth_conf *conf); +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 2a302e5..13f92da 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -44,6 +44,9 @@ 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); ++static int hns3vf_dev_link_update(struct rte_eth_dev *eth_dev, ++ __rte_unused int wait_to_complete); ++ + /* set PCI bus mastering */ + static int + hns3vf_set_bus_master(const struct rte_pci_device *device, bool op) +@@ -1191,6 +1194,65 @@ hns3vf_query_dev_specifications(struct hns3_hw *hw) + return hns3vf_check_dev_specifications(hw); + } + ++void ++hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported) ++{ ++ uint16_t val = supported ? HNS3_PF_PUSH_LSC_CAP_SUPPORTED : ++ HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED; ++ uint16_t exp = HNS3_PF_PUSH_LSC_CAP_UNKNOWN; ++ struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw); ++ ++ if (vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_UNKNOWN) ++ __atomic_compare_exchange(&vf->pf_push_lsc_cap, &exp, &val, 0, ++ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); ++} ++ ++static void ++hns3vf_get_push_lsc_cap(struct hns3_hw *hw) ++{ ++#define HNS3_CHECK_PUSH_LSC_CAP_TIMEOUT_MS 500 ++ ++ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; ++ int32_t remain_ms = HNS3_CHECK_PUSH_LSC_CAP_TIMEOUT_MS; ++ uint16_t val = HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED; ++ uint16_t exp = HNS3_PF_PUSH_LSC_CAP_UNKNOWN; ++ struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw); ++ ++ __atomic_store_n(&vf->pf_push_lsc_cap, HNS3_PF_PUSH_LSC_CAP_UNKNOWN, ++ __ATOMIC_RELEASE); ++ ++ (void)hns3_send_mbx_msg(hw, HNS3_MBX_GET_LINK_STATUS, 0, NULL, 0, false, ++ NULL, 0); ++ ++ while (remain_ms > 0) { ++ rte_delay_ms(HNS3_POLL_RESPONE_MS); ++ if (__atomic_load_n(&vf->pf_push_lsc_cap, __ATOMIC_ACQUIRE) != ++ HNS3_PF_PUSH_LSC_CAP_UNKNOWN) ++ break; ++ remain_ms--; ++ } ++ ++ /* ++ * When exit above loop, the pf_push_lsc_cap could be one of the three ++ * state: unknown (means pf not ack), not_supported, supported. ++ * Here config it as 'not_supported' when it's 'unknown' state. ++ */ ++ __atomic_compare_exchange(&vf->pf_push_lsc_cap, &exp, &val, 0, ++ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); ++ ++ if (__atomic_load_n(&vf->pf_push_lsc_cap, __ATOMIC_ACQUIRE) == ++ HNS3_PF_PUSH_LSC_CAP_SUPPORTED) { ++ hns3_info(hw, "detect PF support push link status change!"); ++ } else { ++ /* ++ * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver ++ * declared RTE_PCI_DRV_INTR_LSC in drv_flags. So here cleared ++ * the RTE_ETH_DEV_INTR_LSC capability. ++ */ ++ dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; ++ } ++} ++ + static int + hns3vf_get_capability(struct hns3_hw *hw) + { +@@ -1404,6 +1466,8 @@ hns3vf_get_configuration(struct hns3_hw *hw) + return ret; + } + ++ hns3vf_get_push_lsc_cap(hw); ++ + /* Get queue configuration from PF */ + ret = hns3vf_get_queue_info(hw); + if (ret) +@@ -1451,15 +1515,28 @@ hns3vf_set_tc_queue_mapping(struct hns3_adapter *hns, uint16_t nb_rx_q, + static void + hns3vf_request_link_info(struct hns3_hw *hw) + { ++ struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw); + uint8_t resp_msg; ++ bool send_req; + int ret; + + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) + return; ++ ++ send_req = vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_NOT_SUPPORTED || ++ vf->req_link_info_cnt > 0; ++ if (!send_req) ++ return; ++ + ret = hns3_send_mbx_msg(hw, HNS3_MBX_GET_LINK_STATUS, 0, NULL, 0, false, + &resp_msg, sizeof(resp_msg)); +- if (ret) +- hns3_err(hw, "Failed to fetch link status from PF: %d", ret); ++ if (ret) { ++ hns3_err(hw, "failed to fetch link status, ret = %d", ret); ++ return; ++ } ++ ++ if (vf->req_link_info_cnt > 0) ++ vf->req_link_info_cnt--; + } + + void +@@ -1467,34 +1544,30 @@ hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status, + uint32_t link_speed, uint8_t link_duplex) + { + struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; ++ struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw); + struct hns3_mac *mac = &hw->mac; +- bool report_lse; +- bool changed; +- +- changed = mac->link_status != link_status || +- mac->link_speed != link_speed || +- mac->link_duplex != link_duplex; +- if (!changed) +- return; ++ int ret; + + /* +- * VF's link status/speed/duplex were updated by polling from PF driver, +- * because the link status/speed/duplex may be changed in the polling +- * interval, so driver will report lse (lsc event) once any of the above +- * thress variables changed. +- * But if the PF's link status is down and driver saved link status is +- * also down, there are no need to report lse. ++ * PF kernel driver may push link status when VF driver is in resetting, ++ * driver will stop polling job in this case, after resetting done ++ * driver will start polling job again. ++ * When polling job started, driver will get initial link status by ++ * sending request to PF kernel driver, then could update link status by ++ * process PF kernel driver's link status mailbox message. + */ +- report_lse = true; +- if (link_status == ETH_LINK_DOWN && link_status == mac->link_status) +- report_lse = false; ++ if (!__atomic_load_n(&vf->poll_job_started, __ATOMIC_RELAXED)) ++ return; ++ ++ if (hw->adapter_state != HNS3_NIC_STARTED) ++ return; + + mac->link_status = link_status; + mac->link_speed = link_speed; + mac->link_duplex = link_duplex; +- +- if (report_lse) +- rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); ++ ret = hns3vf_dev_link_update(dev, 0); ++ if (ret == 0 && dev->data->dev_conf.intr_conf.lsc != 0) ++ hns3_start_report_lse(dev); + } + + static int +@@ -1710,8 +1783,8 @@ hns3vf_service_handler(void *param) + + /* + * The query link status and reset processing are executed in the +- * interrupt thread.When the IMP reset occurs, IMP will not respond, +- * and the query operation will time out after 30ms. In the case of ++ * interrupt thread. When the IMP reset occurs, IMP will not respond, ++ * and the query operation will timeout after 30ms. In the case of + * multiple PF/VFs, each query failure timeout causes the IMP reset + * interrupt to fail to respond within 100ms. + * Before querying the link status, check whether there is a reset +@@ -1726,6 +1799,31 @@ hns3vf_service_handler(void *param) + eth_dev); + } + ++static void ++hns3vf_start_poll_job(struct rte_eth_dev *dev) ++{ ++#define HNS3_REQUEST_LINK_INFO_REMAINS_CNT 3 ++ ++ struct hns3_vf *vf = HNS3_DEV_PRIVATE_TO_VF(dev->data->dev_private); ++ ++ if (vf->pf_push_lsc_cap == HNS3_PF_PUSH_LSC_CAP_SUPPORTED) ++ vf->req_link_info_cnt = HNS3_REQUEST_LINK_INFO_REMAINS_CNT; ++ ++ __atomic_store_n(&vf->poll_job_started, 1, __ATOMIC_RELAXED); ++ ++ hns3vf_service_handler(dev); ++} ++ ++static void ++hns3vf_stop_poll_job(struct rte_eth_dev *dev) ++{ ++ struct hns3_vf *vf = HNS3_DEV_PRIVATE_TO_VF(dev->data->dev_private); ++ ++ rte_eal_alarm_cancel(hns3vf_service_handler, dev); ++ ++ __atomic_store_n(&vf->poll_job_started, 0, __ATOMIC_RELAXED); ++} ++ + static int + hns3_query_vf_resource(struct hns3_hw *hw) + { +@@ -2032,7 +2130,8 @@ hns3vf_dev_stop(struct rte_eth_dev *dev) + hw->adapter_state = HNS3_NIC_CONFIGURED; + } + hns3_rx_scattered_reset(dev); +- rte_eal_alarm_cancel(hns3vf_service_handler, dev); ++ hns3vf_stop_poll_job(dev); ++ hns3_stop_report_lse(dev); + rte_spinlock_unlock(&hw->lock); + + return 0; +@@ -2302,19 +2401,17 @@ hns3vf_dev_start(struct rte_eth_dev *dev) + hns3_rx_scattered_calc(dev); + hns3_set_rxtx_function(dev); + hns3_mp_req_start_rxtx(dev); +- hns3vf_service_handler(dev); + + hns3vf_restore_filter(dev); + + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); +- +- /* +- * After finished the initialization, start all tqps to receive/transmit +- * packets and refresh all queue status. +- */ + hns3_start_tqps(hw); + ++ if (dev->data->dev_conf.intr_conf.lsc != 0) ++ hns3vf_dev_link_update(dev, 0); ++ hns3vf_start_poll_job(dev); ++ + return ret; + + start_all_rxqs_fail: +@@ -2454,9 +2551,13 @@ hns3vf_stop_service(struct hns3_adapter *hns) + + eth_dev = &rte_eth_devices[hw->data->port_id]; + if (hw->adapter_state == HNS3_NIC_STARTED) { +- rte_eal_alarm_cancel(hns3vf_service_handler, eth_dev); ++ /* ++ * Make sure call update link status before hns3vf_stop_poll_job ++ * because update link status depend on polling job exist. ++ */ + hns3vf_update_link_status(hw, ETH_LINK_DOWN, hw->mac.link_speed, +- hw->mac.link_duplex); ++ hw->mac.link_duplex); ++ hns3vf_stop_poll_job(eth_dev); + } + hw->mac.link_status = ETH_LINK_DOWN; + +@@ -2497,7 +2598,7 @@ hns3vf_start_service(struct hns3_adapter *hns) + hns3_set_rxtx_function(eth_dev); + hns3_mp_req_start_rxtx(eth_dev); + if (hw->adapter_state == HNS3_NIC_STARTED) { +- hns3vf_service_handler(eth_dev); ++ hns3vf_start_poll_job(eth_dev); + + /* Enable interrupt of all rx queues before enabling queues */ + hns3_dev_all_rx_queue_intr_enable(hw, true); +@@ -2968,7 +3069,7 @@ static const struct rte_pci_id pci_id_hns3vf_map[] = { + + static struct rte_pci_driver rte_hns3vf_pmd = { + .id_table = pci_id_hns3vf_map, +- .drv_flags = RTE_PCI_DRV_NEED_MAPPING, ++ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, + .probe = eth_hns3vf_pci_probe, + .remove = eth_hns3vf_pci_remove, + }; +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index c259f2e..6250c36 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -2614,3 +2614,33 @@ hns3_reset_abort(struct hns3_adapter *hns) + reset_string[hw->reset.level], tv.tv_sec, tv.tv_usec); + } + } ++ ++static void ++hns3_report_lse(void *arg) ++{ ++ struct rte_eth_dev *dev = (struct rte_eth_dev *)arg; ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ ++ if (hw->adapter_state == HNS3_NIC_STARTED) ++ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); ++} ++ ++void ++hns3_start_report_lse(struct rte_eth_dev *dev) ++{ ++#define DELAY_REPORT_LSE_US 1 ++ /* ++ * When this function called, the context may hold hns3_hw.lock, if ++ * report lse right now, in some application such as bonding, it will ++ * trigger call driver's ops which may acquire hns3_hw.lock again, so ++ * lead to deadlock. ++ * Here we use delay report to avoid the deadlock. ++ */ ++ rte_eal_alarm_set(DELAY_REPORT_LSE_US, hns3_report_lse, dev); ++} ++ ++void ++hns3_stop_report_lse(struct rte_eth_dev *dev) ++{ ++ rte_eal_alarm_cancel(hns3_report_lse, dev); ++} +diff --git a/drivers/net/hns3/hns3_intr.h b/drivers/net/hns3/hns3_intr.h +index c569a9d..4a0a731 100644 +--- a/drivers/net/hns3/hns3_intr.h ++++ b/drivers/net/hns3/hns3_intr.h +@@ -115,5 +115,7 @@ int hns3_reset_req_hw_reset(struct hns3_adapter *hns); + int hns3_reset_process(struct hns3_adapter *hns, + enum hns3_reset_level reset_level); + void hns3_reset_abort(struct hns3_adapter *hns); ++void hns3_start_report_lse(struct rte_eth_dev *dev); ++void hns3_stop_report_lse(struct rte_eth_dev *dev); + + #endif /* _HNS3_INTR_H_ */ +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 7357d7f..ea2953e 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -177,6 +177,7 @@ hns3_mbx_handler(struct hns3_hw *hw) + { + enum hns3_reset_level reset_level; + uint8_t link_status, link_duplex; ++ uint8_t support_push_lsc; + uint32_t link_speed; + uint16_t *msg_q; + uint8_t opcode; +@@ -196,6 +197,8 @@ hns3_mbx_handler(struct hns3_hw *hw) + link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]); + hns3vf_update_link_status(hw, link_status, link_speed, + link_duplex); ++ support_push_lsc = (*(uint8_t *)&msg_q[5]) & 1u; ++ hns3vf_update_push_lsc_cap(hw, support_push_lsc); + break; + case HNS3_MBX_ASSERTING_RESET: + /* PF has asserted reset hence VF should go in pending +-- +2.7.4 + diff --git a/0088-net-hns3-refactor-PF-LSC-event-report.patch b/0088-net-hns3-refactor-PF-LSC-event-report.patch new file mode 100644 index 0000000..dea3358 --- /dev/null +++ b/0088-net-hns3-refactor-PF-LSC-event-report.patch @@ -0,0 +1,242 @@ +From 4190f95f69d9dde53221a65d44672bc61e100419 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 9 Apr 2021 12:45:22 +0800 +Subject: [PATCH 088/189] net/hns3: refactor PF LSC event report + +Currently, PF driver will report lsc when it detects the link status +change, it's not a generic implementation. + +We refactor PF lsc event report by following scheme: +1. PF driver marks RTE_PCI_DRV_INTR_LSC in rte_pci_driver by default. +2. In the init stage, PF driver will detect whether firmware supports + lsc interrupt or not, driver will clear RTE_ETH_DEV_INTR_LSC flag if + firmware doesn't support lsc interrupt. +3. PF driver will report lsc event only when dev_conf.intr_conf.lsc is + set. + +Note: If the firmware supports lsc interrupt, we also keep periodic +polling to deal with the interrupt loss. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/features/hns3.ini | 1 + + drivers/net/hns3/hns3_ethdev.c | 85 ++++++++++++++++++++++++--------------- + drivers/net/hns3/hns3_ethdev.h | 2 +- + drivers/net/hns3/hns3_mbx.c | 2 +- + 4 files changed, 56 insertions(+), 34 deletions(-) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index cc1ad0f..d1a493b 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -5,6 +5,7 @@ + ; + [Features] + Link status = Y ++Link status event = Y + Rx interrupt = Y + Queue start/stop = Y + Runtime Rx queue setup = Y +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 6f3502f..54c72e9 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2753,10 +2753,15 @@ static int + hns3_update_port_link_info(struct rte_eth_dev *eth_dev) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); ++ int ret; + + (void)hns3_update_link_status(hw); + +- return hns3_update_link_info(eth_dev); ++ ret = hns3_update_link_info(eth_dev); ++ if (ret) ++ hw->mac.link_status = ETH_LINK_DOWN; ++ ++ return ret; + } + + static void +@@ -2807,7 +2812,6 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) + do { + ret = hns3_update_port_link_info(eth_dev); + if (ret) { +- mac->link_status = ETH_LINK_DOWN; + hns3_err(hw, "failed to get port link info, ret = %d.", + ret); + break; +@@ -4780,30 +4784,22 @@ hns3_update_link_status(struct hns3_hw *hw) + return false; + } + +-/* +- * Current, the PF driver get link status by two ways: +- * 1) Periodic polling in the intr thread context, driver call +- * hns3_update_link_status to update link status. +- * 2) Firmware report async interrupt, driver process the event in the intr +- * thread context, and call hns3_update_link_status to update link status. +- * +- * If detect link status changed, driver need report LSE. One method is add the +- * report LSE logic in hns3_update_link_status. +- * +- * But the PF driver ops(link_update) also call hns3_update_link_status to +- * update link status. +- * If we report LSE in hns3_update_link_status, it may lead to deadlock in the +- * bonding application. +- * +- * So add the one new API which used only in intr thread context. +- */ + void +-hns3_update_link_status_and_event(struct hns3_hw *hw) ++hns3_update_linkstatus_and_event(struct hns3_hw *hw, bool query) + { + struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; +- bool changed = hns3_update_link_status(hw); +- if (changed) +- rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); ++ struct rte_eth_link new_link; ++ int ret; ++ ++ if (query) ++ hns3_update_port_link_info(dev); ++ ++ memset(&new_link, 0, sizeof(new_link)); ++ hns3_setup_linkstatus(dev, &new_link); ++ ++ ret = rte_eth_linkstatus_set(dev, &new_link); ++ if (ret == 0 && dev->data->dev_conf.intr_conf.lsc != 0) ++ hns3_start_report_lse(dev); + } + + static void +@@ -4813,16 +4809,36 @@ hns3_service_handler(void *param) + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + +- if (!hns3_is_reset_pending(hns)) { +- hns3_update_link_status_and_event(hw); +- hns3_update_link_info(eth_dev); +- } else { ++ if (!hns3_is_reset_pending(hns)) ++ hns3_update_linkstatus_and_event(hw, true); ++ else + hns3_warn(hw, "Cancel the query when reset is pending"); +- } + + rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev); + } + ++static void ++hns3_update_dev_lsc_cap(struct hns3_hw *hw, ++ int fw_compact_cmd_result) ++{ ++ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; ++ ++ if (hw->adapter_state != HNS3_NIC_UNINITIALIZED) ++ return; ++ ++ if (fw_compact_cmd_result != 0) { ++ /* ++ * If fw_compact_cmd_result is not zero, it means firmware don't ++ * support link status change interrupt. ++ * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver ++ * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear ++ * the RTE_ETH_DEV_INTR_LSC capability when detect firmware ++ * don't support link status change interrupt. ++ */ ++ dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; ++ } ++} ++ + static int + hns3_init_hardware(struct hns3_adapter *hns) + { +@@ -4910,6 +4926,7 @@ hns3_init_hardware(struct hns3_adapter *hns) + if (ret) + PMD_INIT_LOG(WARNING, "firmware compatible features not " + "supported, ret = %d.", ret); ++ hns3_update_dev_lsc_cap(hw, ret); + + return 0; + +@@ -5302,7 +5319,6 @@ hns3_dev_start(struct rte_eth_dev *dev) + hns3_rx_scattered_calc(dev); + hns3_set_rxtx_function(dev); + hns3_mp_req_start_rxtx(dev); +- rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, dev); + + hns3_restore_filter(dev); + +@@ -5317,6 +5333,10 @@ hns3_dev_start(struct rte_eth_dev *dev) + + hns3_tm_dev_start_proc(hw); + ++ if (dev->data->dev_conf.intr_conf.lsc != 0) ++ hns3_dev_link_update(dev, 0); ++ rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, dev); ++ + hns3_info(hw, "hns3 dev start successful!"); + + return 0; +@@ -5430,6 +5450,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) + } + hns3_rx_scattered_reset(dev); + rte_eal_alarm_cancel(hns3_service_handler, dev); ++ hns3_stop_report_lse(dev); + rte_spinlock_unlock(&hw->lock); + + return 0; +@@ -5933,11 +5954,11 @@ hns3_stop_service(struct hns3_adapter *hns) + struct rte_eth_dev *eth_dev; + + eth_dev = &rte_eth_devices[hw->data->port_id]; ++ hw->mac.link_status = ETH_LINK_DOWN; + if (hw->adapter_state == HNS3_NIC_STARTED) { + rte_eal_alarm_cancel(hns3_service_handler, eth_dev); +- hns3_update_link_status_and_event(hw); ++ hns3_update_linkstatus_and_event(hw, false); + } +- hw->mac.link_status = ETH_LINK_DOWN; + + hns3_set_rxtx_function(eth_dev); + rte_wmb(); +@@ -6939,7 +6960,7 @@ static const struct rte_pci_id pci_id_hns3_map[] = { + + static struct rte_pci_driver rte_hns3_pmd = { + .id_table = pci_id_hns3_map, +- .drv_flags = RTE_PCI_DRV_NEED_MAPPING, ++ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, + .probe = eth_hns3_pci_probe, + .remove = eth_hns3_pci_remove, + }; +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index dcf14d6..585eeaf 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -1022,7 +1022,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_and_event(struct hns3_hw *hw); ++void hns3_update_linkstatus_and_event(struct hns3_hw *hw, bool query); + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr); + int hns3_dev_infos_get(struct rte_eth_dev *eth_dev, +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index ea2953e..2a96f6c 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -287,7 +287,7 @@ hns3_handle_link_change_event(struct hns3_hw *hw, + if (!req->msg[LINK_STATUS_OFFSET]) + hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]); + +- hns3_update_link_status_and_event(hw); ++ hns3_update_linkstatus_and_event(hw, true); + } + + static void +-- +2.7.4 + diff --git a/0089-net-hns3-log-selected-datapath.patch b/0089-net-hns3-log-selected-datapath.patch new file mode 100644 index 0000000..6f9bb8b --- /dev/null +++ b/0089-net-hns3-log-selected-datapath.patch @@ -0,0 +1,51 @@ +From b9cd59d3f64c7a594fa9b7cbaa3907788fe4696f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 9 Apr 2021 18:26:43 +0800 +Subject: [PATCH 089/189] net/hns3: log selected datapath + +This patch adds debug info for Rx/Tx burst function which was choosing. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index b06b723..e81344c 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4231,6 +4231,22 @@ hns3_dummy_rxtx_burst(void *dpdk_txq __rte_unused, + return 0; + } + ++static void ++hns3_trace_rxtx_function(struct rte_eth_dev *dev) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct rte_eth_burst_mode rx_mode; ++ struct rte_eth_burst_mode tx_mode; ++ ++ memset(&rx_mode, 0, sizeof(rx_mode)); ++ memset(&tx_mode, 0, sizeof(tx_mode)); ++ (void)hns3_rx_burst_mode_get(dev, 0, &rx_mode); ++ (void)hns3_tx_burst_mode_get(dev, 0, &tx_mode); ++ ++ hns3_dbg(hw, "using rx_pkt_burst: %s, tx_pkt_burst: %s.", ++ rx_mode.info, tx_mode.info); ++} ++ + void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + { + struct hns3_adapter *hns = eth_dev->data->dev_private; +@@ -4243,6 +4259,7 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + eth_dev->tx_pkt_burst = hns3_get_tx_function(eth_dev, &prep); + eth_dev->tx_pkt_prepare = prep; + eth_dev->tx_descriptor_status = hns3_dev_tx_descriptor_status; ++ hns3_trace_rxtx_function(eth_dev); + } else { + eth_dev->rx_pkt_burst = hns3_dummy_rxtx_burst; + eth_dev->tx_pkt_burst = hns3_dummy_rxtx_burst; +-- +2.7.4 + diff --git a/0090-net-hns3-simplify-selecting-Rx-Tx-function.patch b/0090-net-hns3-simplify-selecting-Rx-Tx-function.patch new file mode 100644 index 0000000..9b3dabe --- /dev/null +++ b/0090-net-hns3-simplify-selecting-Rx-Tx-function.patch @@ -0,0 +1,109 @@ +From 2633d60f38e8ce132379c3af0dda026e1812a7a2 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 10 Apr 2021 09:11:14 +0800 +Subject: [PATCH 090/189] net/hns3: simplify selecting Rx/Tx function + +Currently, there are four control variables (rx_simple_allowed, +rx_vec_allowed, tx_simple_allowed and tx_vec_allowed) which are used +to impact the selection of Rx/Tx burst function. + +The purpose of the design is to provide a way to control the selection +of Rx/Tx burst function by modifying it's values, but these variables +have no entry to modify unless make intrusive modifications. + +Now we already support runtime config to select Rx/Tx function, these +variables could be removed. + +Fixes: a124f9e9591b ("net/hns3: add runtime config to select IO burst function") + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 5 ----- + drivers/net/hns3/hns3_ethdev.h | 5 ----- + drivers/net/hns3/hns3_ethdev_vf.c | 5 ----- + drivers/net/hns3/hns3_rxtx.c | 11 ++++------- + 4 files changed, 4 insertions(+), 22 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 54c72e9..40af6b8 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2513,11 +2513,6 @@ hns3_dev_configure(struct rte_eth_dev *dev) + if (ret) + goto cfg_err; + +- hns->rx_simple_allowed = true; +- hns->rx_vec_allowed = true; +- hns->tx_simple_allowed = true; +- hns->tx_vec_allowed = true; +- + hns3_init_rx_ptype_tble(dev); + hw->adapter_state = HNS3_NIC_CONFIGURED; + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 585eeaf..cd15bf3 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -795,11 +795,6 @@ struct hns3_adapter { + struct hns3_vf vf; + }; + +- bool rx_simple_allowed; +- bool rx_vec_allowed; +- bool tx_simple_allowed; +- bool tx_vec_allowed; +- + uint32_t rx_func_hint; + uint32_t tx_func_hint; + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 13f92da..dd8f248 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -857,11 +857,6 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) + if (ret) + goto cfg_err; + +- hns->rx_simple_allowed = true; +- hns->rx_vec_allowed = true; +- hns->tx_simple_allowed = true; +- hns->tx_vec_allowed = true; +- + hns3_init_rx_ptype_tble(dev); + + hw->adapter_state = HNS3_NIC_CONFIGURED; +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index e81344c..4ea6b8b 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2805,10 +2805,9 @@ hns3_get_rx_function(struct rte_eth_dev *dev) + uint64_t offloads = dev->data->dev_conf.rxmode.offloads; + bool vec_allowed, sve_allowed, simple_allowed; + +- vec_allowed = hns->rx_vec_allowed && +- hns3_rx_check_vec_support(dev) == 0; ++ vec_allowed = hns3_rx_check_vec_support(dev) == 0; + sve_allowed = vec_allowed && hns3_check_sve_support(); +- simple_allowed = hns->rx_simple_allowed && !dev->data->scattered_rx && ++ simple_allowed = !dev->data->scattered_rx && + (offloads & DEV_RX_OFFLOAD_TCP_LRO) == 0; + + if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_VEC && vec_allowed) +@@ -4195,11 +4194,9 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + struct hns3_adapter *hns = dev->data->dev_private; + bool vec_allowed, sve_allowed, simple_allowed; + +- vec_allowed = hns->tx_vec_allowed && +- hns3_tx_check_vec_support(dev) == 0; ++ vec_allowed = hns3_tx_check_vec_support(dev) == 0; + sve_allowed = vec_allowed && hns3_check_sve_support(); +- simple_allowed = hns->tx_simple_allowed && +- hns3_tx_check_simple_support(dev); ++ simple_allowed = hns3_tx_check_simple_support(dev); + + *prep = NULL; + +-- +2.7.4 + diff --git a/0091-net-hns3-fix-rollback-in-PF-init.patch b/0091-net-hns3-fix-rollback-in-PF-init.patch new file mode 100644 index 0000000..c43415d --- /dev/null +++ b/0091-net-hns3-fix-rollback-in-PF-init.patch @@ -0,0 +1,31 @@ +From 396d7c32a45fd944587cec3424a948f0e1b51e2d Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Sat, 10 Apr 2021 09:11:15 +0800 +Subject: [PATCH 091/189] net/hns3: fix rollback in PF init + +This patch adds rollback processing when updating imissed +stats failed in PF init. + +Fixes: 3e9f3042d7c8 ("net/hns3: add imissed packet stats") + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 40af6b8..c67486c 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5009,7 +5009,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + ret = hns3_update_imissed_stats(hw, true); + if (ret) { + hns3_err(hw, "clear imissed stats failed, ret = %d", ret); +- return ret; ++ goto err_cmd_init; + } + + hns3_config_all_msix_error(hw, true); +-- +2.7.4 + diff --git a/0092-net-hns3-fix-concurrent-interrupt-handling.patch b/0092-net-hns3-fix-concurrent-interrupt-handling.patch new file mode 100644 index 0000000..7921d20 --- /dev/null +++ b/0092-net-hns3-fix-concurrent-interrupt-handling.patch @@ -0,0 +1,42 @@ +From c7b459449995a35bdb5eac512ce8fb65a28cfe7f Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Sat, 10 Apr 2021 09:11:16 +0800 +Subject: [PATCH 092/189] net/hns3: fix concurrent interrupt handling + +Currently, if RAS interrupt and FLR occurred at the same time, FLR will +be detected and corresponding schedule state will be set during RAS +interrupt processing. However, the schedule state value will be +overridden in subsequent RAS processing, resulting in FLR processing +failure. This patch solves this problem. + +Fixes: 2790c6464725 ("net/hns3: support device reset") +Cc: stable@dpdk.org + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_intr.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 6250c36..ccc90c5 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -2133,10 +2133,11 @@ hns3_schedule_reset(struct hns3_adapter *hns) + SCHEDULE_REQUESTED) + return; + if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) == +- SCHEDULE_DEFERRED) ++ SCHEDULE_DEFERRED) + rte_eal_alarm_cancel(hw->reset.ops->reset_service, hns); +- __atomic_store_n(&hw->reset.schedule, SCHEDULE_REQUESTED, +- __ATOMIC_RELAXED); ++ else ++ __atomic_store_n(&hw->reset.schedule, SCHEDULE_REQUESTED, ++ __ATOMIC_RELAXED); + + rte_eal_alarm_set(SWITCH_CONTEXT_US, hw->reset.ops->reset_service, hns); + } +-- +2.7.4 + diff --git a/0093-net-hns3-fix-some-packet-types.patch b/0093-net-hns3-fix-some-packet-types.patch new file mode 100644 index 0000000..b97d784 --- /dev/null +++ b/0093-net-hns3-fix-some-packet-types.patch @@ -0,0 +1,177 @@ +From 4d90ba638f71a610da429d136fec5f3ebc076f97 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 10 Apr 2021 09:11:17 +0800 +Subject: [PATCH 093/189] net/hns3: fix some packet types + +Currently, the packet type calculated by +vlan/ovlan/l3id/l4id/ol3id/ol4id fields have the following problems: +1) Identify error when exist VLAN strip which will lead to the data + buffer has non VLAN header but mbuf's ptype have L2_ETHER_VLAN flag. +2) Some packet identifies error, eg: hardware report it's RARP or + unknown packet, but ptype will marked with L2_ETHER . + +So driver will calculate packet type only by l3id/l4id/ol3id/ol4id +fields. + +Fixes: 0e98d5e6d9c3 ("net/hns3: fix packet type report in Rx") +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 4 +-- + drivers/net/hns3/hns3_rxtx.c | 60 +++++++++++++----------------------------- + drivers/net/hns3/hns3_rxtx.h | 14 ++++------ + 3 files changed, 24 insertions(+), 54 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index cd15bf3..47d998d 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -682,12 +682,10 @@ struct hns3_ptype_table { + * The next fields used to calc packet-type by the + * L3_ID/L4_ID/OL3_ID/OL4_ID from the Rx descriptor. + */ +- uint32_t l2l3table[HNS3_L2TBL_NUM][HNS3_L3TBL_NUM]; ++ uint32_t l3table[HNS3_L3TBL_NUM]; + uint32_t l4table[HNS3_L4TBL_NUM]; +- uint32_t inner_l2table[HNS3_L2TBL_NUM]; + uint32_t inner_l3table[HNS3_L3TBL_NUM]; + uint32_t inner_l4table[HNS3_L4TBL_NUM]; +- uint32_t ol2table[HNS3_OL2TBL_NUM]; + uint32_t ol3table[HNS3_OL3TBL_NUM]; + uint32_t ol4table[HNS3_OL4TBL_NUM]; + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 4ea6b8b..46d6943 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2003,32 +2003,12 @@ hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev) + static void + hns3_init_non_tunnel_ptype_tbl(struct hns3_ptype_table *tbl) + { +- tbl->l2l3table[0][0] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4; +- tbl->l2l3table[0][1] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6; +- tbl->l2l3table[0][2] = RTE_PTYPE_L2_ETHER_ARP; +- tbl->l2l3table[0][3] = RTE_PTYPE_L2_ETHER; +- tbl->l2l3table[0][4] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT; +- tbl->l2l3table[0][5] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT; +- tbl->l2l3table[0][6] = RTE_PTYPE_L2_ETHER_LLDP; +- tbl->l2l3table[0][15] = RTE_PTYPE_L2_ETHER; +- +- tbl->l2l3table[1][0] = RTE_PTYPE_L2_ETHER_VLAN | RTE_PTYPE_L3_IPV4; +- tbl->l2l3table[1][1] = RTE_PTYPE_L2_ETHER_VLAN | RTE_PTYPE_L3_IPV6; +- tbl->l2l3table[1][2] = RTE_PTYPE_L2_ETHER_ARP; +- tbl->l2l3table[1][3] = RTE_PTYPE_L2_ETHER_VLAN; +- tbl->l2l3table[1][4] = RTE_PTYPE_L2_ETHER_VLAN | RTE_PTYPE_L3_IPV4_EXT; +- tbl->l2l3table[1][5] = RTE_PTYPE_L2_ETHER_VLAN | RTE_PTYPE_L3_IPV6_EXT; +- tbl->l2l3table[1][6] = RTE_PTYPE_L2_ETHER_LLDP; +- tbl->l2l3table[1][15] = RTE_PTYPE_L2_ETHER_VLAN; +- +- tbl->l2l3table[2][0] = RTE_PTYPE_L2_ETHER_QINQ | RTE_PTYPE_L3_IPV4; +- tbl->l2l3table[2][1] = RTE_PTYPE_L2_ETHER_QINQ | RTE_PTYPE_L3_IPV6; +- tbl->l2l3table[2][2] = RTE_PTYPE_L2_ETHER_ARP; +- tbl->l2l3table[2][3] = RTE_PTYPE_L2_ETHER_QINQ; +- tbl->l2l3table[2][4] = RTE_PTYPE_L2_ETHER_QINQ | RTE_PTYPE_L3_IPV4_EXT; +- tbl->l2l3table[2][5] = RTE_PTYPE_L2_ETHER_QINQ | RTE_PTYPE_L3_IPV6_EXT; +- tbl->l2l3table[2][6] = RTE_PTYPE_L2_ETHER_LLDP; +- tbl->l2l3table[2][15] = RTE_PTYPE_L2_ETHER_QINQ; ++ tbl->l3table[0] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4; ++ tbl->l3table[1] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6; ++ tbl->l3table[2] = RTE_PTYPE_L2_ETHER_ARP; ++ tbl->l3table[4] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT; ++ tbl->l3table[5] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT; ++ tbl->l3table[6] = RTE_PTYPE_L2_ETHER_LLDP; + + tbl->l4table[0] = RTE_PTYPE_L4_UDP; + tbl->l4table[1] = RTE_PTYPE_L4_TCP; +@@ -2041,17 +2021,17 @@ hns3_init_non_tunnel_ptype_tbl(struct hns3_ptype_table *tbl) + static void + hns3_init_tunnel_ptype_tbl(struct hns3_ptype_table *tbl) + { +- tbl->inner_l2table[0] = RTE_PTYPE_INNER_L2_ETHER; +- tbl->inner_l2table[1] = RTE_PTYPE_INNER_L2_ETHER_VLAN; +- tbl->inner_l2table[2] = RTE_PTYPE_INNER_L2_ETHER_QINQ; +- +- tbl->inner_l3table[0] = RTE_PTYPE_INNER_L3_IPV4; +- tbl->inner_l3table[1] = RTE_PTYPE_INNER_L3_IPV6; ++ tbl->inner_l3table[0] = RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4; ++ tbl->inner_l3table[1] = RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6; + /* There is not a ptype for inner ARP/RARP */ + tbl->inner_l3table[2] = RTE_PTYPE_UNKNOWN; + tbl->inner_l3table[3] = RTE_PTYPE_UNKNOWN; +- tbl->inner_l3table[4] = RTE_PTYPE_INNER_L3_IPV4_EXT; +- tbl->inner_l3table[5] = RTE_PTYPE_INNER_L3_IPV6_EXT; ++ tbl->inner_l3table[4] = RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV4_EXT; ++ tbl->inner_l3table[5] = RTE_PTYPE_INNER_L2_ETHER | ++ RTE_PTYPE_INNER_L3_IPV6_EXT; + + tbl->inner_l4table[0] = RTE_PTYPE_INNER_L4_UDP; + tbl->inner_l4table[1] = RTE_PTYPE_INNER_L4_TCP; +@@ -2062,16 +2042,12 @@ hns3_init_tunnel_ptype_tbl(struct hns3_ptype_table *tbl) + tbl->inner_l4table[4] = RTE_PTYPE_UNKNOWN; + tbl->inner_l4table[5] = RTE_PTYPE_INNER_L4_ICMP; + +- tbl->ol2table[0] = RTE_PTYPE_L2_ETHER; +- tbl->ol2table[1] = RTE_PTYPE_L2_ETHER_VLAN; +- tbl->ol2table[2] = RTE_PTYPE_L2_ETHER_QINQ; +- +- tbl->ol3table[0] = RTE_PTYPE_L3_IPV4; +- tbl->ol3table[1] = RTE_PTYPE_L3_IPV6; ++ tbl->ol3table[0] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4; ++ tbl->ol3table[1] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6; + tbl->ol3table[2] = RTE_PTYPE_UNKNOWN; + tbl->ol3table[3] = RTE_PTYPE_UNKNOWN; +- tbl->ol3table[4] = RTE_PTYPE_L3_IPV4_EXT; +- tbl->ol3table[5] = RTE_PTYPE_L3_IPV6_EXT; ++ tbl->ol3table[4] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT; ++ tbl->ol3table[5] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT; + + tbl->ol4table[0] = RTE_PTYPE_UNKNOWN; + tbl->ol4table[1] = RTE_PTYPE_TUNNEL_VXLAN; +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index eebbebf..44d0ca7 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -635,8 +635,8 @@ hns3_rx_calc_ptype(struct hns3_rx_queue *rxq, const uint32_t l234_info, + const uint32_t ol_info) + { + const struct hns3_ptype_table * const ptype_tbl = rxq->ptype_tbl; +- uint32_t l2id, l3id, l4id; +- uint32_t ol3id, ol4id, ol2id; ++ uint32_t ol3id, ol4id; ++ uint32_t l3id, l4id; + uint32_t ptype; + + if (rxq->ptype_en) { +@@ -647,20 +647,16 @@ hns3_rx_calc_ptype(struct hns3_rx_queue *rxq, const uint32_t l234_info, + + ol4id = hns3_get_field(ol_info, HNS3_RXD_OL4ID_M, HNS3_RXD_OL4ID_S); + ol3id = hns3_get_field(ol_info, HNS3_RXD_OL3ID_M, HNS3_RXD_OL3ID_S); +- ol2id = hns3_get_field(ol_info, HNS3_RXD_OVLAN_M, HNS3_RXD_OVLAN_S); +- l2id = hns3_get_field(l234_info, HNS3_RXD_VLAN_M, HNS3_RXD_VLAN_S); + l3id = hns3_get_field(l234_info, HNS3_RXD_L3ID_M, HNS3_RXD_L3ID_S); + l4id = hns3_get_field(l234_info, HNS3_RXD_L4ID_M, HNS3_RXD_L4ID_S); + + if (unlikely(ptype_tbl->ol4table[ol4id])) +- return ptype_tbl->inner_l2table[l2id] | +- ptype_tbl->inner_l3table[l3id] | ++ return ptype_tbl->inner_l3table[l3id] | + ptype_tbl->inner_l4table[l4id] | + ptype_tbl->ol3table[ol3id] | +- ptype_tbl->ol4table[ol4id] | ptype_tbl->ol2table[ol2id]; ++ ptype_tbl->ol4table[ol4id]; + else +- return ptype_tbl->l2l3table[l2id][l3id] | +- ptype_tbl->l4table[l4id]; ++ return ptype_tbl->l3table[l3id] | ptype_tbl->l4table[l4id]; + } + + void hns3_dev_rx_queue_release(void *queue); +-- +2.7.4 + diff --git a/0094-net-hns3-fix-timing-in-resetting-queues.patch b/0094-net-hns3-fix-timing-in-resetting-queues.patch new file mode 100644 index 0000000..21cf73d --- /dev/null +++ b/0094-net-hns3-fix-timing-in-resetting-queues.patch @@ -0,0 +1,63 @@ +From b4cc7885926cc27da1934c457e4d3ebb43926056 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Sat, 10 Apr 2021 09:11:18 +0800 +Subject: [PATCH 094/189] net/hns3: fix timing in resetting queues + +During the task queue pairs reset, the getimeofday is used to obtain the +timestamp to determine whether the command execution times out. But +gettimeofday is not monotonous, it can be modified by system +administrators, so the timing may not be accurate or even cause the loop +to wait consistently. +And actually, in this scenario, it is not necessary to obtain the +timestamp. + +This patch removes the operation of obtaining the timestamp from the task +queue pairs reset function. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 46d6943..b864350 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -625,8 +625,8 @@ static int + hns3pf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) + { + #define HNS3_TQP_RESET_TRY_MS 200 ++ uint16_t wait_time = 0; + uint8_t reset_status; +- uint64_t end; + int ret; + + /* +@@ -639,17 +639,18 @@ hns3pf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) + hns3_err(hw, "Send reset tqp cmd fail, ret = %d", ret); + return ret; + } +- end = get_timeofday_ms() + HNS3_TQP_RESET_TRY_MS; ++ + do { + /* Wait for tqp hw reset */ + rte_delay_ms(HNS3_POLL_RESPONE_MS); ++ wait_time += HNS3_POLL_RESPONE_MS; + ret = hns3_get_tqp_reset_status(hw, queue_id, &reset_status); + if (ret) + goto tqp_reset_fail; + + if (reset_status) + break; +- } while (get_timeofday_ms() < end); ++ } while (wait_time < HNS3_TQP_RESET_TRY_MS); + + if (!reset_status) { + ret = -ETIMEDOUT; +-- +2.7.4 + diff --git a/0095-net-hns3-fix-queue-state-when-concurrent-with-reset.patch b/0095-net-hns3-fix-queue-state-when-concurrent-with-reset.patch new file mode 100644 index 0000000..f291797 --- /dev/null +++ b/0095-net-hns3-fix-queue-state-when-concurrent-with-reset.patch @@ -0,0 +1,108 @@ +From 94765554f123475e03c5900686b19c2227ce05ad Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Sat, 10 Apr 2021 09:11:19 +0800 +Subject: [PATCH 095/189] net/hns3: fix queue state when concurrent with reset + +At the end of the reset, the state of queues need to be restored +according to the states saved in the driver. If the start and stop +operations of the queues are concurrent at this time, it may cause the +final status to be uncertain. + +This patch requires queues to acquire the hw lock before starting and +stopping. If the device is being restored due to reset at this time, it +will block until the reset is completed. + +Fixes: fa29fe45a7b4 ("net/hns3: support queue start and stop") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index b864350..cbcfb0b 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4287,10 +4287,12 @@ hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + ++ rte_spinlock_lock(&hw->lock); + ret = hns3_reset_queue(hw, rx_queue_id, HNS3_RING_TYPE_RX); + if (ret) { + hns3_err(hw, "fail to reset Rx queue %u, ret = %d.", + rx_queue_id, ret); ++ rte_spinlock_unlock(&hw->lock); + return ret; + } + +@@ -4298,11 +4300,13 @@ hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) + if (ret) { + hns3_err(hw, "fail to init Rx queue %u, ret = %d.", + rx_queue_id, ret); ++ rte_spinlock_unlock(&hw->lock); + return ret; + } + + hns3_enable_rxq(rxq, true); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; ++ rte_spinlock_unlock(&hw->lock); + + return ret; + } +@@ -4329,12 +4333,14 @@ hns3_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + ++ rte_spinlock_lock(&hw->lock); + hns3_enable_rxq(rxq, false); + + hns3_rx_queue_release_mbufs(rxq); + + hns3_reset_sw_rxq(rxq); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; ++ rte_spinlock_unlock(&hw->lock); + + return 0; + } +@@ -4349,16 +4355,19 @@ hns3_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + ++ rte_spinlock_lock(&hw->lock); + ret = hns3_reset_queue(hw, tx_queue_id, HNS3_RING_TYPE_TX); + if (ret) { + hns3_err(hw, "fail to reset Tx queue %u, ret = %d.", + tx_queue_id, ret); ++ rte_spinlock_unlock(&hw->lock); + return ret; + } + + hns3_init_txq(txq); + hns3_enable_txq(txq, true); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; ++ rte_spinlock_unlock(&hw->lock); + + return ret; + } +@@ -4372,6 +4381,7 @@ hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + ++ rte_spinlock_lock(&hw->lock); + hns3_enable_txq(txq, false); + hns3_tx_queue_release_mbufs(txq); + /* +@@ -4383,6 +4393,7 @@ hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) + */ + hns3_init_txq(txq); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; ++ rte_spinlock_unlock(&hw->lock); + + return 0; + } +-- +2.7.4 + diff --git a/0096-net-hns3-fix-configure-FEC-when-concurrent-with-rese.patch b/0096-net-hns3-fix-configure-FEC-when-concurrent-with-rese.patch new file mode 100644 index 0000000..06ed0bd --- /dev/null +++ b/0096-net-hns3-fix-configure-FEC-when-concurrent-with-rese.patch @@ -0,0 +1,48 @@ +From 755d92e8a3c3327632dc9e6f74fb7f07b4073a3e Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Sat, 10 Apr 2021 09:11:20 +0800 +Subject: [PATCH 096/189] net/hns3: fix configure FEC when concurrent with + reset + +Currently, after the reset is complete, the PMD restores the FEC +according to the FEC configuration reserved in the driver. If there is a +concurrency between the FEC setup operation and the restore operation +after a reset, the FEC status of the last hardware may be unknown. + +This patch adds the step of obtaining the lock when setting the FEC to +avoid concurrency between restore operation and setting operation. + +Fixes: 9bf2ea8dbc65 ("net/hns3: support FEC") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index c67486c..85e54ae 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6433,11 +6433,16 @@ hns3_fec_set(struct rte_eth_dev *dev, uint32_t mode) + return -EINVAL; + } + ++ rte_spinlock_lock(&hw->lock); + ret = hns3_set_fec_hw(hw, mode); +- if (ret) ++ if (ret) { ++ rte_spinlock_unlock(&hw->lock); + return ret; ++ } + + pf->fec_mode = mode; ++ rte_spinlock_unlock(&hw->lock); ++ + return 0; + } + +-- +2.7.4 + diff --git a/0097-net-hns3-delete-mailbox-arq-ring.patch b/0097-net-hns3-delete-mailbox-arq-ring.patch new file mode 100644 index 0000000..ad2550c --- /dev/null +++ b/0097-net-hns3-delete-mailbox-arq-ring.patch @@ -0,0 +1,197 @@ +From b46465d9deb6c1e0ef26cc53f4050cb7f6322d56 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:00 +0800 +Subject: [PATCH 097/189] net/hns3: delete mailbox arq ring + +Currently, driver will copy mailbox messages body into arq ring when +process HNS3_MBX_LINK_STAT_CHANGE and HNS3_MBX_LINK_STAT_CHANGE +message, and then call hns3_mbx_handler API which will direct process +pre-copy messages. In the whole process, the arq ring don't have a +substantial effect. + +Note: The arq ring is designed for kernel environment which could not +do much job in interrupt context, but for DPDK it's not required. + +Also we rename hns3_handle_link_change_event to +hns3pf_handle_link_change_event which add 'pf' suffix to make it +better to distinguish. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 1 - + drivers/net/hns3/hns3_mbx.c | 83 +++++++++++++++++------------------------- + drivers/net/hns3/hns3_mbx.h | 14 ------- + 3 files changed, 33 insertions(+), 65 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 47d998d..1763cc9 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -438,7 +438,6 @@ struct hns3_hw { + 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 */ + struct hns3_mac mac; + unsigned int secondary_cnt; /* Number of secondary processes init'd. */ + struct hns3_tqp_stats tqp_stats; +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 2a96f6c..6768207 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -173,55 +173,42 @@ hns3_cmd_crq_empty(struct hns3_hw *hw) + } + + static void +-hns3_mbx_handler(struct hns3_hw *hw) ++hns3vf_handle_link_change_event(struct hns3_hw *hw, ++ struct hns3_mbx_pf_to_vf_cmd *req) + { +- enum hns3_reset_level reset_level; + uint8_t link_status, link_duplex; ++ uint16_t *msg_q = req->msg; + uint8_t support_push_lsc; + uint32_t link_speed; +- uint16_t *msg_q; +- uint8_t opcode; +- uint32_t tail; + +- tail = hw->arq.tail; +- +- /* process all the async queue messages */ +- while (tail != hw->arq.head) { +- msg_q = hw->arq.msg_q[hw->arq.head]; ++ memcpy(&link_speed, &msg_q[2], sizeof(link_speed)); ++ link_status = rte_le_to_cpu_16(msg_q[1]); ++ link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]); ++ hns3vf_update_link_status(hw, link_status, link_speed, ++ link_duplex); ++ support_push_lsc = (*(uint8_t *)&msg_q[5]) & 1u; ++ hns3vf_update_push_lsc_cap(hw, support_push_lsc); ++} + +- opcode = msg_q[0] & 0xff; +- switch (opcode) { +- case HNS3_MBX_LINK_STAT_CHANGE: +- memcpy(&link_speed, &msg_q[2], sizeof(link_speed)); +- link_status = rte_le_to_cpu_16(msg_q[1]); +- link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]); +- hns3vf_update_link_status(hw, link_status, link_speed, +- link_duplex); +- support_push_lsc = (*(uint8_t *)&msg_q[5]) & 1u; +- hns3vf_update_push_lsc_cap(hw, support_push_lsc); +- break; +- case HNS3_MBX_ASSERTING_RESET: +- /* PF has asserted reset hence VF should go in pending +- * state and poll for the hardware reset status till it +- * has been completely reset. After this stack should +- * eventually be re-initialized. +- */ +- reset_level = rte_le_to_cpu_16(msg_q[1]); +- hns3_atomic_set_bit(reset_level, &hw->reset.pending); ++static void ++hns3_handle_asserting_reset(struct hns3_hw *hw, ++ struct hns3_mbx_pf_to_vf_cmd *req) ++{ ++ enum hns3_reset_level reset_level; ++ uint16_t *msg_q = req->msg; + +- hns3_warn(hw, "PF inform reset level %d", reset_level); +- hw->reset.stats.request_cnt++; +- hns3_schedule_reset(HNS3_DEV_HW_TO_ADAPTER(hw)); +- break; +- default: +- hns3_err(hw, "Fetched unsupported(%u) message from arq", +- opcode); +- break; +- } ++ /* ++ * PF has asserted reset hence VF should go in pending ++ * state and poll for the hardware reset status till it ++ * has been completely reset. After this stack should ++ * eventually be re-initialized. ++ */ ++ reset_level = rte_le_to_cpu_16(msg_q[1]); ++ hns3_atomic_set_bit(reset_level, &hw->reset.pending); + +- hns3_mbx_head_ptr_move_arq(hw->arq); +- msg_q = hw->arq.msg_q[hw->arq.head]; +- } ++ hns3_warn(hw, "PF inform reset level %d", reset_level); ++ hw->reset.stats.request_cnt++; ++ hns3_schedule_reset(HNS3_DEV_HW_TO_ADAPTER(hw)); + } + + /* +@@ -278,7 +265,7 @@ hns3_link_fail_parse(struct hns3_hw *hw, uint8_t link_fail_code) + } + + static void +-hns3_handle_link_change_event(struct hns3_hw *hw, ++hns3pf_handle_link_change_event(struct hns3_hw *hw, + struct hns3_mbx_pf_to_vf_cmd *req) + { + #define LINK_STATUS_OFFSET 1 +@@ -337,7 +324,6 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + struct hns3_mbx_pf_to_vf_cmd *req; + struct hns3_cmd_desc *desc; + uint32_t msg_data; +- uint16_t *msg_q; + uint8_t opcode; + uint16_t flag; + uint8_t *temp; +@@ -380,16 +366,13 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + hns3_update_resp_position(hw, msg_data); + break; + case HNS3_MBX_LINK_STAT_CHANGE: ++ hns3vf_handle_link_change_event(hw, req); ++ break; + case HNS3_MBX_ASSERTING_RESET: +- msg_q = hw->arq.msg_q[hw->arq.tail]; +- memcpy(&msg_q[0], req->msg, +- HNS3_MBX_MAX_ARQ_MSG_SIZE * sizeof(uint16_t)); +- hns3_mbx_tail_ptr_move_arq(hw->arq); +- +- hns3_mbx_handler(hw); ++ hns3_handle_asserting_reset(hw, req); + break; + case HNS3_MBX_PUSH_LINK_STATUS: +- hns3_handle_link_change_event(hw, req); ++ hns3pf_handle_link_change_event(hw, req); + break; + case HNS3_MBX_PUSH_VLAN_INFO: + /* +diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h +index 7f7ade1..adb77b5 100644 +--- a/drivers/net/hns3/hns3_mbx.h ++++ b/drivers/net/hns3/hns3_mbx.h +@@ -144,22 +144,8 @@ struct hns3_pf_rst_done_cmd { + + #define HNS3_PF_RESET_DONE_BIT BIT(0) + +-/* used by VF to store the received Async responses from PF */ +-struct hns3_mbx_arq_ring { +-#define HNS3_MBX_MAX_ARQ_MSG_SIZE 8 +-#define HNS3_MBX_MAX_ARQ_MSG_NUM 1024 +- uint32_t head; +- uint32_t tail; +- uint32_t count; +- uint16_t msg_q[HNS3_MBX_MAX_ARQ_MSG_NUM][HNS3_MBX_MAX_ARQ_MSG_SIZE]; +-}; +- + #define hns3_mbx_ring_ptr_move_crq(crq) \ + ((crq)->next_to_use = ((crq)->next_to_use + 1) % (crq)->desc_num) +-#define hns3_mbx_tail_ptr_move_arq(arq) \ +- ((arq).tail = ((arq).tail + 1) % HNS3_MBX_MAX_ARQ_MSG_SIZE) +-#define hns3_mbx_head_ptr_move_arq(arq) \ +- ((arq).head = ((arq).head + 1) % HNS3_MBX_MAX_ARQ_MSG_SIZE) + + struct hns3_hw; + void hns3_dev_handle_mbx_msg(struct hns3_hw *hw); +-- +2.7.4 + diff --git a/0098-net-hns3-fix-possible-mismatched-response-of-mailbox.patch b/0098-net-hns3-fix-possible-mismatched-response-of-mailbox.patch new file mode 100644 index 0000000..0ebe1a8 --- /dev/null +++ b/0098-net-hns3-fix-possible-mismatched-response-of-mailbox.patch @@ -0,0 +1,298 @@ +From a996a465d332ce155ff5a98c451a824516d85e73 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:01 +0800 +Subject: [PATCH 098/189] net/hns3: fix possible mismatched response of mailbox + +Currently, the mailbox synchronous communication between VF and PF use +the following fields to maintain communication: +1. Req_msg_data which was combined by message code and subcode, used to + match request and response. +2. Head which means the number of requests successfully sent by VF. +3. Tail which means the number of responses successfully received by VF. +4. Lost which means the number of requests which are timeout. + +There may possible mismatches of the following situation: +1. VF sends message A with code=1 subcode=1. + Then head=1, tail=0, lost=0. +2. PF was blocked about 500ms when processing the message A. +3. VF will detect message A timeout because it can't get the response +within 500ms. + Then head=1, tail=0, lost=1. +4. VF sends message B with code=1 subcode=1 which equal message A. + Then head=2, tail=0, lost=1. +5. PF processes the first message A and send the response message to VF. +6. VF will update tail field to 1, but the lost field will remain + unchanged because the code/subcode equal message B's, so driver will + return success because now the head(2) equals tail(1) plus lost(1). + This will lead to mismatch of request and response. + +To fix the above bug, we use the following scheme: +1. The message sent from VF was labelled with match_id which was a + unique 16-bit non-zero value. +2. The response sent from PF will label with match_id which got from the + request. +3. The VF uses the match_id to match request and response message. + +This scheme depends on the PF driver, if the PF driver don't support +then VF will uses the original scheme. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 120 +++++++++++++++++++++++++++++++++++--------- + drivers/net/hns3/hns3_mbx.h | 20 +++++++- + 2 files changed, 114 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 6768207..7a69b63 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -40,14 +40,32 @@ hns3_resp_to_errno(uint16_t resp_code) + return -EIO; + } + ++static void ++hns3_mbx_proc_timeout(struct hns3_hw *hw, uint16_t code, uint16_t subcode) ++{ ++ if (hw->mbx_resp.matching_scheme == ++ HNS3_MBX_RESP_MATCHING_SCHEME_OF_ORIGINAL) { ++ hw->mbx_resp.lost++; ++ hns3_err(hw, ++ "VF could not get mbx(%u,%u) head(%u) tail(%u) " ++ "lost(%u) from PF", ++ code, subcode, hw->mbx_resp.head, hw->mbx_resp.tail, ++ hw->mbx_resp.lost); ++ return; ++ } ++ ++ hns3_err(hw, "VF could not get mbx(%u,%u) from PF", code, subcode); ++} ++ + static int +-hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, ++hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + uint8_t *resp_data, uint16_t resp_len) + { + #define HNS3_MAX_RETRY_MS 500 + #define HNS3_WAIT_RESP_US 100 + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_mbx_resp_status *mbx_resp; ++ bool received; + uint64_t now; + uint64_t end; + +@@ -59,8 +77,7 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, + + now = get_timeofday_ms(); + end = now + HNS3_MAX_RETRY_MS; +- while ((hw->mbx_resp.head != hw->mbx_resp.tail + hw->mbx_resp.lost) && +- (now < end)) { ++ while (now < end) { + if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) { + hns3_err(hw, "Don't wait for mbx respone because of " + "disable_cmd"); +@@ -77,16 +94,20 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, + hns3_dev_handle_mbx_msg(hw); + rte_delay_us(HNS3_WAIT_RESP_US); + ++ if (hw->mbx_resp.matching_scheme == ++ HNS3_MBX_RESP_MATCHING_SCHEME_OF_ORIGINAL) ++ received = (hw->mbx_resp.head == ++ hw->mbx_resp.tail + hw->mbx_resp.lost); ++ else ++ received = hw->mbx_resp.received_match_resp; ++ if (received) ++ break; ++ + now = get_timeofday_ms(); + } + hw->mbx_resp.req_msg_data = 0; + if (now >= end) { +- hw->mbx_resp.lost++; +- hns3_err(hw, +- "VF could not get mbx(%u,%u) head(%u) tail(%u) " +- "lost(%u) from PF", +- code0, code1, hw->mbx_resp.head, hw->mbx_resp.tail, +- hw->mbx_resp.lost); ++ hns3_mbx_proc_timeout(hw, code, subcode); + return -ETIME; + } + rte_io_rmb(); +@@ -101,6 +122,29 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1, + return 0; + } + ++static void ++hns3_mbx_prepare_resp(struct hns3_hw *hw, uint16_t code, uint16_t subcode) ++{ ++ /* ++ * Init both matching scheme fields because we may not know the exact ++ * scheme will be used when in the initial phase. ++ * ++ * Also, there are OK to init both matching scheme fields even though ++ * we get the exact scheme which is used. ++ */ ++ hw->mbx_resp.req_msg_data = (uint32_t)code << 16 | subcode; ++ hw->mbx_resp.head++; ++ ++ /* Update match_id and ensure the value of match_id is not zero */ ++ hw->mbx_resp.match_id++; ++ if (hw->mbx_resp.match_id == 0) ++ hw->mbx_resp.match_id = 1; ++ hw->mbx_resp.received_match_resp = false; ++ ++ hw->mbx_resp.resp_status = 0; ++ memset(hw->mbx_resp.additional_info, 0, HNS3_MBX_MAX_RESP_DATA_SIZE); ++} ++ + int + hns3_send_mbx_msg(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + const uint8_t *msg_data, uint8_t msg_len, bool need_resp, +@@ -138,8 +182,8 @@ hns3_send_mbx_msg(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + if (need_resp) { + req->mbx_need_resp |= HNS3_MBX_NEED_RESP_BIT; + rte_spinlock_lock(&hw->mbx_resp.lock); +- hw->mbx_resp.req_msg_data = (uint32_t)code << 16 | subcode; +- hw->mbx_resp.head++; ++ hns3_mbx_prepare_resp(hw, code, subcode); ++ req->match_id = hw->mbx_resp.match_id; + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { + hw->mbx_resp.head--; +@@ -244,6 +288,46 @@ hns3_update_resp_position(struct hns3_hw *hw, uint32_t resp_msg) + } + + static void ++hns3_handle_mbx_response(struct hns3_hw *hw, struct hns3_mbx_pf_to_vf_cmd *req) ++{ ++ struct hns3_mbx_resp_status *resp = &hw->mbx_resp; ++ uint32_t msg_data; ++ ++ if (req->match_id != 0) { ++ /* ++ * If match_id is not zero, it means PF support copy request's ++ * match_id to its response. So VF could use the match_id ++ * to match the request. ++ */ ++ if (resp->matching_scheme != ++ HNS3_MBX_RESP_MATCHING_SCHEME_OF_MATCH_ID) { ++ resp->matching_scheme = ++ HNS3_MBX_RESP_MATCHING_SCHEME_OF_MATCH_ID; ++ hns3_info(hw, "detect mailbox support match id!"); ++ } ++ if (req->match_id == resp->match_id) { ++ resp->resp_status = hns3_resp_to_errno(req->msg[3]); ++ memcpy(resp->additional_info, &req->msg[4], ++ HNS3_MBX_MAX_RESP_DATA_SIZE); ++ rte_io_wmb(); ++ resp->received_match_resp = true; ++ } ++ return; ++ } ++ ++ /* ++ * If the below instructions can be executed, it means PF does not ++ * support copy request's match_id to its response. So VF follows the ++ * original scheme to process. ++ */ ++ resp->resp_status = hns3_resp_to_errno(req->msg[3]); ++ memcpy(resp->additional_info, &req->msg[4], ++ HNS3_MBX_MAX_RESP_DATA_SIZE); ++ msg_data = (uint32_t)req->msg[1] << 16 | req->msg[2]; ++ hns3_update_resp_position(hw, msg_data); ++} ++ ++static void + hns3_link_fail_parse(struct hns3_hw *hw, uint8_t link_fail_code) + { + switch (link_fail_code) { +@@ -319,15 +403,11 @@ hns3_handle_promisc_info(struct hns3_hw *hw, uint16_t promisc_en) + void + hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + { +- struct hns3_mbx_resp_status *resp = &hw->mbx_resp; + struct hns3_cmq_ring *crq = &hw->cmq.crq; + struct hns3_mbx_pf_to_vf_cmd *req; + struct hns3_cmd_desc *desc; +- uint32_t msg_data; + uint8_t opcode; + uint16_t flag; +- uint8_t *temp; +- int i; + + rte_spinlock_lock(&hw->cmq.crq.lock); + +@@ -355,15 +435,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + + switch (opcode) { + case HNS3_MBX_PF_VF_RESP: +- resp->resp_status = hns3_resp_to_errno(req->msg[3]); +- +- temp = (uint8_t *)&req->msg[4]; +- for (i = 0; i < HNS3_MBX_MAX_RESP_DATA_SIZE; i++) { +- resp->additional_info[i] = *temp; +- temp++; +- } +- msg_data = (uint32_t)req->msg[1] << 16 | req->msg[2]; +- hns3_update_resp_position(hw, msg_data); ++ hns3_handle_mbx_response(hw, req); + break; + case HNS3_MBX_LINK_STAT_CHANGE: + hns3vf_handle_link_change_event(hw, req); +diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h +index adb77b5..338c2c2 100644 +--- a/drivers/net/hns3/hns3_mbx.h ++++ b/drivers/net/hns3/hns3_mbx.h +@@ -83,12 +83,26 @@ enum hns3_mbx_link_fail_subcode { + #define HNS3_MBX_RING_MAP_BASIC_MSG_NUM 3 + #define HNS3_MBX_RING_NODE_VARIABLE_NUM 3 + ++enum { ++ HNS3_MBX_RESP_MATCHING_SCHEME_OF_ORIGINAL = 0, ++ HNS3_MBX_RESP_MATCHING_SCHEME_OF_MATCH_ID ++}; ++ + struct hns3_mbx_resp_status { + rte_spinlock_t lock; /* protects against contending sync cmd resp */ ++ ++ uint8_t matching_scheme; ++ ++ /* The following fields used in the matching scheme for original */ + uint32_t req_msg_data; + uint32_t head; + uint32_t tail; + uint32_t lost; ++ ++ /* The following fields used in the matching scheme for match_id */ ++ uint16_t match_id; ++ bool received_match_resp; ++ + int resp_status; + uint8_t additional_info[HNS3_MBX_MAX_RESP_DATA_SIZE]; + }; +@@ -106,7 +120,8 @@ struct hns3_mbx_vf_to_pf_cmd { + uint8_t mbx_need_resp; + uint8_t rsv1; + uint8_t msg_len; +- uint8_t rsv2[3]; ++ uint8_t rsv2; ++ uint16_t match_id; + uint8_t msg[HNS3_MBX_MAX_MSG_SIZE]; + }; + +@@ -114,7 +129,8 @@ struct hns3_mbx_pf_to_vf_cmd { + uint8_t dest_vfid; + uint8_t rsv[3]; + uint8_t msg_len; +- uint8_t rsv1[3]; ++ uint8_t rsv1; ++ uint16_t match_id; + uint16_t msg[8]; + }; + +-- +2.7.4 + diff --git a/0099-net-hns3-fix-VF-handling-LSC-event-in-secondary-proc.patch b/0099-net-hns3-fix-VF-handling-LSC-event-in-secondary-proc.patch new file mode 100644 index 0000000..e4b8069 --- /dev/null +++ b/0099-net-hns3-fix-VF-handling-LSC-event-in-secondary-proc.patch @@ -0,0 +1,135 @@ +From 454906f37a15048b7ed19934382234c762842ef0 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:02 +0800 +Subject: [PATCH 099/189] net/hns3: fix VF handling LSC event in secondary + process + +VF will build two queues (csq: command send queue, crq: command receive +queue) with firmware, the crq may contain the following messages: +1) mailbox response message which was the ack of mailbox sync request. +2) PF's link status change message which may send by PF at anytime; + +Currently, any threads in the primary and secondary processes could +send mailbox sync request, so it will need to process the crq messages +in there own thread context. + +If the crq hold two messages: a) PF's link status change message, b) +mailbox response message when secondary process deals with the crq +messages, it will lead to report lsc event in secondary process +because it uses the policy of processing all pending messages at once. + +We use the following scheme to solve it: +1) threads in secondary process could only process specifics messages + (eg. mailbox response message) in crq, if the message processed, its + opcode will rewrite with zero, then the intr thread in primary + process will not process again. +2) threads other than intr thread in the primary process use the same + processing logic as the threads in secondary process. +3) intr thread in the primary process could process all messages. + +Fixes: 76a3836b98c4 ("net/hns3: fix setting default MAC address in bonding of VF") +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 7a69b63..5a88fe2 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -400,6 +400,44 @@ hns3_handle_promisc_info(struct hns3_hw *hw, uint16_t promisc_en) + } + } + ++static void ++hns3_handle_mbx_msg_out_intr(struct hns3_hw *hw) ++{ ++ struct hns3_cmq_ring *crq = &hw->cmq.crq; ++ struct hns3_mbx_pf_to_vf_cmd *req; ++ struct hns3_cmd_desc *desc; ++ uint32_t tail, next_to_use; ++ uint8_t opcode; ++ uint16_t flag; ++ ++ tail = hns3_read_dev(hw, HNS3_CMDQ_RX_TAIL_REG); ++ next_to_use = crq->next_to_use; ++ while (next_to_use != tail) { ++ desc = &crq->desc[next_to_use]; ++ req = (struct hns3_mbx_pf_to_vf_cmd *)desc->data; ++ opcode = req->msg[0] & 0xff; ++ ++ flag = rte_le_to_cpu_16(crq->desc[next_to_use].flag); ++ if (!hns3_get_bit(flag, HNS3_CMDQ_RX_OUTVLD_B)) ++ goto scan_next; ++ ++ if (crq->desc[next_to_use].opcode == 0) ++ goto scan_next; ++ ++ if (opcode == HNS3_MBX_PF_VF_RESP) { ++ hns3_handle_mbx_response(hw, req); ++ /* ++ * Clear opcode to inform intr thread don't process ++ * again. ++ */ ++ crq->desc[crq->next_to_use].opcode = 0; ++ } ++ ++scan_next: ++ next_to_use = (next_to_use + 1) % hw->cmq.crq.desc_num; ++ } ++} ++ + void + hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + { +@@ -411,6 +449,29 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + + rte_spinlock_lock(&hw->cmq.crq.lock); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY || ++ !rte_thread_is_intr()) { ++ /* ++ * Currently, any threads in the primary and secondary processes ++ * could send mailbox sync request, so it will need to process ++ * the crq message (which is the HNS3_MBX_PF_VF_RESP) in there ++ * own thread context. It may also process other messages ++ * because it uses the policy of processing all pending messages ++ * at once. ++ * But some messages such as HNS3_MBX_PUSH_LINK_STATUS could ++ * only process within the intr thread in primary process, ++ * otherwise it may lead to report lsc event in secondary ++ * process. ++ * So the threads other than intr thread in primary process ++ * could only process HNS3_MBX_PF_VF_RESP message, if the ++ * message processed, its opcode will rewrite with zero, then ++ * the intr thread in primary process will not process again. ++ */ ++ hns3_handle_mbx_msg_out_intr(hw); ++ rte_spinlock_unlock(&hw->cmq.crq.lock); ++ return; ++ } ++ + while (!hns3_cmd_crq_empty(hw)) { + if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) { + rte_spinlock_unlock(&hw->cmq.crq.lock); +@@ -433,6 +494,13 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + continue; + } + ++ if (desc->opcode == 0) { ++ /* Message already processed by other thread */ ++ crq->desc[crq->next_to_use].flag = 0; ++ hns3_mbx_ring_ptr_move_crq(crq); ++ continue; ++ } ++ + switch (opcode) { + case HNS3_MBX_PF_VF_RESP: + hns3_handle_mbx_response(hw, req); +-- +2.7.4 + diff --git a/0100-net-hns3-fix-timing-in-mailbox.patch b/0100-net-hns3-fix-timing-in-mailbox.patch new file mode 100644 index 0000000..ec549fa --- /dev/null +++ b/0100-net-hns3-fix-timing-in-mailbox.patch @@ -0,0 +1,70 @@ +From bfcf3af1b6ccb9eb022ceabcc6d41f3985445c3f Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Tue, 13 Apr 2021 19:50:03 +0800 +Subject: [PATCH 100/189] net/hns3: fix timing in mailbox + +Currently, when processing MBX messages, the system timestamp is obtained +to determine whether timeout occurs. However, the gettimeofday function +is not monotonically increasing. Therefore, this may lead to incorrect +judgment or difficulty exiting the loop. And actually, in this scenario, +it is not necessary to obtain the timestamp. + +This patch deletes the call to the gettimeofday function during MBX +message processing. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 5a88fe2..9955f27 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -61,13 +61,12 @@ static int + hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + uint8_t *resp_data, uint16_t resp_len) + { +-#define HNS3_MAX_RETRY_MS 500 ++#define HNS3_MAX_RETRY_US 500000 + #define HNS3_WAIT_RESP_US 100 + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_mbx_resp_status *mbx_resp; ++ uint32_t wait_time = 0; + bool received; +- uint64_t now; +- uint64_t end; + + if (resp_len > HNS3_MBX_MAX_RESP_DATA_SIZE) { + hns3_err(hw, "VF mbx response len(=%u) exceeds maximum(=%d)", +@@ -75,9 +74,7 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + return -EINVAL; + } + +- now = get_timeofday_ms(); +- end = now + HNS3_MAX_RETRY_MS; +- while (now < end) { ++ while (wait_time < HNS3_MAX_RETRY_US) { + if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) { + hns3_err(hw, "Don't wait for mbx respone because of " + "disable_cmd"); +@@ -103,10 +100,10 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + if (received) + break; + +- now = get_timeofday_ms(); ++ wait_time += HNS3_WAIT_RESP_US; + } + hw->mbx_resp.req_msg_data = 0; +- if (now >= end) { ++ if (wait_time >= HNS3_MAX_RETRY_US) { + hns3_mbx_proc_timeout(hw, code, subcode); + return -ETIME; + } +-- +2.7.4 + diff --git a/0101-net-hns3-fix-use-of-command-status-enumeration.patch b/0101-net-hns3-fix-use-of-command-status-enumeration.patch new file mode 100644 index 0000000..1af67a0 --- /dev/null +++ b/0101-net-hns3-fix-use-of-command-status-enumeration.patch @@ -0,0 +1,99 @@ +From 1e3415f3ba207dfb012e5f4fab96bb5760419fae Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Tue, 13 Apr 2021 19:50:04 +0800 +Subject: [PATCH 101/189] net/hns3: fix use of command status enumeration + +The type of return value of hns3_cmd_send is int, some function declare +the return value as hns3_cmd_status. + +This patch fix the incorrect use of the enum hns3_cmd_status. + +Fixes: 737f30e1c3ab ("net/hns3: support command interface with firmware") +Fixes: 02a7b55657b2 ("net/hns3: support Rx interrupt") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 2 +- + drivers/net/hns3/hns3_cmd.h | 9 +-------- + drivers/net/hns3/hns3_ethdev.c | 12 ++++++------ + 3 files changed, 8 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 1bf1c32..58833ce 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -450,7 +450,7 @@ hns3_build_api_caps(void) + return rte_cpu_to_le_32(api_caps); + } + +-static enum hns3_cmd_status ++static int + hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw) + { + struct hns3_query_version_cmd *resp; +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 5d1fb67..9a975b8 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -56,13 +56,6 @@ enum hns3_cmd_return_status { + HNS3_CMD_ROH_CHECK_FAIL = 12 + }; + +-enum hns3_cmd_status { +- HNS3_STATUS_SUCCESS = 0, +- HNS3_ERR_CSQ_FULL = -1, +- HNS3_ERR_CSQ_TIMEOUT = -2, +- HNS3_ERR_CSQ_ERROR = -3, +-}; +- + struct hns3_misc_vector { + uint8_t *addr; + int vector_irq; +@@ -72,7 +65,7 @@ struct hns3_cmq { + struct hns3_cmq_ring csq; + struct hns3_cmq_ring crq; + uint16_t tx_timeout; +- enum hns3_cmd_status last_status; ++ enum hns3_cmd_return_status last_status; + }; + + enum hns3_opcode_type { +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 85e54ae..a06fdc9 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2310,11 +2310,11 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, + struct hns3_cmd_desc desc; + struct hns3_ctrl_vector_chain_cmd *req = + (struct hns3_ctrl_vector_chain_cmd *)desc.data; +- enum hns3_cmd_status status; + enum hns3_opcode_type op; + uint16_t tqp_type_and_id = 0; + uint16_t type; + uint16_t gl; ++ int ret; + + op = en ? HNS3_OPC_ADD_RING_TO_VECTOR : HNS3_OPC_DEL_RING_TO_VECTOR; + hns3_cmd_setup_basic_desc(&desc, op, false); +@@ -2337,11 +2337,11 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, + gl); + req->tqp_type_and_id[0] = rte_cpu_to_le_16(tqp_type_and_id); + req->int_cause_num = 1; +- status = hns3_cmd_send(hw, &desc, 1); +- if (status) { +- hns3_err(hw, "%s TQP %u fail, vector_id is %u, status is %d.", +- en ? "Map" : "Unmap", queue_id, vector_id, status); +- return status; ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "%s TQP %u fail, vector_id = %u, ret = %d.", ++ en ? "Map" : "Unmap", queue_id, vector_id, ret); ++ return ret; + } + + return 0; +-- +2.7.4 + diff --git a/0102-net-hns3-fix-verification-of-NEON-support.patch b/0102-net-hns3-fix-verification-of-NEON-support.patch new file mode 100644 index 0000000..f964b7c --- /dev/null +++ b/0102-net-hns3-fix-verification-of-NEON-support.patch @@ -0,0 +1,80 @@ +From 0be6bd46ca0352c7308a9bdb04d2f1a9d9ccd888 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:05 +0800 +Subject: [PATCH 102/189] net/hns3: fix verification of NEON support + +This patch adds verification of whether NEON supported. + +Fixes: a3d4f4d291d7 ("net/hns3: support NEON Rx") +Fixes: e31f123db06b ("net/hns3: support NEON Tx") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index cbcfb0b..f3ced19 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -11,7 +11,7 @@ + #include + #include + #include +-#if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE) ++#if defined(RTE_ARCH_ARM64) + #include + #endif + +@@ -2766,7 +2766,17 @@ hns3_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, + } + + static bool +-hns3_check_sve_support(void) ++hns3_get_default_vec_support(void) ++{ ++#if defined(RTE_ARCH_ARM64) ++ if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) ++ return true; ++#endif ++ return false; ++} ++ ++static bool ++hns3_get_sve_support(void) + { + #if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE) + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SVE)) +@@ -2781,9 +2791,11 @@ hns3_get_rx_function(struct rte_eth_dev *dev) + struct hns3_adapter *hns = dev->data->dev_private; + uint64_t offloads = dev->data->dev_conf.rxmode.offloads; + bool vec_allowed, sve_allowed, simple_allowed; ++ bool vec_support; + +- vec_allowed = hns3_rx_check_vec_support(dev) == 0; +- sve_allowed = vec_allowed && hns3_check_sve_support(); ++ vec_support = hns3_rx_check_vec_support(dev) == 0; ++ vec_allowed = vec_support && hns3_get_default_vec_support(); ++ sve_allowed = vec_support && hns3_get_sve_support(); + simple_allowed = !dev->data->scattered_rx && + (offloads & DEV_RX_OFFLOAD_TCP_LRO) == 0; + +@@ -4170,9 +4182,11 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + { + struct hns3_adapter *hns = dev->data->dev_private; + bool vec_allowed, sve_allowed, simple_allowed; ++ bool vec_support; + +- vec_allowed = hns3_tx_check_vec_support(dev) == 0; +- sve_allowed = vec_allowed && hns3_check_sve_support(); ++ vec_support = hns3_tx_check_vec_support(dev) == 0; ++ vec_allowed = vec_support && hns3_get_default_vec_support(); ++ sve_allowed = vec_support && hns3_get_sve_support(); + simple_allowed = hns3_tx_check_simple_support(dev); + + *prep = NULL; +-- +2.7.4 + diff --git a/0103-net-hns3-fix-missing-outer-L4-UDP-flag-for-VXLAN.patch b/0103-net-hns3-fix-missing-outer-L4-UDP-flag-for-VXLAN.patch new file mode 100644 index 0000000..8529f3f --- /dev/null +++ b/0103-net-hns3-fix-missing-outer-L4-UDP-flag-for-VXLAN.patch @@ -0,0 +1,32 @@ +From e8eb8b70d1d9cf8c1fd6ece253d4195e49208a21 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:06 +0800 +Subject: [PATCH 103/189] net/hns3: fix missing outer L4 UDP flag for VXLAN + +This patch adds RTE_PTYPE_L4_UDP flag when parsed tunnel vxlan packet. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index f3ced19..7e9b762 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2051,7 +2051,7 @@ hns3_init_tunnel_ptype_tbl(struct hns3_ptype_table *tbl) + tbl->ol3table[5] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT; + + tbl->ol4table[0] = RTE_PTYPE_UNKNOWN; +- tbl->ol4table[1] = RTE_PTYPE_TUNNEL_VXLAN; ++ tbl->ol4table[1] = RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_VXLAN; + tbl->ol4table[2] = RTE_PTYPE_TUNNEL_NVGRE; + } + +-- +2.7.4 + diff --git a/0104-net-hns3-add-reporting-tunnel-GRE-packet-type.patch b/0104-net-hns3-add-reporting-tunnel-GRE-packet-type.patch new file mode 100644 index 0000000..7583553 --- /dev/null +++ b/0104-net-hns3-add-reporting-tunnel-GRE-packet-type.patch @@ -0,0 +1,45 @@ +From a501cc13ee7b3047e81233c9488a5782108ede68 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:07 +0800 +Subject: [PATCH 104/189] net/hns3: add reporting tunnel GRE packet type + +This patch supports reporting TUNNEL GRE packet type when rxd advanced +layout enabled. + +Fixes: fb5e90694022 ("net/hns3: support Rx descriptor advanced layout") + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 7e9b762..db64578 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2074,8 +2074,8 @@ hns3_init_adv_layout_ptype(struct hns3_ptype_table *tbl) + RTE_PTYPE_L4_UDP; + ptype[20] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_TCP; +- /* The next ptype is GRE over IPv4 */ +- ptype[21] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; ++ ptype[21] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRE; + ptype[22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | + RTE_PTYPE_L4_SCTP; + ptype[23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | +@@ -2162,8 +2162,8 @@ hns3_init_adv_layout_ptype(struct hns3_ptype_table *tbl) + RTE_PTYPE_L4_UDP; + ptype[114] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_TCP; +- /* The next ptype is GRE over IPv6 */ +- ptype[115] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; ++ ptype[115] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | ++ RTE_PTYPE_TUNNEL_GRE; + ptype[116] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | + RTE_PTYPE_L4_SCTP; + ptype[117] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | +-- +2.7.4 + diff --git a/0105-net-hns3-fix-PTP-capability-report.patch b/0105-net-hns3-fix-PTP-capability-report.patch new file mode 100644 index 0000000..14de7cc --- /dev/null +++ b/0105-net-hns3-fix-PTP-capability-report.patch @@ -0,0 +1,47 @@ +From de73577fd9d4db0ea444cd88ab32b03f7d67e81f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:08 +0800 +Subject: [PATCH 105/189] net/hns3: fix PTP capability report + +The PTP depends on special packet type reported by hardware which +enabled rxd advanced layout, so if the hardware doesn't support rxd +advanced layout, driver should ignore the PTP capability. + +Fixes: 438752358158 ("net/hns3: get device capability from firmware") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 58833ce..41e2caa 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -422,8 +422,19 @@ hns3_parse_capability(struct hns3_hw *hw, + if (hns3_get_bit(caps, HNS3_CAPS_FD_QUEUE_REGION_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B, + 1); +- if (hns3_get_bit(caps, HNS3_CAPS_PTP_B)) +- hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_PTP_B, 1); ++ if (hns3_get_bit(caps, HNS3_CAPS_PTP_B)) { ++ /* ++ * PTP depends on special packet type reported by hardware which ++ * enabled rxd advanced layout, so if the hardware doesn't ++ * support rxd advanced layout, driver should ignore the PTP ++ * capability. ++ */ ++ if (hns3_get_bit(caps, HNS3_CAPS_RXD_ADV_LAYOUT_B)) ++ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_PTP_B, 1); ++ else ++ hns3_warn(hw, "ignore PTP capability due to lack of " ++ "rxd advanced layout capability."); ++ } + if (hns3_get_bit(caps, HNS3_CAPS_TX_PUSH_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TX_PUSH_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B)) +-- +2.7.4 + diff --git a/0106-net-hns3-list-supported-ptypes-for-advanced-Rx-descr.patch b/0106-net-hns3-list-supported-ptypes-for-advanced-Rx-descr.patch new file mode 100644 index 0000000..53475f7 --- /dev/null +++ b/0106-net-hns3-list-supported-ptypes-for-advanced-Rx-descr.patch @@ -0,0 +1,74 @@ +From 80f567aff0391603b59243ef493730ec360caaba Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:10 +0800 +Subject: [PATCH 106/189] net/hns3: list supported ptypes for advanced Rx + descriptor + +Kunpeng 930 supports RXD advanced layout. If enabled the layout, the +hardware will report packet type by 8-bit PTYPE filed in the Rx +descriptor, and the supported ptypes are different from original +scheme. So this patch adds supported list for RXD advanced layout. + +Fixes: fb5e90694022 ("net/hns3: support Rx descriptor advanced layout") + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 37 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 35 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index db64578..a37c3c1 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -1991,12 +1991,45 @@ hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev) + RTE_PTYPE_TUNNEL_NVGRE, + RTE_PTYPE_UNKNOWN + }; ++ static const uint32_t adv_layout_ptypes[] = { ++ RTE_PTYPE_L2_ETHER, ++ RTE_PTYPE_L2_ETHER_TIMESYNC, ++ RTE_PTYPE_L2_ETHER_LLDP, ++ RTE_PTYPE_L2_ETHER_ARP, ++ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, ++ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, ++ RTE_PTYPE_L4_FRAG, ++ RTE_PTYPE_L4_NONFRAG, ++ RTE_PTYPE_L4_UDP, ++ RTE_PTYPE_L4_TCP, ++ RTE_PTYPE_L4_SCTP, ++ RTE_PTYPE_L4_IGMP, ++ RTE_PTYPE_L4_ICMP, ++ RTE_PTYPE_TUNNEL_GRE, ++ RTE_PTYPE_TUNNEL_GRENAT, ++ RTE_PTYPE_INNER_L2_ETHER, ++ RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, ++ RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, ++ RTE_PTYPE_INNER_L4_FRAG, ++ RTE_PTYPE_INNER_L4_ICMP, ++ RTE_PTYPE_INNER_L4_NONFRAG, ++ RTE_PTYPE_INNER_L4_UDP, ++ RTE_PTYPE_INNER_L4_TCP, ++ RTE_PTYPE_INNER_L4_SCTP, ++ RTE_PTYPE_INNER_L4_ICMP, ++ RTE_PTYPE_UNKNOWN ++ }; ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (dev->rx_pkt_burst == hns3_recv_pkts || + dev->rx_pkt_burst == hns3_recv_scattered_pkts || + dev->rx_pkt_burst == hns3_recv_pkts_vec || +- dev->rx_pkt_burst == hns3_recv_pkts_vec_sve) +- return ptypes; ++ dev->rx_pkt_burst == hns3_recv_pkts_vec_sve) { ++ if (hns3_dev_rxd_adv_layout_supported(hw)) ++ return adv_layout_ptypes; ++ else ++ return ptypes; ++ } + + return NULL; + } +-- +2.7.4 + diff --git a/0107-net-hns3-remove-VLAN-QinQ-ptypes-from-support-list.patch b/0107-net-hns3-remove-VLAN-QinQ-ptypes-from-support-list.patch new file mode 100644 index 0000000..5df13d5 --- /dev/null +++ b/0107-net-hns3-remove-VLAN-QinQ-ptypes-from-support-list.patch @@ -0,0 +1,49 @@ +From e535bf3131e855ad973c309ec6c5b35e627751aa Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 13 Apr 2021 19:50:11 +0800 +Subject: [PATCH 107/189] net/hns3: remove VLAN/QinQ ptypes from support list + +In the previous patch, driver will calculate packet type by ignoring +VLAN information because the packet type may calculate error when +exist VLAN and VLAN strip. + +So here remove the following ptypes from support list: +1) RTE_PTYPE_L2_ETHER_VLAN +2) RTE_PTYPE_L2_ETHER_QINQ +3) RTE_PTYPE_INNER_L2_ETHER_VLAN +4) RTE_PTYPE_INNER_L2_ETHER_QINQ + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index a37c3c1..43f8c64 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -1962,8 +1962,6 @@ hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev) + { + static const uint32_t ptypes[] = { + RTE_PTYPE_L2_ETHER, +- RTE_PTYPE_L2_ETHER_VLAN, +- RTE_PTYPE_L2_ETHER_QINQ, + RTE_PTYPE_L2_ETHER_LLDP, + RTE_PTYPE_L2_ETHER_ARP, + RTE_PTYPE_L3_IPV4, +@@ -1977,8 +1975,6 @@ hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev) + RTE_PTYPE_L4_UDP, + RTE_PTYPE_TUNNEL_GRE, + RTE_PTYPE_INNER_L2_ETHER, +- RTE_PTYPE_INNER_L2_ETHER_VLAN, +- RTE_PTYPE_INNER_L2_ETHER_QINQ, + RTE_PTYPE_INNER_L3_IPV4, + RTE_PTYPE_INNER_L3_IPV6, + RTE_PTYPE_INNER_L3_IPV4_EXT, +-- +2.7.4 + diff --git a/0108-net-hns3-fix-supported-speed-of-copper-ports.patch b/0108-net-hns3-fix-supported-speed-of-copper-ports.patch new file mode 100644 index 0000000..692973d --- /dev/null +++ b/0108-net-hns3-fix-supported-speed-of-copper-ports.patch @@ -0,0 +1,75 @@ +From aab52c0cbdfbd5c05a8589d08bcdbaa6f34739be Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:11 +0800 +Subject: [PATCH 108/189] net/hns3: fix supported speed of copper ports + +The "supported capability" obtained from firmware on copper ports +includes the speed capability, auto-negotiation capability, and flow +control capability. Therefore, this patch changes "supported_capa" to +"supported_speed" and parses the speed capability supported by the +driver from the "supported capability". + +Fixes: 2e4859f3b362 ("net/hns3: support PF device with copper PHYs") + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 11 +++++++---- + drivers/net/hns3/hns3_ethdev.h | 2 +- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index a06fdc9..e57163b 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4612,7 +4612,10 @@ hns3_update_fiber_link_info(struct hns3_hw *hw) + static void + hns3_parse_copper_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac) + { ++#define HNS3_PHY_SUPPORTED_SPEED_MASK 0x2f ++ + struct hns3_phy_params_bd0_cmd *req; ++ uint32_t supported; + + req = (struct hns3_phy_params_bd0_cmd *)desc[0].data; + mac->link_speed = rte_le_to_cpu_32(req->speed); +@@ -4620,11 +4623,11 @@ hns3_parse_copper_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac) + HNS3_PHY_DUPLEX_CFG_B); + mac->link_autoneg = hns3_get_bit(req->autoneg, + HNS3_PHY_AUTONEG_CFG_B); +- mac->supported_capa = rte_le_to_cpu_32(req->supported); + mac->advertising = rte_le_to_cpu_32(req->advertising); + mac->lp_advertising = rte_le_to_cpu_32(req->lp_advertising); +- mac->support_autoneg = !!(mac->supported_capa & +- HNS3_PHY_LINK_MODE_AUTONEG_BIT); ++ supported = rte_le_to_cpu_32(req->supported); ++ mac->supported_speed = supported & HNS3_PHY_SUPPORTED_SPEED_MASK; ++ mac->support_autoneg = !!(supported & HNS3_PHY_LINK_MODE_AUTONEG_BIT); + } + + static int +@@ -4673,7 +4676,7 @@ hns3_update_copper_link_info(struct hns3_hw *hw) + mac->link_speed = mac_info.link_speed; + mac->link_duplex = mac_info.link_duplex; + mac->link_autoneg = mac_info.link_autoneg; +- mac->supported_capa = mac_info.supported_capa; ++ mac->supported_speed = mac_info.supported_speed; + mac->advertising = mac_info.advertising; + mac->lp_advertising = mac_info.lp_advertising; + mac->support_autoneg = mac_info.support_autoneg; +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 1763cc9..986bf26 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -183,7 +183,7 @@ struct hns3_mac { + uint8_t link_autoneg : 1; /* ETH_LINK_[AUTONEG/FIXED] */ + uint8_t link_status : 1; /* ETH_LINK_[DOWN/UP] */ + uint32_t link_speed; /* ETH_SPEED_NUM_ */ +- uint32_t supported_capa; /* supported capability for current media */ ++ uint32_t supported_speed; /* supported speed for current media type */ + uint32_t advertising; /* advertised capability in the local part */ + /* advertised capability in the link partner */ + uint32_t lp_advertising; +-- +2.7.4 + diff --git a/0109-net-hns3-add-1000M-speed-bit-for-copper-PHYs.patch b/0109-net-hns3-add-1000M-speed-bit-for-copper-PHYs.patch new file mode 100644 index 0000000..07e60e7 --- /dev/null +++ b/0109-net-hns3-add-1000M-speed-bit-for-copper-PHYs.patch @@ -0,0 +1,32 @@ +From 8000e1aa7b8666b401153b6e31519b62d1423aa3 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:12 +0800 +Subject: [PATCH 109/189] net/hns3: add 1000M speed bit for copper PHYs + +The bit(5) of supported, advertising and lp_advertising for copper +PHYs obtained from the firmware indicates 1000M full-duplex. This +speed capability bit is missing in the current codes. + +Fixes: 2e4859f3b362 ("net/hns3: support PF device with copper PHYs") + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 9a975b8..a7dd2b5 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -679,6 +679,7 @@ struct hns3_firmware_compat_cmd { + #define HNS3_PHY_LINK_SPEED_10M_BIT BIT(1) + #define HNS3_PHY_LINK_SPEED_100M_HD_BIT BIT(2) + #define HNS3_PHY_LINK_SPEED_100M_BIT BIT(3) ++#define HNS3_PHY_LINK_SPEED_1000M_BIT BIT(5) + #define HNS3_PHY_LINK_MODE_AUTONEG_BIT BIT(6) + #define HNS3_PHY_LINK_MODE_PAUSE_BIT BIT(13) + #define HNS3_PHY_LINK_MODE_ASYM_PAUSE_BIT BIT(14) +-- +2.7.4 + diff --git a/0110-net-hns3-fix-flow-control-mode.patch b/0110-net-hns3-fix-flow-control-mode.patch new file mode 100644 index 0000000..785897c --- /dev/null +++ b/0110-net-hns3-fix-flow-control-mode.patch @@ -0,0 +1,245 @@ +From ad7b090b87b90f4348cc257b22f4253e466e46f3 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:13 +0800 +Subject: [PATCH 110/189] net/hns3: fix flow control mode + +Currently, hns3 driver doesn't support to flow control auto-negotiation. +The FC mode requested by user is the same as the current FC mode. It is +not necessary to maintain the current FC mode. We only report the current +FC mode based on actual flow control mode in hns3_flow_ctrl_get(). + +This patch removes this redundant field. In addition, "requested_mode" in +hns3_hw struct indicates the FC mode requested by user, and the name is +unreasonable. It needs to be modified to "requested_fc_mode". + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_dcb.c | 23 ++++++++--------------- + drivers/net/hns3/hns3_ethdev.c | 28 ++++++++++------------------ + drivers/net/hns3/hns3_ethdev.h | 3 +-- + 3 files changed, 19 insertions(+), 35 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index ebfc240..49b8be7 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -1238,7 +1238,7 @@ hns3_qs_bp_cfg(struct hns3_hw *hw, uint8_t tc, uint8_t grp_id, uint32_t bit_map) + static void + hns3_get_rx_tx_en_status(struct hns3_hw *hw, bool *tx_en, bool *rx_en) + { +- switch (hw->current_mode) { ++ switch (hw->requested_fc_mode) { + case HNS3_FC_NONE: + *tx_en = false; + *rx_en = false; +@@ -1415,7 +1415,7 @@ hns3_dcb_cfg_validate(struct hns3_adapter *hns, uint8_t *tc, bool *changed) + * We ensure that dcb information can be reconfigured + * after the hns3_priority_flow_ctrl_set function called. + */ +- if (hw->current_mode != HNS3_FC_FULL) ++ if (hw->requested_fc_mode != HNS3_FC_FULL) + *changed = true; + pfc_en = RTE_LEN2MASK((uint8_t)dcb_rx_conf->nb_tcs, uint8_t); + if (hw->dcb_info.pfc_en != pfc_en) +@@ -1529,7 +1529,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + struct hns3_pf *pf = &hns->pf; + struct hns3_hw *hw = &hns->hw; + enum hns3_fc_status fc_status = hw->current_fc_status; +- enum hns3_fc_mode current_mode = hw->current_mode; ++ enum hns3_fc_mode requested_fc_mode = hw->requested_fc_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; + int ret, status; + +@@ -1559,7 +1559,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + return ret; + + hw->current_fc_status = HNS3_FC_STATUS_PFC; +- hw->current_mode = HNS3_FC_FULL; ++ hw->requested_fc_mode = HNS3_FC_FULL; + ret = hns3_dcb_pause_setup_hw(hw); + if (ret) { + hns3_err(hw, "setup pfc failed! ret = %d", ret); +@@ -1580,7 +1580,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + return 0; + + pfc_setup_fail: +- hw->current_mode = current_mode; ++ hw->requested_fc_mode = requested_fc_mode; + hw->current_fc_status = fc_status; + hw->dcb_info.hw_pfc_map = hw_pfc_map; + status = hns3_buffer_alloc(hw); +@@ -1659,8 +1659,7 @@ hns3_dcb_init(struct hns3_hw *hw) + * will be changed. + */ + if (hw->adapter_state == HNS3_NIC_UNINITIALIZED) { +- hw->requested_mode = HNS3_FC_NONE; +- hw->current_mode = hw->requested_mode; ++ hw->requested_fc_mode = HNS3_FC_NONE; + pf->pause_time = HNS3_DEFAULT_PAUSE_TRANS_TIME; + hw->current_fc_status = HNS3_FC_STATUS_NONE; + +@@ -1761,7 +1760,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + enum hns3_fc_status fc_status = hw->current_fc_status; +- enum hns3_fc_mode current_mode = hw->current_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; + uint8_t pfc_en = hw->dcb_info.pfc_en; + uint8_t priority = pfc_conf->priority; +@@ -1769,7 +1767,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + int ret, status; + + pf->pause_time = pfc_conf->fc.pause_time; +- hw->current_mode = hw->requested_mode; + hw->current_fc_status = HNS3_FC_STATUS_PFC; + hw->dcb_info.pfc_en |= BIT(priority); + hw->dcb_info.hw_pfc_map = +@@ -1780,7 +1777,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + + /* + * The flow control mode of all UPs will be changed based on +- * current_mode coming from user. ++ * requested_fc_mode coming from user. + */ + ret = hns3_dcb_pause_setup_hw(hw); + if (ret) { +@@ -1791,7 +1788,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + return 0; + + pfc_setup_fail: +- hw->current_mode = current_mode; + hw->current_fc_status = fc_status; + pf->pause_time = pause_time; + hw->dcb_info.pfc_en = pfc_en; +@@ -1815,18 +1811,16 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + enum hns3_fc_status fc_status = hw->current_fc_status; +- enum hns3_fc_mode current_mode = hw->current_mode; + uint16_t pause_time = pf->pause_time; + int ret; + + pf->pause_time = fc_conf->pause_time; +- hw->current_mode = hw->requested_mode; + + /* + * In fact, current_fc_status is HNS3_FC_STATUS_NONE when mode + * of flow control is configured to be HNS3_FC_NONE. + */ +- if (hw->current_mode == HNS3_FC_NONE) ++ if (hw->requested_fc_mode == HNS3_FC_NONE) + hw->current_fc_status = HNS3_FC_STATUS_NONE; + else + hw->current_fc_status = HNS3_FC_STATUS_MAC_PAUSE; +@@ -1840,7 +1834,6 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return 0; + + setup_fc_fail: +- hw->current_mode = current_mode; + hw->current_fc_status = fc_status; + pf->pause_time = pause_time; + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index e57163b..5e7ac54 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5496,8 +5496,11 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + + fc_conf->pause_time = pf->pause_time; + +- /* return fc current mode */ +- switch (hw->current_mode) { ++ /* ++ * If fc auto-negotiation is not supported, the configured fc mode ++ * from user is the current fc mode. ++ */ ++ switch (hw->requested_fc_mode) { + case HNS3_FC_FULL: + fc_conf->mode = RTE_FC_FULL; + break; +@@ -5521,19 +5524,19 @@ hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) + { + switch (mode) { + case RTE_FC_NONE: +- hw->requested_mode = HNS3_FC_NONE; ++ hw->requested_fc_mode = HNS3_FC_NONE; + break; + case RTE_FC_RX_PAUSE: +- hw->requested_mode = HNS3_FC_RX_PAUSE; ++ hw->requested_fc_mode = HNS3_FC_RX_PAUSE; + break; + case RTE_FC_TX_PAUSE: +- hw->requested_mode = HNS3_FC_TX_PAUSE; ++ hw->requested_fc_mode = HNS3_FC_TX_PAUSE; + break; + case RTE_FC_FULL: +- hw->requested_mode = HNS3_FC_FULL; ++ hw->requested_fc_mode = HNS3_FC_FULL; + break; + default: +- hw->requested_mode = HNS3_FC_NONE; ++ hw->requested_fc_mode = HNS3_FC_NONE; + hns3_warn(hw, "fc_mode(%u) exceeds member scope and is " + "configured to RTE_FC_NONE", mode); + break; +@@ -5544,7 +5547,6 @@ static int + hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + int ret; + + if (fc_conf->high_water || fc_conf->low_water || +@@ -5579,9 +5581,6 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + } + + hns3_get_fc_mode(hw, fc_conf->mode); +- if (hw->requested_mode == hw->current_mode && +- pf->pause_time == fc_conf->pause_time) +- return 0; + + rte_spinlock_lock(&hw->lock); + ret = hns3_fc_enable(dev, fc_conf); +@@ -5595,8 +5594,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, + struct rte_eth_pfc_conf *pfc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); +- uint8_t priority; + int ret; + + if (!hns3_dev_dcb_supported(hw)) { +@@ -5631,12 +5628,7 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, + return -EOPNOTSUPP; + } + +- priority = pfc_conf->priority; + hns3_get_fc_mode(hw, pfc_conf->fc.mode); +- if (hw->dcb_info.pfc_en & BIT(priority) && +- hw->requested_mode == hw->current_mode && +- pfc_conf->fc.pause_time == pf->pause_time) +- return 0; + + rte_spinlock_lock(&hw->lock); + ret = hns3_dcb_pfc_enable(dev, pfc_conf); +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 986bf26..03bb783 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -469,8 +469,7 @@ struct hns3_hw { + + uint8_t num_tc; /* Total number of enabled TCs */ + uint8_t hw_tc_map; +- enum hns3_fc_mode current_mode; +- enum hns3_fc_mode requested_mode; ++ enum hns3_fc_mode requested_fc_mode; /* FC mode requested by user */ + struct hns3_dcb_info dcb_info; + enum hns3_fc_status current_fc_status; /* current flow control status */ + struct hns3_tc_queue_info tc_queue[HNS3_MAX_TC_NUM]; +-- +2.7.4 + diff --git a/0111-net-hns3-fix-firmware-compatibility-configuration.patch b/0111-net-hns3-fix-firmware-compatibility-configuration.patch new file mode 100644 index 0000000..1c01a12 --- /dev/null +++ b/0111-net-hns3-fix-firmware-compatibility-configuration.patch @@ -0,0 +1,278 @@ +From a74108b0e8f10b207b2b253c5511efd519d071a3 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:14 +0800 +Subject: [PATCH 111/189] net/hns3: fix firmware compatibility configuration + +The firmware compatibility configuration in PF driver is used to +maintain the compatibility of some features of the driver and +firmware, and requires firmware to enable these features. Currently, +the configuration is in hns3_init_hardware(), which is a little back. +Because firmware may clear some configurations (such as, MAC related) +after receiving the command. And firmware can not be aware of some +default initializations (such as, flow control) before executing the +command to set the copper PHY when the PHY is controlled by firmware. +Therefore, it is recommended that no other hardware resources are +configured before the compatibility configuration. And it should be +moved to hns3_cmd_init(), which is responsible for the firmware +command initialization of driver. + +In addition, the driver needs to perform corresponding processing +if the command fails to be sent. +1) If firmware fails to take over the copper PHY, the copper port fails + to initialize. +2) If fails to enable the report of link events, the device does not + support the LSC capability. + +Fixes: bff6ebfe30d4 ("net/hns3: refactor PF LSC event report") +Fixes: bac6a0644121 ("net/hns3: fix link status change from firmware") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 116 +++++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_ethdev.c | 56 -------------------- + 2 files changed, 116 insertions(+), 56 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 41e2caa..15bf781 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -526,9 +526,99 @@ hns3_cmd_init_queue(struct hns3_hw *hw) + return ret; + } + ++static void ++hns3_update_dev_lsc_cap(struct hns3_hw *hw, int fw_compact_cmd_result) ++{ ++ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; ++ ++ if (hw->adapter_state != HNS3_NIC_UNINITIALIZED) ++ return; ++ ++ if (fw_compact_cmd_result != 0) { ++ /* ++ * If fw_compact_cmd_result is not zero, it means firmware don't ++ * support link status change interrupt. ++ * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver ++ * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear ++ * the RTE_ETH_DEV_INTR_LSC capability when detect firmware ++ * don't support link status change interrupt. ++ */ ++ dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; ++ } ++} ++ ++static int ++hns3_apply_fw_compat_cmd_result(struct hns3_hw *hw, int result) ++{ ++ if (result != 0 && hns3_dev_copper_supported(hw)) { ++ hns3_err(hw, "firmware fails to initialize the PHY, ret = %d.", ++ result); ++ return result; ++ } ++ ++ hns3_update_dev_lsc_cap(hw, result); ++ ++ return 0; ++} ++ ++static int ++hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init) ++{ ++ struct hns3_firmware_compat_cmd *req; ++ struct hns3_cmd_desc desc; ++ uint32_t compat = 0; ++ ++#if defined(RTE_HNS3_ONLY_1630_FPGA) ++ /* If resv reg enabled phy driver of imp is not configured, driver ++ * will use temporary phy driver. ++ */ ++ struct rte_pci_device *pci_dev; ++ struct rte_eth_dev *eth_dev; ++ uint8_t revision; ++ int ret; ++ ++ eth_dev = &rte_eth_devices[hw->data->port_id]; ++ pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); ++ /* Get PCI revision id */ ++ ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN, ++ HNS3_PCI_REVISION_ID); ++ if (ret != HNS3_PCI_REVISION_ID_LEN) { ++ PMD_INIT_LOG(ERR, "failed to read pci revision id, ret = %d", ++ ret); ++ return -EIO; ++ } ++ if (revision == PCI_REVISION_ID_HIP09_A) { ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ if (hns3_dev_copper_supported(hw) == 0 || pf->is_tmp_phy) { ++ PMD_INIT_LOG(ERR, "***use temp phy driver in dpdk***"); ++ pf->is_tmp_phy = true; ++ hns3_set_bit(hw->capability, ++ HNS3_DEV_SUPPORT_COPPER_B, 1); ++ return 0; ++ } ++ ++ PMD_INIT_LOG(ERR, "***use phy driver in imp***"); ++ } ++#endif ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false); ++ req = (struct hns3_firmware_compat_cmd *)desc.data; ++ ++ if (is_init) { ++ hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1); ++ hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0); ++ if (hns3_dev_copper_supported(hw)) ++ hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1); ++ } ++ req->compat = rte_cpu_to_le_32(compat); ++ ++ return hns3_cmd_send(hw, &desc, 1); ++} ++ + int + hns3_cmd_init(struct hns3_hw *hw) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + uint32_t version; + int ret; + +@@ -575,6 +665,27 @@ hns3_cmd_init(struct hns3_hw *hw) + hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M, + HNS3_FW_VERSION_BYTE0_S)); + ++ if (hns->is_vf) ++ return 0; ++ ++ /* ++ * Requiring firmware to enable some features, firber port can still ++ * work without it, but copper port can't work because the firmware ++ * fails to take over the PHY. ++ */ ++ ret = hns3_firmware_compat_config(hw, true); ++ if (ret) ++ PMD_INIT_LOG(WARNING, "firmware compatible features not " ++ "supported, ret = %d.", ret); ++ ++ /* ++ * Perform some corresponding operations based on the firmware ++ * compatibility configuration result. ++ */ ++ ret = hns3_apply_fw_compat_cmd_result(hw, ret); ++ if (ret) ++ goto err_cmd_init; ++ + return 0; + + err_cmd_init: +@@ -602,6 +713,11 @@ hns3_cmd_destroy_queue(struct hns3_hw *hw) + void + hns3_cmd_uninit(struct hns3_hw *hw) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ ++ if (!hns->is_vf) ++ (void)hns3_firmware_compat_config(hw, false); ++ + __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); + + /* +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 5e7ac54..7bae923 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4118,28 +4118,6 @@ hns3_buffer_alloc(struct hns3_hw *hw) + } + + static int +-hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init) +-{ +- struct hns3_firmware_compat_cmd *req; +- struct hns3_cmd_desc desc; +- uint32_t compat = 0; +- +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false); +- req = (struct hns3_firmware_compat_cmd *)desc.data; +- +- if (is_init) { +- hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1); +- hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0); +- if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) +- hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1); +- } +- +- req->compat = rte_cpu_to_le_32(compat); +- +- return hns3_cmd_send(hw, &desc, 1); +-} +- +-static int + hns3_mac_init(struct hns3_hw *hw) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +@@ -4815,28 +4793,6 @@ hns3_service_handler(void *param) + rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev); + } + +-static void +-hns3_update_dev_lsc_cap(struct hns3_hw *hw, +- int fw_compact_cmd_result) +-{ +- struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; +- +- if (hw->adapter_state != HNS3_NIC_UNINITIALIZED) +- return; +- +- if (fw_compact_cmd_result != 0) { +- /* +- * If fw_compact_cmd_result is not zero, it means firmware don't +- * support link status change interrupt. +- * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver +- * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear +- * the RTE_ETH_DEV_INTR_LSC capability when detect firmware +- * don't support link status change interrupt. +- */ +- dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; +- } +-} +- + static int + hns3_init_hardware(struct hns3_adapter *hns) + { +@@ -4916,16 +4872,6 @@ hns3_init_hardware(struct hns3_adapter *hns) + goto err_mac_init; + } + +- /* +- * Requiring firmware to enable some features, driver can +- * still work without it. +- */ +- ret = hns3_firmware_compat_config(hw, true); +- if (ret) +- PMD_INIT_LOG(WARNING, "firmware compatible features not " +- "supported, ret = %d.", ret); +- hns3_update_dev_lsc_cap(hw, ret); +- + return 0; + + err_mac_init: +@@ -5073,7 +5019,6 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + err_enable_intr: + hns3_fdir_filter_uninit(hns); + err_fdir: +- (void)hns3_firmware_compat_config(hw, false); + hns3_uninit_umv_space(hw); + err_init_hw: + hns3_tqp_stats_uninit(hw); +@@ -5108,7 +5053,6 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) + (void)hns3_config_gro(hw, false); + hns3_promisc_uninit(hw); + hns3_fdir_filter_uninit(hns); +- (void)hns3_firmware_compat_config(hw, false); + hns3_uninit_umv_space(hw); + hns3_tqp_stats_uninit(hw); + hns3_config_mac_tnl_int(hw, false); +-- +2.7.4 + diff --git a/0112-net-hns3-obtain-supported-speed-for-fiber-port.patch b/0112-net-hns3-obtain-supported-speed-for-fiber-port.patch new file mode 100644 index 0000000..6aa88f4 --- /dev/null +++ b/0112-net-hns3-obtain-supported-speed-for-fiber-port.patch @@ -0,0 +1,275 @@ +From 984fd9914cfd3f9d24eb9b6c0914595dba9f3575 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:15 +0800 +Subject: [PATCH 112/189] net/hns3: obtain supported speed for fiber port + +Currently, the speed of fiber port is obtained by using the default +query type of HNS3_OPC_GET_SFP_INFO opcode. In this way, only +the speed of the optical module can be obtained. In fact, the opcode +also supports an active query type, which is a channel for obtaining +information such as the speed, the supported speed, auto-negotiation +capability, and FEC mode. This patch changes the query type of the +opcode from the default query type to the active query type to obtain +the supported speed of fiber port. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.h | 41 ++++++++++++++-------- + drivers/net/hns3/hns3_ethdev.c | 80 ++++++++++++++++++++++++++++++++---------- + drivers/net/hns3/hns3_ethdev.h | 26 ++++++++++++-- + 3 files changed, 113 insertions(+), 34 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index a7dd2b5..4c25c43 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -230,7 +230,7 @@ enum hns3_opcode_type { + /* SFP command */ + HNS3_OPC_GET_SFP_EEPROM = 0x7100, + HNS3_OPC_GET_SFP_EXIST = 0x7101, +- HNS3_OPC_SFP_GET_SPEED = 0x7104, ++ HNS3_OPC_GET_SFP_INFO = 0x7104, + + /* Interrupts commands */ + HNS3_OPC_ADD_RING_TO_VECTOR = 0x1503, +@@ -767,13 +767,6 @@ struct hns3_config_auto_neg_cmd { + uint8_t rsv[20]; + }; + +-#define HNS3_MAC_CFG_FEC_AUTO_EN_B 0 +-#define HNS3_MAC_CFG_FEC_MODE_S 1 +-#define HNS3_MAC_CFG_FEC_MODE_M GENMASK(3, 1) +-#define HNS3_MAC_FEC_OFF 0 +-#define HNS3_MAC_FEC_BASER 1 +-#define HNS3_MAC_FEC_RS 2 +- + #define HNS3_SFP_INFO_BD0_LEN 20UL + #define HNS3_SFP_INFO_BDX_LEN 24UL + +@@ -788,14 +781,34 @@ struct hns3_sfp_type { + uint8_t ext_type; + }; + +-struct hns3_sfp_speed_cmd { +- uint32_t sfp_speed; +- uint8_t query_type; /* 0: sfp speed, 1: active fec */ +- uint8_t active_fec; /* current FEC mode */ +- uint16_t rsv1; +- uint32_t rsv2[4]; ++/* Bitmap flags in supported_speed */ ++#define HNS3_FIBER_LINK_SPEED_1G_BIT BIT(0) ++#define HNS3_FIBER_LINK_SPEED_10G_BIT BIT(1) ++#define HNS3_FIBER_LINK_SPEED_25G_BIT BIT(2) ++#define HNS3_FIBER_LINK_SPEED_50G_BIT BIT(3) ++#define HNS3_FIBER_LINK_SPEED_100G_BIT BIT(4) ++#define HNS3_FIBER_LINK_SPEED_40G_BIT BIT(5) ++#define HNS3_FIBER_LINK_SPEED_100M_BIT BIT(6) ++#define HNS3_FIBER_LINK_SPEED_10M_BIT BIT(7) ++#define HNS3_FIBER_LINK_SPEED_200G_BIT BIT(8) ++ ++struct hns3_sfp_info_cmd { ++ uint32_t sfp_speed; ++ uint8_t query_type; /* 0: sfp speed, 1: active */ ++ uint8_t active_fec; /* current FEC mode */ ++ uint16_t rsv; ++ uint32_t supported_speed; /* speed supported by current media */ ++ uint32_t module_type; ++ uint8_t rsv1[8]; + }; + ++#define HNS3_MAC_CFG_FEC_AUTO_EN_B 0 ++#define HNS3_MAC_CFG_FEC_MODE_S 1 ++#define HNS3_MAC_CFG_FEC_MODE_M GENMASK(3, 1) ++#define HNS3_MAC_FEC_OFF 0 ++#define HNS3_MAC_FEC_BASER 1 ++#define HNS3_MAC_FEC_RS 2 ++ + /* Configure FEC mode, opcode:0x031A */ + struct hns3_config_fec_cmd { + uint8_t fec_mode; +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7bae923..5f629e7 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4507,24 +4507,45 @@ hns3_dev_promisc_restore(struct hns3_adapter *hns) + } + + static int +-hns3_get_sfp_speed(struct hns3_hw *hw, uint32_t *speed) ++hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info) + { +- struct hns3_sfp_speed_cmd *resp; ++ struct hns3_sfp_info_cmd *resp; + struct hns3_cmd_desc desc; + int ret; + +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_SFP_GET_SPEED, true); +- resp = (struct hns3_sfp_speed_cmd *)desc.data; ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GET_SFP_INFO, true); ++ resp = (struct hns3_sfp_info_cmd *)desc.data; ++ resp->query_type = HNS3_ACTIVE_QUERY; ++ + ret = hns3_cmd_send(hw, &desc, 1); + if (ret == -EOPNOTSUPP) { +- hns3_err(hw, "IMP do not support get SFP speed %d", ret); ++ hns3_warn(hw, "firmware does not support get SFP info," ++ " ret = %d.", ret); + return ret; + } else if (ret) { +- hns3_err(hw, "get sfp speed failed %d", ret); ++ hns3_err(hw, "get sfp info failed, ret = %d.", ret); + return ret; + } + +- *speed = resp->sfp_speed; ++ /* ++ * In some case, the speed of MAC obtained from firmware may be 0, it ++ * shouldn't be set to mac->speed. ++ */ ++ if (!rte_le_to_cpu_32(resp->sfp_speed)) ++ return 0; ++ ++ mac_info->link_speed = rte_le_to_cpu_32(resp->sfp_speed); ++ /* ++ * if resp->supported_speed is 0, it means it's an old version ++ * firmware, do not update these params. ++ */ ++ if (resp->supported_speed) { ++ mac_info->query_type = HNS3_ACTIVE_QUERY; ++ mac_info->supported_speed = ++ rte_le_to_cpu_32(resp->supported_speed); ++ } else { ++ mac_info->query_type = HNS3_DEFAULT_QUERY; ++ } + + return 0; + } +@@ -4566,25 +4587,49 @@ static int + hns3_update_fiber_link_info(struct hns3_hw *hw) + { + struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); +- uint32_t speed; ++ struct hns3_mac *mac = &hw->mac; ++ struct hns3_mac mac_info; + int ret; + +- /* If IMP do not support get SFP/qSFP speed, return directly */ ++ /* If firmware do not support get SFP/qSFP speed, return directly */ + if (!pf->support_sfp_query) + return 0; + +- ret = hns3_get_sfp_speed(hw, &speed); ++ memset(&mac_info, 0, sizeof(struct hns3_mac)); ++ ret = hns3_get_sfp_info(hw, &mac_info); + if (ret == -EOPNOTSUPP) { + pf->support_sfp_query = false; + return ret; + } else if (ret) + return ret; + +- if (speed == ETH_SPEED_NUM_NONE) +- return 0; /* do nothing if no SFP */ ++ /* Do nothing if no SFP */ ++ if (mac_info.link_speed == ETH_SPEED_NUM_NONE) ++ return 0; ++ ++ /* ++ * If query_type is HNS3_ACTIVE_QUERY, it is no need ++ * to reconfigure the speed of MAC. Otherwise, it indicates ++ * that the current firmware only supports to obtain the ++ * speed of the SFP, and the speed of MAC needs to reconfigure. ++ */ ++ mac->query_type = mac_info.query_type; ++ if (mac->query_type == HNS3_ACTIVE_QUERY) { ++ if (mac_info.link_speed != mac->link_speed) { ++ ret = hns3_port_shaper_update(hw, mac_info.link_speed); ++ if (ret) ++ return ret; ++ } ++ ++ mac->link_speed = mac_info.link_speed; ++ mac->supported_speed = mac_info.supported_speed; ++ ++ return 0; ++ } + + /* Config full duplex for SFP */ +- return hns3_cfg_mac_speed_dup(hw, speed, ETH_LINK_FULL_DUPLEX); ++ return hns3_cfg_mac_speed_dup(hw, mac_info.link_speed, ++ ETH_LINK_FULL_DUPLEX); + } + + static void +@@ -6200,8 +6245,7 @@ get_current_fec_auto_state(struct hns3_hw *hw, uint8_t *state) + static int + hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa) + { +-#define QUERY_ACTIVE_SPEED 1 +- struct hns3_sfp_speed_cmd *resp; ++ struct hns3_sfp_info_cmd *resp; + uint32_t tmp_fec_capa; + uint8_t auto_state; + struct hns3_cmd_desc desc; +@@ -6223,9 +6267,9 @@ hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa) + } + } + +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_SFP_GET_SPEED, true); +- resp = (struct hns3_sfp_speed_cmd *)desc.data; +- resp->query_type = QUERY_ACTIVE_SPEED; ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GET_SFP_INFO, true); ++ resp = (struct hns3_sfp_info_cmd *)desc.data; ++ resp->query_type = HNS3_ACTIVE_QUERY; + + ret = hns3_cmd_send(hw, &desc, 1); + if (ret == -EOPNOTSUPP) { +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 03bb783..a677ddc 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -174,6 +174,9 @@ enum hns3_media_type { + HNS3_MEDIA_TYPE_NONE, + }; + ++#define HNS3_DEFAULT_QUERY 0 ++#define HNS3_ACTIVE_QUERY 1 ++ + struct hns3_mac { + uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; + bool default_addr_setted; /* whether default addr(mac_addr) is set */ +@@ -183,10 +186,29 @@ struct hns3_mac { + uint8_t link_autoneg : 1; /* ETH_LINK_[AUTONEG/FIXED] */ + uint8_t link_status : 1; /* ETH_LINK_[DOWN/UP] */ + uint32_t link_speed; /* ETH_SPEED_NUM_ */ ++ /* ++ * Some firmware versions support only the SFP speed query. In addition ++ * to the SFP speed query, some firmware supports the query of the speed ++ * capability, auto-negotiation capability, and FEC mode, which can be ++ * selected by the 'query_type' filed in the HNS3_OPC_GET_SFP_INFO CMD. ++ * This field is used to record the SFP information query mode. ++ * Value range: ++ * HNS3_DEFAULT_QUERY/HNS3_ACTIVE_QUERY ++ * ++ * - HNS3_DEFAULT_QUERY ++ * Speed obtained is from SFP. When the queried speed changes, the MAC ++ * speed needs to be reconfigured. ++ * ++ * - HNS3_ACTIVE_QUERY ++ * Speed obtained is from MAC. At this time, it is unnecessary for ++ * driver to reconfigured the MAC speed. In addition, more information, ++ * such as, the speed capability, auto-negotiation capability and FEC ++ * mode, can be obtained by the HNS3_OPC_GET_SFP_INFO CMD. ++ */ ++ uint8_t query_type; + uint32_t supported_speed; /* supported speed for current media type */ + uint32_t advertising; /* advertised capability in the local part */ +- /* advertised capability in the link partner */ +- uint32_t lp_advertising; ++ uint32_t lp_advertising; /* advertised capability in the link partner */ + uint8_t support_autoneg; + }; + +-- +2.7.4 + diff --git a/0113-net-hns3-report-speed-capability-for-PF.patch b/0113-net-hns3-report-speed-capability-for-PF.patch new file mode 100644 index 0000000..477715f --- /dev/null +++ b/0113-net-hns3-report-speed-capability-for-PF.patch @@ -0,0 +1,206 @@ +From 52ae922fdca38de506df971337fcbd0a0cefcd78 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:16 +0800 +Subject: [PATCH 113/189] net/hns3: report speed capability for PF + +The speed capability of the device can be reported to the upper-layer app +in rte_eth_dev_info_get API. In this API, the speed capability is derived +from the 'supported_speed', which is the speed capability actually +supported by the NIC. The value of the 'supported_speed' is obtained +once in the probe stage and may be updated in the scheduled task to deal +with the change of the transmission interface. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/features/hns3.ini | 1 + + drivers/net/hns3/hns3_ethdev.c | 136 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 137 insertions(+) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index d1a493b..4685cc1 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -4,6 +4,7 @@ + ; Refer to default.ini for the full list of available PMD features. + ; + [Features] ++Speed capabilities = Y + Link status = Y + Link status event = Y + Rx interrupt = Y +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 5f629e7..aa9f140 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2617,6 +2617,67 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + return 0; + } + ++static uint32_t ++hns3_get_copper_port_speed_capa(uint32_t supported_speed) ++{ ++ uint32_t speed_capa = 0; ++ ++ if (supported_speed & HNS3_PHY_LINK_SPEED_10M_HD_BIT) ++ speed_capa |= ETH_LINK_SPEED_10M_HD; ++ if (supported_speed & HNS3_PHY_LINK_SPEED_10M_BIT) ++ speed_capa |= ETH_LINK_SPEED_10M; ++ if (supported_speed & HNS3_PHY_LINK_SPEED_100M_HD_BIT) ++ speed_capa |= ETH_LINK_SPEED_100M_HD; ++ if (supported_speed & HNS3_PHY_LINK_SPEED_100M_BIT) ++ speed_capa |= ETH_LINK_SPEED_100M; ++ if (supported_speed & HNS3_PHY_LINK_SPEED_1000M_BIT) ++ speed_capa |= ETH_LINK_SPEED_1G; ++ ++ return speed_capa; ++} ++ ++static uint32_t ++hns3_get_firber_port_speed_capa(uint32_t supported_speed) ++{ ++ uint32_t speed_capa = 0; ++ ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_1G_BIT) ++ speed_capa |= ETH_LINK_SPEED_1G; ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_10G_BIT) ++ speed_capa |= ETH_LINK_SPEED_10G; ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_25G_BIT) ++ speed_capa |= ETH_LINK_SPEED_25G; ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_40G_BIT) ++ speed_capa |= ETH_LINK_SPEED_40G; ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_50G_BIT) ++ speed_capa |= ETH_LINK_SPEED_50G; ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_100G_BIT) ++ speed_capa |= ETH_LINK_SPEED_100G; ++ if (supported_speed & HNS3_FIBER_LINK_SPEED_200G_BIT) ++ speed_capa |= ETH_LINK_SPEED_200G; ++ ++ return speed_capa; ++} ++ ++static uint32_t ++hns3_get_speed_capa(struct hns3_hw *hw) ++{ ++ struct hns3_mac *mac = &hw->mac; ++ uint32_t speed_capa; ++ ++ if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) ++ speed_capa = ++ hns3_get_copper_port_speed_capa(mac->supported_speed); ++ else ++ speed_capa = ++ hns3_get_firber_port_speed_capa(mac->supported_speed); ++ ++ if (mac->support_autoneg == 0) ++ speed_capa |= ETH_LINK_SPEED_FIXED; ++ ++ return speed_capa; ++} ++ + int + hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + { +@@ -2688,6 +2749,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + .nb_mtu_seg_max = hw->max_non_tso_bd_num, + }; + ++ info->speed_capa = hns3_get_speed_capa(hw); + info->default_rxconf = (struct rte_eth_rxconf) { + .rx_free_thresh = HNS3_DEFAULT_RX_FREE_THRESH, + /* +@@ -4957,6 +5019,71 @@ hns3_config_all_msix_error(struct hns3_hw *hw, bool enable) + hns3_write_dev(hw, HNS3_VECTOR0_OTER_EN_REG, val); + } + ++static uint32_t ++hns3_set_firber_default_support_speed(struct hns3_hw *hw) ++{ ++ struct hns3_mac *mac = &hw->mac; ++ ++ switch (mac->link_speed) { ++ case ETH_SPEED_NUM_1G: ++ return HNS3_FIBER_LINK_SPEED_1G_BIT; ++ case ETH_SPEED_NUM_10G: ++ return HNS3_FIBER_LINK_SPEED_10G_BIT; ++ case ETH_SPEED_NUM_25G: ++ return HNS3_FIBER_LINK_SPEED_25G_BIT; ++ case ETH_SPEED_NUM_40G: ++ return HNS3_FIBER_LINK_SPEED_40G_BIT; ++ case ETH_SPEED_NUM_50G: ++ return HNS3_FIBER_LINK_SPEED_50G_BIT; ++ case ETH_SPEED_NUM_100G: ++ return HNS3_FIBER_LINK_SPEED_100G_BIT; ++ case ETH_SPEED_NUM_200G: ++ return HNS3_FIBER_LINK_SPEED_200G_BIT; ++ default: ++ hns3_warn(hw, "invalid speed %u Mbps.", mac->link_speed); ++ return 0; ++ } ++} ++ ++/* ++ * Validity of supported_speed for firber and copper media type can be ++ * guaranteed by the following policy: ++ * Copper: ++ * Although the initialization of the phy in the firmware may not be ++ * completed, the firmware can guarantees that the supported_speed is ++ * an valid value. ++ * Firber: ++ * If the version of firmware supports the acitive query way of the ++ * HNS3_OPC_GET_SFP_INFO opcode, the supported_speed can be obtained ++ * through it. If unsupported, use the SFP's speed as the value of the ++ * supported_speed. ++ */ ++static int ++hns3_get_port_supported_speed(struct rte_eth_dev *eth_dev) ++{ ++ struct hns3_adapter *hns = eth_dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ struct hns3_mac *mac = &hw->mac; ++ int ret; ++ ++ ret = hns3_update_link_info(eth_dev); ++ if (ret) ++ return ret; ++ ++ if (mac->media_type == HNS3_MEDIA_TYPE_FIBER) { ++ /* ++ * Some firmware does not support the report of supported_speed, ++ * and only report the effective speed of SFP. In this case, it ++ * is necessary to use the SFP's speed as the supported_speed. ++ */ ++ if (mac->supported_speed == 0) ++ mac->supported_speed = ++ hns3_set_firber_default_support_speed(hw); ++ } ++ ++ return 0; ++} ++ + static int + hns3_init_pf(struct rte_eth_dev *eth_dev) + { +@@ -5057,10 +5184,19 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + goto err_enable_intr; + } + ++ ret = hns3_get_port_supported_speed(eth_dev); ++ if (ret) { ++ PMD_INIT_LOG(ERR, "failed to get speed capabilities supported " ++ "by device, ret = %d.", ret); ++ goto err_supported_speed; ++ } ++ + hns3_tm_conf_init(eth_dev); + + return 0; + ++err_supported_speed: ++ (void)hns3_enable_hw_error_intr(hns, false); + err_enable_intr: + hns3_fdir_filter_uninit(hns); + err_fdir: +-- +2.7.4 + diff --git a/0114-net-hns3-support-link-speed-autoneg-for-PF.patch b/0114-net-hns3-support-link-speed-autoneg-for-PF.patch new file mode 100644 index 0000000..e86ad81 --- /dev/null +++ b/0114-net-hns3-support-link-speed-autoneg-for-PF.patch @@ -0,0 +1,254 @@ +From 80276e4e599abc03596ab80ebbb4637282299474 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:17 +0800 +Subject: [PATCH 114/189] net/hns3: support link speed autoneg for PF + +This patch supports link speed auto-negotiation for PF. If the +device supports auto-negotiation, the device negotiates with +the link partner at all speeds supported by the device. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.h | 5 +- + drivers/net/hns3/hns3_ethdev.c | 152 ++++++++++++++++++++++++++++++++++++++++- + drivers/net/hns3/hns3_ethdev.h | 6 ++ + 3 files changed, 160 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 4c25c43..a24063b 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -108,6 +108,7 @@ enum hns3_opcode_type { + + /* MAC command */ + HNS3_OPC_CONFIG_MAC_MODE = 0x0301, ++ HNS3_OPC_CONFIG_AN_MODE = 0x0304, + HNS3_OPC_QUERY_LINK_STATUS = 0x0307, + HNS3_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, + HNS3_OPC_CONFIG_SPEED_DUP = 0x0309, +@@ -796,7 +797,9 @@ struct hns3_sfp_info_cmd { + uint32_t sfp_speed; + uint8_t query_type; /* 0: sfp speed, 1: active */ + uint8_t active_fec; /* current FEC mode */ +- uint16_t rsv; ++ uint8_t autoneg; /* current autoneg state */ ++ /* 0: not support autoneg, 1: support autoneg */ ++ uint8_t autoneg_ability; + uint32_t supported_speed; /* speed supported by current media */ + uint32_t module_type; + uint8_t rsv1[8]; +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index aa9f140..019d9fe 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2850,8 +2850,7 @@ hns3_setup_linkstatus(struct rte_eth_dev *eth_dev, + + new_link->link_duplex = mac->link_duplex; + new_link->link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN; +- new_link->link_autoneg = +- !(eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED); ++ new_link->link_autoneg = mac->link_autoneg; + } + + static int +@@ -4605,6 +4604,9 @@ hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info) + mac_info->query_type = HNS3_ACTIVE_QUERY; + mac_info->supported_speed = + rte_le_to_cpu_32(resp->supported_speed); ++ mac_info->support_autoneg = resp->autoneg_ability; ++ mac_info->link_autoneg = (resp->autoneg == 0) ? ETH_LINK_FIXED ++ : ETH_LINK_AUTONEG; + } else { + mac_info->query_type = HNS3_DEFAULT_QUERY; + } +@@ -4685,6 +4687,8 @@ hns3_update_fiber_link_info(struct hns3_hw *hw) + + mac->link_speed = mac_info.link_speed; + mac->supported_speed = mac_info.supported_speed; ++ mac->support_autoneg = mac_info.support_autoneg; ++ mac->link_autoneg = mac_info.link_autoneg; + + return 0; + } +@@ -5248,6 +5252,144 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) + } + + static int ++hns3_set_copper_port_link_speed(struct hns3_hw *hw, ++ struct hns3_set_link_speed_cfg *cfg) ++{ ++ struct hns3_cmd_desc desc[HNS3_PHY_PARAM_CFG_BD_NUM]; ++ struct hns3_phy_params_bd0_cmd *req; ++ uint16_t i; ++ ++ for (i = 0; i < HNS3_PHY_PARAM_CFG_BD_NUM - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, ++ false); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, false); ++ req = (struct hns3_phy_params_bd0_cmd *)desc[0].data; ++ req->autoneg = cfg->autoneg; ++ ++ /* ++ * The full speed capability is used to negotiate when ++ * auto-negotiation is enabled. ++ */ ++ if (cfg->autoneg) { ++ req->advertising = HNS3_PHY_LINK_SPEED_10M_BIT | ++ HNS3_PHY_LINK_SPEED_10M_HD_BIT | ++ HNS3_PHY_LINK_SPEED_100M_BIT | ++ HNS3_PHY_LINK_SPEED_100M_HD_BIT | ++ HNS3_PHY_LINK_SPEED_1000M_BIT; ++ } ++ ++ return hns3_cmd_send(hw, desc, HNS3_PHY_PARAM_CFG_BD_NUM); ++} ++ ++static int ++hns3_set_autoneg(struct hns3_hw *hw, bool enable) ++{ ++ struct hns3_config_auto_neg_cmd *req; ++ struct hns3_cmd_desc desc; ++ uint32_t flag = 0; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CONFIG_AN_MODE, false); ++ ++ req = (struct hns3_config_auto_neg_cmd *)desc.data; ++ if (enable) ++ hns3_set_bit(flag, HNS3_MAC_CFG_AN_EN_B, 1); ++ req->cfg_an_cmd_flag = rte_cpu_to_le_32(flag); ++ ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) ++ hns3_err(hw, "autoneg set cmd failed, ret = %d.", ret); ++ ++ return ret; ++} ++ ++static int ++hns3_set_fiber_port_link_speed(struct hns3_hw *hw, ++ struct hns3_set_link_speed_cfg *cfg) ++{ ++ int ret; ++ ++ if (hw->mac.support_autoneg) { ++ ret = hns3_set_autoneg(hw, cfg->autoneg); ++ if (ret) { ++ hns3_err(hw, "failed to configure auto-negotiation."); ++ return ret; ++ } ++ ++ /* ++ * To enable auto-negotiation, we only need to open the switch ++ * of auto-negotiation, then firmware sets all speed ++ * capabilities. ++ */ ++ if (cfg->autoneg) ++ return 0; ++ } ++ ++ /* ++ * Some hardware doesn't support auto-negotiation, but users may not ++ * configure link_speeds (default 0), which means auto-negotiation ++ * In this case, a warning message need to be printed, instead of ++ * an error. ++ */ ++ if (cfg->autoneg) { ++ hns3_warn(hw, "auto-negotiation is not supported."); ++ return 0; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_set_port_link_speed(struct hns3_hw *hw, ++ struct hns3_set_link_speed_cfg *cfg) ++{ ++ int ret; ++ ++ if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) { ++#if defined(RTE_HNS3_ONLY_1630_FPGA) ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ if (pf->is_tmp_phy) ++ return 0; ++#endif ++ ++ ret = hns3_set_copper_port_link_speed(hw, cfg); ++ if (ret) { ++ hns3_err(hw, "failed to set copper port link speed," ++ "ret = %d.", ret); ++ return ret; ++ } ++ } else if (hw->mac.media_type == HNS3_MEDIA_TYPE_FIBER) { ++ ret = hns3_set_fiber_port_link_speed(hw, cfg); ++ if (ret) { ++ hns3_err(hw, "failed to set fiber port link speed," ++ "ret = %d.", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_apply_link_speed(struct hns3_hw *hw) ++{ ++ struct rte_eth_conf *conf = &hw->data->dev_conf; ++ struct hns3_set_link_speed_cfg cfg; ++ ++ memset(&cfg, 0, sizeof(struct hns3_set_link_speed_cfg)); ++ cfg.autoneg = (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) ? ++ ETH_LINK_AUTONEG : ETH_LINK_FIXED; ++ if (cfg.autoneg != ETH_LINK_AUTONEG) { ++ hns3_err(hw, "device doesn't support to force link speed."); ++ return -EOPNOTSUPP; ++ } ++ ++ return hns3_set_port_link_speed(hw, &cfg); ++} ++ ++static int + hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + { + struct hns3_hw *hw = &hns->hw; +@@ -5280,9 +5422,15 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + PMD_INIT_LOG(ERR, "failed to enable MAC, ret = %d", ret); + goto err_config_mac_mode; + } ++ ++ ret = hns3_apply_link_speed(hw); ++ if (ret) ++ goto err_config_mac_mode; ++ + return 0; + + err_config_mac_mode: ++ (void)hns3_cfg_mac_mode(hw, false); + hns3_dev_release_mbufs(hns); + /* + * Here is exception handling, hns3_reset_all_tqps will have the +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index a677ddc..8b6c0d2 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -165,6 +165,12 @@ struct hns3_cfg { + uint16_t umv_space; + }; + ++struct hns3_set_link_speed_cfg { ++ uint32_t speed; ++ uint8_t duplex : 1; ++ uint8_t autoneg : 1; ++}; ++ + /* mac media type */ + enum hns3_media_type { + HNS3_MEDIA_TYPE_UNKNOWN, +-- +2.7.4 + diff --git a/0115-net-hns3-support-flow-control-autoneg-for-copper-por.patch b/0115-net-hns3-support-flow-control-autoneg-for-copper-por.patch new file mode 100644 index 0000000..706f60d --- /dev/null +++ b/0115-net-hns3-support-flow-control-autoneg-for-copper-por.patch @@ -0,0 +1,239 @@ +From d2f7bc262f17f8f640e279706f6b3bc99a4dbb0f Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:18 +0800 +Subject: [PATCH 115/189] net/hns3: support flow control autoneg for copper + port + +If the flow control auto-negotiation is not supported and the flow +control modes on the local and link partner is asymmetric, the flow +control on the NIC does not take effect. The support of the +auto-negotiation capability requires the cooperation of the firmware +and driver. + +This patch supports the flow control auto-negotiation only for copper +port. For optical ports, the forced flow control mode is still used. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 162 ++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 152 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 019d9fe..1ee1651 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5088,6 +5088,24 @@ hns3_get_port_supported_speed(struct rte_eth_dev *eth_dev) + return 0; + } + ++static void ++hns3_get_fc_autoneg_capability(struct hns3_adapter *hns) ++{ ++ struct hns3_mac *mac = &hns->hw.mac; ++ ++ if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) { ++ hns->pf.support_fc_autoneg = true; ++ return; ++ } ++ ++ /* ++ * Flow control auto-negotiation requires the cooperation of the driver ++ * and firmware. Currently, the optical port does not support flow ++ * control auto-negotiation. ++ */ ++ hns->pf.support_fc_autoneg = false; ++} ++ + static int + hns3_init_pf(struct rte_eth_dev *eth_dev) + { +@@ -5195,6 +5213,8 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) + goto err_supported_speed; + } + ++ hns3_get_fc_autoneg_capability(hns); ++ + hns3_tm_conf_init(eth_dev); + + return 0; +@@ -5761,19 +5781,102 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) + return ret; + } + +-static int +-hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) ++static void ++hns3_get_autoneg_rxtx_pause_copper(struct hns3_hw *hw, bool *rx_pause, ++ bool *tx_pause) ++{ ++ struct hns3_mac *mac = &hw->mac; ++ uint32_t advertising = mac->advertising; ++ uint32_t lp_advertising = mac->lp_advertising; ++ *rx_pause = false; ++ *tx_pause = false; ++ ++ if (advertising & lp_advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) { ++ *rx_pause = true; ++ *tx_pause = true; ++ } else if (advertising & lp_advertising & ++ HNS3_PHY_LINK_MODE_ASYM_PAUSE_BIT) { ++ if (advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) ++ *rx_pause = true; ++ else if (lp_advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) ++ *tx_pause = true; ++ } ++} ++ ++static enum hns3_fc_mode ++hns3_get_autoneg_fc_mode(struct hns3_hw *hw) ++{ ++ enum hns3_fc_mode current_mode; ++ bool rx_pause = false; ++ bool tx_pause = false; ++ ++ switch (hw->mac.media_type) { ++ case HNS3_MEDIA_TYPE_COPPER: ++ hns3_get_autoneg_rxtx_pause_copper(hw, &rx_pause, &tx_pause); ++ break; ++ ++ /* ++ * Flow control auto-negotiation is not supported for fiber and ++ * backpalne media type. ++ */ ++ case HNS3_MEDIA_TYPE_FIBER: ++ case HNS3_MEDIA_TYPE_BACKPLANE: ++ hns3_err(hw, "autoneg FC mode can't be obtained, but flow control auto-negotiation is enabled."); ++ current_mode = hw->requested_fc_mode; ++ goto out; ++ default: ++ hns3_err(hw, "autoneg FC mode can't be obtained for unknown media type(%u).", ++ hw->mac.media_type); ++ current_mode = HNS3_FC_NONE; ++ goto out; ++ } ++ ++ if (rx_pause && tx_pause) ++ current_mode = HNS3_FC_FULL; ++ else if (rx_pause) ++ current_mode = HNS3_FC_RX_PAUSE; ++ else if (tx_pause) ++ current_mode = HNS3_FC_TX_PAUSE; ++ else ++ current_mode = HNS3_FC_NONE; ++ ++out: ++ return current_mode; ++} ++ ++static enum hns3_fc_mode ++hns3_get_current_fc_mode(struct rte_eth_dev *dev) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_mac *mac = &hw->mac; + +- fc_conf->pause_time = pf->pause_time; ++ /* ++ * When the flow control mode is obtained, the device may not complete ++ * auto-negotiation. It is necessary to wait for link establishment. ++ */ ++ (void)hns3_dev_link_update(dev, 1); + + /* +- * If fc auto-negotiation is not supported, the configured fc mode +- * from user is the current fc mode. ++ * If the link auto-negotiation of the nic is disabled, or the flow ++ * control auto-negotiation is not supported, the forced flow control ++ * mode is used. + */ +- switch (hw->requested_fc_mode) { ++ if (mac->link_autoneg == 0 || !pf->support_fc_autoneg) ++ return hw->requested_fc_mode; ++ ++ return hns3_get_autoneg_fc_mode(hw); ++} ++ ++static int ++hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ enum hns3_fc_mode current_mode; ++ ++ current_mode = hns3_get_current_fc_mode(dev); ++ switch (current_mode) { + case HNS3_FC_FULL: + fc_conf->mode = RTE_FC_FULL; + break; +@@ -5789,6 +5892,9 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + break; + } + ++ fc_conf->pause_time = pf->pause_time; ++ fc_conf->autoneg = pf->support_fc_autoneg ? hw->mac.link_autoneg : 0; ++ + return 0; + } + +@@ -5817,6 +5923,41 @@ hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) + } + + static int ++hns3_check_fc_autoneg_valid(struct hns3_hw *hw, uint8_t autoneg) ++{ ++ struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); ++ ++ if (!pf->support_fc_autoneg) { ++ if (autoneg != 0) { ++ hns3_err(hw, "unsupported fc auto-negotiation setting."); ++ return -EOPNOTSUPP; ++ } ++ ++ /* ++ * Flow control auto-negotiation of the NIC is not supported, ++ * but other auto-negotiation features may be supported. ++ */ ++ if (autoneg != hw->mac.link_autoneg) { ++ hns3_err(hw, "please use 'link_speeds' in struct rte_eth_conf to disable autoneg!"); ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++ } ++ ++ /* ++ * If flow control auto-negotiation of the NIC is supported, all ++ * auto-negotiation features are supported. ++ */ ++ if (autoneg != hw->mac.link_autoneg) { ++ hns3_err(hw, "please use 'link_speeds' in struct rte_eth_conf to change autoneg!"); ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int + hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +@@ -5831,10 +5972,11 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + fc_conf->send_xon, fc_conf->mac_ctrl_frame_fwd); + return -EINVAL; + } +- if (fc_conf->autoneg) { +- hns3_err(hw, "Unsupported fc auto-negotiation setting."); +- return -EINVAL; +- } ++ ++ ret = hns3_check_fc_autoneg_valid(hw, fc_conf->autoneg); ++ if (ret) ++ return ret; ++ + if (!fc_conf->pause_time) { + hns3_err(hw, "Invalid pause time %u setting.", + fc_conf->pause_time); +-- +2.7.4 + diff --git a/0116-net-hns3-support-fixed-link-speed.patch b/0116-net-hns3-support-fixed-link-speed.patch new file mode 100644 index 0000000..47e3ab6 --- /dev/null +++ b/0116-net-hns3-support-fixed-link-speed.patch @@ -0,0 +1,204 @@ +From 50d4bb519096de30035d48d3a8a2246bd4b09469 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Tue, 13 Apr 2021 21:47:19 +0800 +Subject: [PATCH 116/189] net/hns3: support fixed link speed + +This patch adds the configuration of fixed speed for the PF device. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 144 ++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 135 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 1ee1651..1d09b5b 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2473,12 +2473,6 @@ hns3_dev_configure(struct rte_eth_dev *dev) + } + + hw->adapter_state = HNS3_NIC_CONFIGURING; +- if (conf->link_speeds & ETH_LINK_SPEED_FIXED) { +- hns3_err(hw, "setting link speed/duplex not supported"); +- ret = -EINVAL; +- goto cfg_err; +- } +- + if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) { + ret = hns3_check_dcb_cfg(dev); + if (ret) +@@ -5271,6 +5265,130 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) + hw->io_base = NULL; + } + ++static uint32_t ++hns3_convert_link_speeds2bitmap_copper(uint32_t link_speeds) ++{ ++ uint32_t speed_bit; ++ ++ switch (link_speeds & ~ETH_LINK_SPEED_FIXED) { ++ case ETH_LINK_SPEED_10M: ++ speed_bit = HNS3_PHY_LINK_SPEED_10M_BIT; ++ break; ++ case ETH_LINK_SPEED_10M_HD: ++ speed_bit = HNS3_PHY_LINK_SPEED_10M_HD_BIT; ++ break; ++ case ETH_LINK_SPEED_100M: ++ speed_bit = HNS3_PHY_LINK_SPEED_100M_BIT; ++ break; ++ case ETH_LINK_SPEED_100M_HD: ++ speed_bit = HNS3_PHY_LINK_SPEED_100M_HD_BIT; ++ break; ++ case ETH_LINK_SPEED_1G: ++ speed_bit = HNS3_PHY_LINK_SPEED_1000M_BIT; ++ break; ++ default: ++ speed_bit = 0; ++ break; ++ } ++ ++ return speed_bit; ++} ++ ++static uint32_t ++hns3_convert_link_speeds2bitmap_fiber(uint32_t link_speeds) ++{ ++ uint32_t speed_bit; ++ ++ switch (link_speeds & ~ETH_LINK_SPEED_FIXED) { ++ case ETH_LINK_SPEED_1G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_1G_BIT; ++ break; ++ case ETH_LINK_SPEED_10G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_10G_BIT; ++ break; ++ case ETH_LINK_SPEED_25G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_25G_BIT; ++ break; ++ case ETH_LINK_SPEED_40G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_40G_BIT; ++ break; ++ case ETH_LINK_SPEED_50G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_50G_BIT; ++ break; ++ case ETH_LINK_SPEED_100G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_100G_BIT; ++ break; ++ case ETH_LINK_SPEED_200G: ++ speed_bit = HNS3_FIBER_LINK_SPEED_200G_BIT; ++ break; ++ default: ++ speed_bit = 0; ++ break; ++ } ++ ++ return speed_bit; ++} ++ ++static int ++hns3_check_port_speed(struct hns3_hw *hw, uint32_t link_speeds) ++{ ++ struct hns3_mac *mac = &hw->mac; ++ uint32_t supported_speed = mac->supported_speed; ++ uint32_t speed_bit = 0; ++ ++ if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) ++ speed_bit = hns3_convert_link_speeds2bitmap_copper(link_speeds); ++ else if (mac->media_type == HNS3_MEDIA_TYPE_FIBER) ++ speed_bit = hns3_convert_link_speeds2bitmap_fiber(link_speeds); ++ ++ if (!(speed_bit & supported_speed)) { ++ hns3_err(hw, "link_speeds(0x%x) exceeds the supported speed capability or is incorrect.", ++ link_speeds); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static inline uint32_t ++hns3_get_link_speed(uint32_t link_speeds) ++{ ++ uint32_t speed = ETH_SPEED_NUM_NONE; ++ ++ if (link_speeds & ETH_LINK_SPEED_10M || ++ link_speeds & ETH_LINK_SPEED_10M_HD) ++ speed = ETH_SPEED_NUM_10M; ++ if (link_speeds & ETH_LINK_SPEED_100M || ++ link_speeds & ETH_LINK_SPEED_100M_HD) ++ speed = ETH_SPEED_NUM_100M; ++ if (link_speeds & ETH_LINK_SPEED_1G) ++ speed = ETH_SPEED_NUM_1G; ++ if (link_speeds & ETH_LINK_SPEED_10G) ++ speed = ETH_SPEED_NUM_10G; ++ if (link_speeds & ETH_LINK_SPEED_25G) ++ speed = ETH_SPEED_NUM_25G; ++ if (link_speeds & ETH_LINK_SPEED_40G) ++ speed = ETH_SPEED_NUM_40G; ++ if (link_speeds & ETH_LINK_SPEED_50G) ++ speed = ETH_SPEED_NUM_50G; ++ if (link_speeds & ETH_LINK_SPEED_100G) ++ speed = ETH_SPEED_NUM_100G; ++ if (link_speeds & ETH_LINK_SPEED_200G) ++ speed = ETH_SPEED_NUM_200G; ++ ++ return speed; ++} ++ ++static uint8_t ++hns3_get_link_duplex(uint32_t link_speeds) ++{ ++ if ((link_speeds & ETH_LINK_SPEED_10M_HD) || ++ (link_speeds & ETH_LINK_SPEED_100M_HD)) ++ return ETH_LINK_HALF_DUPLEX; ++ else ++ return ETH_LINK_FULL_DUPLEX; ++} ++ + static int + hns3_set_copper_port_link_speed(struct hns3_hw *hw, + struct hns3_set_link_speed_cfg *cfg) +@@ -5298,6 +5416,9 @@ hns3_set_copper_port_link_speed(struct hns3_hw *hw, + HNS3_PHY_LINK_SPEED_100M_BIT | + HNS3_PHY_LINK_SPEED_100M_HD_BIT | + HNS3_PHY_LINK_SPEED_1000M_BIT; ++ } else { ++ req->speed = cfg->speed; ++ req->duplex = cfg->duplex; + } + + return hns3_cmd_send(hw, desc, HNS3_PHY_PARAM_CFG_BD_NUM); +@@ -5358,7 +5479,7 @@ hns3_set_fiber_port_link_speed(struct hns3_hw *hw, + return 0; + } + +- return 0; ++ return hns3_cfg_mac_speed_dup(hw, cfg->speed, cfg->duplex); + } + + static int +@@ -5397,13 +5518,18 @@ hns3_apply_link_speed(struct hns3_hw *hw) + { + struct rte_eth_conf *conf = &hw->data->dev_conf; + struct hns3_set_link_speed_cfg cfg; ++ int ret; + + memset(&cfg, 0, sizeof(struct hns3_set_link_speed_cfg)); + cfg.autoneg = (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) ? + ETH_LINK_AUTONEG : ETH_LINK_FIXED; + if (cfg.autoneg != ETH_LINK_AUTONEG) { +- hns3_err(hw, "device doesn't support to force link speed."); +- return -EOPNOTSUPP; ++ ret = hns3_check_port_speed(hw, conf->link_speeds); ++ if (ret) ++ return ret; ++ ++ cfg.speed = hns3_get_link_speed(conf->link_speeds); ++ cfg.duplex = hns3_get_link_duplex(conf->link_speeds); + } + + return hns3_set_port_link_speed(hw, &cfg); +-- +2.7.4 + diff --git a/0117-net-hns3-rename-Rx-burst-function.patch b/0117-net-hns3-rename-Rx-burst-function.patch new file mode 100644 index 0000000..58d4024 --- /dev/null +++ b/0117-net-hns3-rename-Rx-burst-function.patch @@ -0,0 +1,106 @@ +From a9baef6c5022ca2b1c78822076ea7a00a1fe4733 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 15 Apr 2021 16:35:21 +0800 +Subject: [PATCH 117/189] net/hns3: rename Rx burst function + +Currently, user could use runtime config "rx_func_hint=simple" to +select the hns3_recv_pkts API, but the API's name get from +rte_eth_rx_burst_mode_get is "Scalar" which has not reflected "simple". + +So this patch renames hns3_recv_pkts to hns3_recv_pkts_simple, and +also change it's name which gets from rte_eth_rx_burst_mode_get to +"Scalar Simple" to maintain conceptual consistency. + +Fixes: 521ab3e93361 ("net/hns3: add simple Rx path") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +Acked-by: Ferruh Yigit +--- + drivers/net/hns3/hns3_rxtx.c | 18 ++++++++++-------- + drivers/net/hns3/hns3_rxtx.h | 4 ++-- + 2 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 43f8c64..4873c9c 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2017,7 +2017,7 @@ hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev) + }; + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + +- if (dev->rx_pkt_burst == hns3_recv_pkts || ++ if (dev->rx_pkt_burst == hns3_recv_pkts_simple || + dev->rx_pkt_burst == hns3_recv_scattered_pkts || + dev->rx_pkt_burst == hns3_recv_pkts_vec || + dev->rx_pkt_burst == hns3_recv_pkts_vec_sve) { +@@ -2389,7 +2389,9 @@ hns3_rx_ptp_timestamp_handle(struct hns3_rx_queue *rxq, struct rte_mbuf *mbuf, + } + + uint16_t +-hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) ++hns3_recv_pkts_simple(void *rx_queue, ++ struct rte_mbuf **rx_pkts, ++ uint16_t nb_pkts) + { + volatile struct hns3_desc *rx_ring; /* RX ring (desc) */ + volatile struct hns3_desc *rxdp; /* pointer of the current desc */ +@@ -2772,10 +2774,10 @@ hns3_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, + eth_rx_burst_t pkt_burst; + const char *info; + } burst_infos[] = { +- { hns3_recv_pkts, "Scalar" }, ++ { hns3_recv_pkts_simple, "Scalar Simple" }, + { hns3_recv_scattered_pkts, "Scalar Scattered" }, +- { hns3_recv_pkts_vec, "Vector Neon" }, +- { hns3_recv_pkts_vec_sve, "Vector Sve" }, ++ { hns3_recv_pkts_vec, "Vector Neon" }, ++ { hns3_recv_pkts_vec_sve, "Vector Sve" }, + }; + + eth_rx_burst_t pkt_burst = dev->rx_pkt_burst; +@@ -2833,14 +2835,14 @@ hns3_get_rx_function(struct rte_eth_dev *dev) + if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_SVE && sve_allowed) + return hns3_recv_pkts_vec_sve; + if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed) +- return hns3_recv_pkts; ++ return hns3_recv_pkts_simple; + if (hns->rx_func_hint == HNS3_IO_FUNC_HINT_COMMON) + return hns3_recv_scattered_pkts; + + if (vec_allowed) + return hns3_recv_pkts_vec; + if (simple_allowed) +- return hns3_recv_pkts; ++ return hns3_recv_pkts_simple; + + return hns3_recv_scattered_pkts; + } +@@ -4517,7 +4519,7 @@ hns3_dev_rx_descriptor_status(void *rx_queue, uint16_t offset) + rxdp = &rxq->rx_ring[desc_id]; + bd_base_info = rte_le_to_cpu_32(rxdp->rx.bd_base_info); + dev = &rte_eth_devices[rxq->port_id]; +- if (dev->rx_pkt_burst == hns3_recv_pkts || ++ if (dev->rx_pkt_burst == hns3_recv_pkts_simple || + dev->rx_pkt_burst == hns3_recv_scattered_pkts) { + if (offset >= rxq->nb_rx_desc - rxq->rx_free_hold) + return RTE_ETH_RX_DESC_UNAVAIL; +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 44d0ca7..5067c92 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -683,8 +683,8 @@ int hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id); + int hns3_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id); + int hns3_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id); + int hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id); +-uint16_t hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +- uint16_t nb_pkts); ++uint16_t hns3_recv_pkts_simple(void *rx_queue, struct rte_mbuf **rx_pkts, ++ uint16_t nb_pkts); + uint16_t hns3_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, + uint16_t nb_pkts); + uint16_t hns3_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +-- +2.7.4 + diff --git a/0118-net-hns3-remove-unused-macros.patch b/0118-net-hns3-remove-unused-macros.patch new file mode 100644 index 0000000..b0c5645 --- /dev/null +++ b/0118-net-hns3-remove-unused-macros.patch @@ -0,0 +1,34 @@ +From 9db649c5eb45a4739fc76e5613b8d5c5cd9f9275 Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Mon, 19 Apr 2021 16:13:31 +0800 +Subject: [PATCH 118/189] net/hns3: remove unused macros + +'HNS3_RXD_TSIND_S' and 'HNS3_RXD_TSIND_M' is unused, which should +be deleted. + +This patch fixed it. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 5067c92..d25edc4 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -104,8 +104,6 @@ + #define HNS3_RXD_LUM_B 9 + #define HNS3_RXD_CRCP_B 10 + #define HNS3_RXD_L3L4P_B 11 +-#define HNS3_RXD_TSIND_S 12 +-#define HNS3_RXD_TSIND_M (0x7 << HNS3_RXD_TSIND_S) + + #define HNS3_RXD_TS_VLD_B 14 + #define HNS3_RXD_LKBK_B 15 +-- +2.7.4 + diff --git a/0119-net-hns3-support-RAS-process-in-Kunpeng-930.patch b/0119-net-hns3-support-RAS-process-in-Kunpeng-930.patch new file mode 100644 index 0000000..fdeb45f --- /dev/null +++ b/0119-net-hns3-support-RAS-process-in-Kunpeng-930.patch @@ -0,0 +1,603 @@ +From 9a12486ffd05e3940cd533ac5ba03ba641c864f2 Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Mon, 19 Apr 2021 15:36:44 +0800 +Subject: [PATCH 119/189] net/hns3: support RAS process in Kunpeng 930 + +Kunpeng 930 uses a new RAS exception reporting solution. +The reset type and exception status are reported through +firmware. The driver modifies the corresponding code to +adapt to the new solution. + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 9 +- + drivers/net/hns3/hns3_cmd.h | 2 + + drivers/net/hns3/hns3_ethdev.c | 11 +- + drivers/net/hns3/hns3_ethdev.h | 23 ++- + drivers/net/hns3/hns3_ethdev_vf.c | 3 +- + drivers/net/hns3/hns3_intr.c | 296 +++++++++++++++++++++++++++++++++++++- + drivers/net/hns3/hns3_intr.h | 70 +++++++++ + 7 files changed, 399 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 15bf781..f3588ab 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -237,7 +237,12 @@ hns3_is_special_opcode(uint16_t opcode) + HNS3_OPC_STATS_MAC, + HNS3_OPC_STATS_MAC_ALL, + HNS3_OPC_QUERY_32_BIT_REG, +- HNS3_OPC_QUERY_64_BIT_REG}; ++ HNS3_OPC_QUERY_64_BIT_REG, ++ HNS3_OPC_QUERY_CLEAR_MPF_RAS_INT, ++ HNS3_OPC_QUERY_CLEAR_PF_RAS_INT, ++ HNS3_OPC_QUERY_CLEAR_ALL_MPF_MSIX_INT, ++ HNS3_OPC_QUERY_CLEAR_ALL_PF_MSIX_INT, ++ HNS3_OPC_QUERY_ALL_ERR_INFO,}; + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(spec_opcode); i++) +@@ -449,6 +454,8 @@ hns3_parse_capability(struct hns3_hw *hw, + if (hns3_get_bit(caps, HNS3_CAPS_UDP_TUNNEL_CSUM_B)) + hns3_set_bit(hw->capability, + HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, 1); ++ if (hns3_get_bit(caps, HNS3_CAPS_RAS_IMP_B)) ++ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_RAS_IMP_B, 1); + } + + static uint32_t +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index a24063b..70aed7b 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -252,6 +252,8 @@ enum hns3_opcode_type { + HNS3_OPC_QUERY_MSIX_INT_STS_BD_NUM = 0x1513, + HNS3_OPC_QUERY_CLEAR_ALL_MPF_MSIX_INT = 0x1514, + HNS3_OPC_QUERY_CLEAR_ALL_PF_MSIX_INT = 0x1515, ++ HNS3_OPC_QUERY_ALL_ERR_BD_NUM = 0x1516, ++ HNS3_OPC_QUERY_ALL_ERR_INFO = 0x1517, + HNS3_OPC_IGU_EGU_TNL_INT_EN = 0x1803, + HNS3_OPC_IGU_COMMON_INT_EN = 0x1806, + HNS3_OPC_TM_QCN_MEM_INT_CFG = 0x1A14, +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 1d09b5b..893b357 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -324,10 +324,8 @@ hns3_interrupt_handler(void *param) + hns3_warn(hw, "received interrupt: vector0_int_stat:0x%x " + "ras_int_stat:0x%x cmdq_int_stat:0x%x", + vector0_int, ras_int, cmdq_int); +- hns3_handle_msix_error(hns, &hw->reset.request); +- hns3_handle_ras_error(hns, &hw->reset.request); + hns3_handle_mac_tnl(hw); +- hns3_schedule_reset(hns); ++ hns3_handle_error(hns); + } else if (event_cause == HNS3_VECTOR0_EVENT_RST) { + hns3_warn(hw, "received reset interrupt"); + hns3_schedule_reset(hns); +@@ -6284,12 +6282,15 @@ hns3_is_reset_pending(struct hns3_adapter *hns) + + hns3_check_event_cause(hns, NULL); + reset = hns3_get_reset_level(hns, &hw->reset.pending); +- if (hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { ++ ++ if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET && ++ hw->reset.level < reset) { + hns3_warn(hw, "High level reset %d is pending", reset); + return true; + } + reset = hns3_get_reset_level(hns, &hw->reset.request); +- if (hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { ++ if (reset != HNS3_NONE_RESET && hw->reset.level != HNS3_NONE_RESET && ++ hw->reset.level < reset) { + hns3_warn(hw, "High level reset %d is request", reset); + return true; + } +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 8b6c0d2..4a855de 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -306,8 +306,9 @@ enum hns3_reset_stage { + }; + + enum hns3_reset_level { +- HNS3_NONE_RESET, ++ HNS3_FLR_RESET, /* A VF perform FLR reset */ + HNS3_VF_FUNC_RESET, /* A VF function reset */ ++ + /* + * All VFs under a PF perform function reset. + * Kernel PF driver use mailbox to inform DPDK VF to do reset, the value +@@ -315,6 +316,7 @@ enum hns3_reset_level { + * same. + */ + HNS3_VF_PF_FUNC_RESET = 2, ++ + /* + * All VFs under a PF perform FLR reset. + * Kernel PF driver use mailbox to inform DPDK VF to do reset, the value +@@ -328,14 +330,23 @@ enum hns3_reset_level { + * In PF FLR, the register state of VF is not reliable, VF's driver + * should not access the registers of the VF device. + */ +- HNS3_VF_FULL_RESET = 3, +- HNS3_FLR_RESET, /* A VF perform FLR reset */ ++ HNS3_VF_FULL_RESET, ++ + /* All VFs under the rootport perform a global or IMP reset */ + HNS3_VF_RESET, +- HNS3_FUNC_RESET, /* A PF function reset */ ++ ++ /* ++ * The enumeration value of HNS3_FUNC_RESET/HNS3_GLOBAL_RESET/ ++ * HNS3_IMP_RESET/HNS3_NONE_RESET are also used by firmware, and ++ * can not be changed. ++ */ ++ ++ HNS3_FUNC_RESET = 5, /* A PF function reset */ ++ + /* All PFs under the rootport perform a global reset */ + HNS3_GLOBAL_RESET, + HNS3_IMP_RESET, /* All PFs under the rootport perform a IMP reset */ ++ HNS3_NONE_RESET, + HNS3_MAX_RESET + }; + +@@ -846,6 +857,7 @@ enum { + #define HNS3_DEV_SUPPORT_STASH_B 0x7 + #define HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B 0x9 + #define HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B 0xA ++#define HNS3_DEV_SUPPORT_RAS_IMP_B 0xB + + #define hns3_dev_dcb_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B) +@@ -882,6 +894,9 @@ enum { + #define hns3_dev_outer_udp_cksum_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B) + ++#define hns3_dev_ras_imp_supported(hw) \ ++ hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_RAS_IMP_B) ++ + #define HNS3_DEV_PRIVATE_TO_HW(adapter) \ + (&((struct hns3_adapter *)adapter)->hw) + #define HNS3_DEV_PRIVATE_TO_PF(adapter) \ +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index dd8f248..efc614b 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2465,7 +2465,8 @@ hns3vf_is_reset_pending(struct hns3_adapter *hns) + /* Check the registers to confirm whether there is reset pending */ + hns3vf_check_event_cause(hns, NULL); + reset = hns3vf_get_reset_level(hw, &hw->reset.pending); +- if (hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { ++ if (hw->reset.level != HNS3_NONE_RESET && reset != HNS3_NONE_RESET && ++ hw->reset.level < reset) { + hns3_warn(hw, "High level reset %d is pending", reset); + return true; + } +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index ccc90c5..7385c7b 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -23,8 +23,8 @@ + } while (0) + + static const char *reset_string[HNS3_MAX_RESET] = { +- "none", "vf_func", "vf_pf_func", "vf_full", "flr", +- "vf_global", "pf_func", "global", "IMP", ++ "flr", "vf_func", "vf_pf_func", "vf_full", "vf_global", ++ "pf_func", "global", "IMP", "none", + }; + + static const struct hns3_hw_error mac_afifo_tnl_int[] = { +@@ -1384,13 +1384,108 @@ static const struct hns3_hw_error_desc pf_msix_err_tbl[] = { + } + }; + +-enum hns3_hw_err_type { ++enum hns3_hw_err_report_type { + MPF_MSIX_ERR, + PF_MSIX_ERR, + MPF_RAS_ERR, + PF_RAS_ERR, + }; + ++static const struct hns3_hw_mod_name hns3_hw_module_name[] = { ++ { ++ .module_name = MODULE_NONE, ++ .msg = "MODULE_NONE" ++ }, { ++ .module_name = MODULE_BIOS_COMMON, ++ .msg = "MODULE_BIOS_COMMON" ++ }, { ++ .module_name = MODULE_GE, ++ .msg = "MODULE_GE" ++ }, { ++ .module_name = MODULE_IGU_EGU, ++ .msg = "MODULE_IGU_EGU" ++ }, { ++ .module_name = MODULE_LGE, ++ .msg = "MODULE_LGE" ++ }, { ++ .module_name = MODULE_NCSI, ++ .msg = "MODULE_NCSI" ++ }, { ++ .module_name = MODULE_PPP, ++ .msg = "MODULE_PPP" ++ }, { ++ .module_name = MODULE_QCN, ++ .msg = "MODULE_QCN" ++ }, { ++ .module_name = MODULE_RCB_RX, ++ .msg = "MODULE_RCB_RX" ++ }, { ++ .module_name = MODULE_RTC, ++ .msg = "MODULE_RTC" ++ }, { ++ .module_name = MODULE_SSU, ++ .msg = "MODULE_SSU" ++ }, { ++ .module_name = MODULE_TM, ++ .msg = "MODULE_TM" ++ }, { ++ .module_name = MODULE_RCB_TX, ++ .msg = "MODULE_RCB_TX" ++ }, { ++ .module_name = MODULE_TXDMA, ++ .msg = "MODULE_TXDMA" ++ }, { ++ .module_name = MODULE_MASTER, ++ .msg = "MODULE_MASTER" ++ }, { ++ .module_name = MODULE_ROH_MAC, ++ .msg = "MODULE_ROH_MAC" ++ } ++}; ++ ++static const struct hns3_hw_err_type hns3_hw_error_type[] = { ++ { ++ .error_type = NONE_ERROR, ++ .msg = "none_error" ++ }, { ++ .error_type = FIFO_ERROR, ++ .msg = "fifo_error" ++ }, { ++ .error_type = MEMORY_ERROR, ++ .msg = "memory_error" ++ }, { ++ .error_type = POISION_ERROR, ++ .msg = "poision_error" ++ }, { ++ .error_type = MSIX_ECC_ERROR, ++ .msg = "msix_ecc_error" ++ }, { ++ .error_type = TQP_INT_ECC_ERROR, ++ .msg = "tqp_int_ecc_error" ++ }, { ++ .error_type = PF_ABNORMAL_INT_ERROR, ++ .msg = "pf_abnormal_int_error" ++ }, { ++ .error_type = MPF_ABNORMAL_INT_ERROR, ++ .msg = "mpf_abnormal_int_error" ++ }, { ++ .error_type = COMMON_ERROR, ++ .msg = "common_error" ++ }, { ++ .error_type = PORT_ERROR, ++ .msg = "port_error" ++ }, { ++ .error_type = ETS_ERROR, ++ .msg = "ets_error" ++ }, { ++ .error_type = NCSI_ERROR, ++ .msg = "ncsi_error" ++ }, { ++ .error_type = GLB_ERROR, ++ .msg = "glb_error" ++ } ++}; ++ + static int + hns3_config_ncsi_hw_err_int(struct hns3_adapter *hns, bool en) + { +@@ -1927,7 +2022,8 @@ hns3_get_hw_error_status(struct hns3_cmd_desc *desc, uint8_t desc_offset, + + static int + hns3_handle_hw_error(struct hns3_adapter *hns, struct hns3_cmd_desc *desc, +- int num, uint64_t *levels, enum hns3_hw_err_type err_type) ++ int num, uint64_t *levels, ++ enum hns3_hw_err_report_type err_type) + { + const struct hns3_hw_error_desc *err = pf_ras_err_tbl; + enum hns3_opcode_type opcode; +@@ -2094,6 +2190,198 @@ hns3_handle_ras_error(struct hns3_adapter *hns, uint64_t *levels) + rte_free(desc); + } + ++static void ++hns3_handle_type_reg_error_data(struct hns3_hw *hw, ++ struct hns3_mod_err_info *mod_err_info, ++ struct hns3_type_reg_err_info *err_info) ++{ ++#define HNS3_ERR_TYPE_MASK 0x7F ++#define HNS3_ERR_TYPE_IS_RAS_OFFSET 7 ++ ++ uint8_t mod_id, total_module, type_id, total_type; ++ uint8_t is_ras; ++ uint8_t i; ++ ++ mod_id = mod_err_info->mod_id; ++ type_id = err_info->type_id & HNS3_ERR_TYPE_MASK; ++ is_ras = err_info->type_id >> HNS3_ERR_TYPE_IS_RAS_OFFSET; ++ ++ total_module = ARRAY_SIZE(hns3_hw_module_name); ++ total_type = ARRAY_SIZE(hns3_hw_error_type); ++ ++ hns3_err(hw, "total_module:%u, total_type:%u", ++ total_module, total_type); ++ ++ if (mod_id < total_module && type_id < total_type) ++ hns3_err(hw, "found %s %s, is %s error.", ++ hns3_hw_module_name[mod_id].msg, ++ hns3_hw_error_type[type_id].msg, ++ is_ras ? "ras" : "msix"); ++ else ++ hns3_err(hw, "unknown module[%u] or type[%u].", ++ mod_id, type_id); ++ ++ hns3_err(hw, "reg_value:"); ++ for (i = 0; i < err_info->reg_num; i++) ++ hns3_err(hw, "0x%08x", err_info->reg[i]); ++} ++ ++static void ++hns3_handle_module_error_data(struct hns3_hw *hw, uint32_t *buf, ++ uint32_t buf_size) ++{ ++ struct hns3_type_reg_err_info *type_reg_err_info; ++ struct hns3_mod_err_info *mod_err_info; ++ struct hns3_sum_err_info *sum_err_info; ++ uint8_t mod_num, reset_type; ++ uint32_t offset = 0; ++ uint8_t err_num; ++ uint8_t i; ++ ++ sum_err_info = (struct hns3_sum_err_info *)&buf[offset++]; ++ mod_num = sum_err_info->mod_num; ++ reset_type = sum_err_info->reset_type; ++ if (reset_type && reset_type != HNS3_NONE_RESET) ++ hns3_atomic_set_bit(reset_type, &hw->reset.request); ++ ++ hns3_err(hw, "reset_type = %s, mod_num = %u.", ++ reset_string[reset_type], mod_num); ++ ++ while (mod_num--) { ++ if (offset >= buf_size) { ++ hns3_err(hw, "offset(%u) exceeds buf's size(%u).", ++ offset, buf_size); ++ return; ++ } ++ mod_err_info = (struct hns3_mod_err_info *)&buf[offset++]; ++ err_num = mod_err_info->err_num; ++ for (i = 0; i < err_num; i++) { ++ if (offset >= buf_size) { ++ hns3_err(hw, ++ "offset(%u) exceeds buf size(%u).", ++ offset, buf_size); ++ return; ++ } ++ ++ type_reg_err_info = (struct hns3_type_reg_err_info *) ++ &buf[offset++]; ++ hns3_handle_type_reg_error_data(hw, mod_err_info, ++ type_reg_err_info); ++ ++ offset += type_reg_err_info->reg_num; ++ } ++ } ++} ++ ++static int ++hns3_query_all_err_bd_num(struct hns3_hw *hw, uint32_t *bd_num) ++{ ++ struct hns3_cmd_desc desc; ++ uint32_t bd_num_data; ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_ALL_ERR_BD_NUM, true); ++ ret = hns3_cmd_send(hw, &desc, 1); ++ if (ret) { ++ hns3_err(hw, "failed to query error bd_num, ret = %d.", ret); ++ return ret; ++ } ++ ++ bd_num_data = rte_le_to_cpu_32(desc.data[0]); ++ *bd_num = bd_num_data; ++ if (bd_num_data == 0) { ++ hns3_err(hw, "the value of bd_num is 0!"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_query_all_err_info(struct hns3_hw *hw, struct hns3_cmd_desc *desc, ++ uint32_t bd_num) ++{ ++ int ret; ++ ++ hns3_cmd_setup_basic_desc(desc, HNS3_OPC_QUERY_ALL_ERR_INFO, true); ++ ret = hns3_cmd_send(hw, desc, bd_num); ++ if (ret) { ++ hns3_err(hw, "failed to query error info, ret = %d.", ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static void ++hns3_handle_hw_error_v2(struct hns3_hw *hw) ++{ ++ uint32_t bd_num, buf_len, i, buf_size; ++ struct hns3_cmd_desc *desc; ++ uint32_t *desc_data; ++ uint32_t *buf; ++ int ret; ++ ++ ret = hns3_query_all_err_bd_num(hw, &bd_num); ++ if (ret) ++ goto out; ++ ++ desc = rte_zmalloc("hns3_ras", bd_num * sizeof(struct hns3_cmd_desc), ++ 0); ++ if (desc == NULL) { ++ hns3_err(hw, "failed to malloc hns3 ras cmd desc."); ++ goto out; ++ } ++ ++ ret = hns3_query_all_err_info(hw, desc, bd_num); ++ if (ret) ++ goto err_desc; ++ ++ buf_len = bd_num * sizeof(struct hns3_cmd_desc) - HNS3_DESC_NO_DATA_LEN; ++ buf_size = buf_len / HNS3_DESC_DATA_UNIT_SIZE; ++ ++ desc_data = rte_zmalloc("hns3_ras", buf_len, 0); ++ if (desc_data == NULL) { ++ hns3_err(hw, "failed to malloc hns3 ras desc data."); ++ goto err_desc; ++ } ++ ++ buf = rte_zmalloc("hns3_ras", buf_len, 0); ++ if (buf == NULL) { ++ hns3_err(hw, "failed to malloc hns3 ras buf data."); ++ goto err_buf_alloc; ++ } ++ ++ memcpy(desc_data, &desc[0].data[0], buf_len); ++ for (i = 0; i < buf_size; i++) ++ buf[i] = rte_le_to_cpu_32(desc_data[i]); ++ ++ hns3_handle_module_error_data(hw, buf, buf_size); ++ rte_free(buf); ++ ++err_buf_alloc: ++ rte_free(desc_data); ++err_desc: ++ rte_free(desc); ++out: ++ return; ++} ++ ++void ++hns3_handle_error(struct hns3_adapter *hns) ++{ ++ struct hns3_hw *hw = &hns->hw; ++ ++ if (hns3_dev_ras_imp_supported(hw)) { ++ hns3_handle_hw_error_v2(hw); ++ hns3_schedule_reset(hns); ++ } else { ++ hns3_handle_msix_error(hns, &hw->reset.request); ++ hns3_handle_ras_error(hns, &hw->reset.request); ++ hns3_schedule_reset(hns); ++ } ++} ++ + int + hns3_reset_init(struct hns3_hw *hw) + { +diff --git a/drivers/net/hns3/hns3_intr.h b/drivers/net/hns3/hns3_intr.h +index 4a0a731..a140ca1 100644 +--- a/drivers/net/hns3/hns3_intr.h ++++ b/drivers/net/hns3/hns3_intr.h +@@ -81,6 +81,75 @@ + + #define HNS3_RESET_PROCESS_MS 200 + ++#define HNS3_DESC_DATA_MAX 8 ++#define HNS3_REG_NUM_MAX 256 ++#define HNS3_DESC_NO_DATA_LEN 8 ++#define HNS3_DESC_DATA_UNIT_SIZE 4 ++ ++enum hns3_mod_name_list { ++ MODULE_NONE, ++ MODULE_BIOS_COMMON, ++ MODULE_GE, ++ MODULE_IGU_EGU, ++ MODULE_LGE, ++ MODULE_NCSI, ++ MODULE_PPP, ++ MODULE_QCN, ++ MODULE_RCB_RX, ++ MODULE_RTC, ++ MODULE_SSU, ++ MODULE_TM, ++ MODULE_RCB_TX, ++ MODULE_TXDMA, ++ MODULE_MASTER, ++ MODULE_ROH_MAC, ++}; ++ ++enum hns3_err_type_list { ++ NONE_ERROR, ++ FIFO_ERROR, ++ MEMORY_ERROR, ++ POISION_ERROR, ++ MSIX_ECC_ERROR, ++ TQP_INT_ECC_ERROR, ++ PF_ABNORMAL_INT_ERROR, ++ MPF_ABNORMAL_INT_ERROR, ++ COMMON_ERROR, ++ PORT_ERROR, ++ ETS_ERROR, ++ NCSI_ERROR, ++ GLB_ERROR, ++}; ++ ++struct hns3_hw_mod_name { ++ enum hns3_mod_name_list module_name; ++ const char *msg; ++}; ++ ++struct hns3_hw_err_type { ++ enum hns3_err_type_list error_type; ++ const char *msg; ++}; ++ ++struct hns3_sum_err_info { ++ uint8_t reset_type; /* the total reset type */ ++ uint8_t mod_num; /* the modules num encounter error */ ++ uint8_t rsv[2]; ++}; ++ ++struct hns3_mod_err_info { ++ uint8_t mod_id; /* the error module id */ ++ uint8_t err_num; /* the errors num in module */ ++ uint8_t rsv[2]; ++}; ++ ++struct hns3_type_reg_err_info { ++ uint8_t type_id; /* the type id of error */ ++ uint8_t reg_num; /* the related registers num of this error */ ++ uint8_t rsv[2]; ++ uint32_t reg[HNS3_REG_NUM_MAX]; /* the registers value */ ++}; ++ + struct hns3_hw_blk { + const char *name; + int (*enable_err_intr)(struct hns3_adapter *hns, bool en); +@@ -103,6 +172,7 @@ int hns3_enable_hw_error_intr(struct hns3_adapter *hns, bool state); + void hns3_handle_msix_error(struct hns3_adapter *hns, uint64_t *levels); + void hns3_handle_ras_error(struct hns3_adapter *hns, uint64_t *levels); + void hns3_config_mac_tnl_int(struct hns3_hw *hw, bool en); ++void hns3_handle_error(struct hns3_adapter *hns); + + void hns3_intr_unregister(const struct rte_intr_handle *hdl, + rte_intr_callback_fn cb_fn, void *cb_arg); +-- +2.7.4 + diff --git a/0120-net-hns3-support-masking-device-capability.patch b/0120-net-hns3-support-masking-device-capability.patch new file mode 100644 index 0000000..34899b4 --- /dev/null +++ b/0120-net-hns3-support-masking-device-capability.patch @@ -0,0 +1,226 @@ +From e0e251dbada5ce120c8f7a6d1b517865fcbc29ce Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 15 Apr 2021 11:52:00 +0800 +Subject: [PATCH 120/189] net/hns3: support masking device capability + +This patch supports runtime config of mask device capability, it was +used to mask the capability which queried from firmware. + +The device argument key is "dev_caps_mask" which takes hexadecimal +bitmask where each bit represents whether mask corresponding capability. + +Its main purpose is to debug and avoid problems. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + doc/guides/nics/hns3.rst | 9 ++++++ + drivers/net/hns3/hns3_cmd.c | 67 +++++++++++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_ethdev.c | 24 +++++++++++++- + drivers/net/hns3/hns3_ethdev.h | 4 +++ + drivers/net/hns3/hns3_ethdev_vf.c | 3 +- + 5 files changed, 105 insertions(+), 2 deletions(-) + +diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst +index d722509..477f03c 100644 +--- a/doc/guides/nics/hns3.rst ++++ b/doc/guides/nics/hns3.rst +@@ -84,6 +84,15 @@ Runtime Config Options + be first checked, if meets, use the ``vec``. Then, ``simple``, at last + ``common``. + ++- ``dev_caps_mask`` (default ``0``) ++ ++ Used to mask the capability which queried from firmware. ++ This args take hexadecimal bitmask where each bit represents whether mask ++ corresponding capability. eg. If the capability is 0xFFFF queried from ++ firmware, and the args value is 0xF which means the bit0~bit3 should be ++ masked off, then the capability will be 0xFFF0. ++ Its main purpose is to debug and avoid problems. ++ + Driver compilation and testing + ------------------------------ + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index f3588ab..5eb8789 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -416,6 +416,68 @@ hns3_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, int num) + return retval; + } + ++static const char * ++hns3_get_caps_name(uint32_t caps_id) ++{ ++ const struct { ++ enum HNS3_CAPS_BITS caps; ++ const char *name; ++ } dev_caps[] = { ++ { HNS3_CAPS_UDP_GSO_B, "udp_gso" }, ++ { HNS3_CAPS_ATR_B, "atr" }, ++ { HNS3_CAPS_FD_QUEUE_REGION_B, "fd_queue_region" }, ++ { HNS3_CAPS_PTP_B, "ptp" }, ++ { HNS3_CAPS_INT_QL_B, "int_ql" }, ++ { HNS3_CAPS_SIMPLE_BD_B, "simple_bd" }, ++ { HNS3_CAPS_TX_PUSH_B, "tx_push" }, ++ { HNS3_CAPS_PHY_IMP_B, "phy_imp" }, ++ { HNS3_CAPS_TQP_TXRX_INDEP_B, "tqp_txrx_indep" }, ++ { HNS3_CAPS_HW_PAD_B, "hw_pad" }, ++ { HNS3_CAPS_STASH_B, "stash" }, ++ { HNS3_CAPS_UDP_TUNNEL_CSUM_B, "udp_tunnel_csum" }, ++ { HNS3_CAPS_RAS_IMP_B, "ras_imp" }, ++ { HNS3_CAPS_FEC_B, "fec" }, ++ { HNS3_CAPS_PAUSE_B, "pause" }, ++ { HNS3_CAPS_RXD_ADV_LAYOUT_B, "rxd_adv_layout" } ++ }; ++ uint32_t i; ++ ++ for (i = 0; i < RTE_DIM(dev_caps); i++) { ++ if (dev_caps[i].caps == caps_id) ++ return dev_caps[i].name; ++ } ++ ++ return "unknown"; ++} ++ ++static void ++hns3_mask_capability(struct hns3_hw *hw, ++ struct hns3_query_version_cmd *cmd) ++{ ++#define MAX_CAPS_BIT 64 ++ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ uint64_t caps_org, caps_new, caps_masked; ++ uint32_t i; ++ ++ if (hns->dev_caps_mask == 0) ++ return; ++ ++ memcpy(&caps_org, &cmd->caps[0], sizeof(caps_org)); ++ caps_org = rte_le_to_cpu_64(caps_org); ++ caps_new = caps_org ^ (caps_org & hns->dev_caps_mask); ++ caps_masked = caps_org ^ caps_new; ++ caps_new = rte_cpu_to_le_64(caps_new); ++ memcpy(&cmd->caps[0], &caps_new, sizeof(caps_new)); ++ ++ for (i = 0; i < MAX_CAPS_BIT; i++) { ++ if (!(caps_masked & BIT_ULL(i))) ++ continue; ++ hns3_info(hw, "mask capabiliy: id-%u, name-%s.", ++ i, hns3_get_caps_name(i)); ++ } ++} ++ + static void + hns3_parse_capability(struct hns3_hw *hw, + struct hns3_query_version_cmd *cmd) +@@ -485,6 +547,11 @@ hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw) + return ret; + + hw->fw_version = rte_le_to_cpu_32(resp->firmware); ++ /* ++ * Make sure mask the capability before parse capability because it ++ * may overwrite resp's data. ++ */ ++ hns3_mask_capability(hw, resp); + hns3_parse_capability(hw, resp); + + return 0; +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 893b357..c75aa9c 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -7209,6 +7209,19 @@ hns3_get_io_hint_func_name(uint32_t hint) + } + } + ++static int ++hns3_parse_dev_caps_mask(const char *key, const char *value, void *extra_args) ++{ ++ uint64_t val; ++ ++ RTE_SET_USED(key); ++ ++ val = strtoull(value, NULL, 16); ++ *(uint64_t *)extra_args = val; ++ ++ return 0; ++} ++ + void + hns3_parse_devargs(struct rte_eth_dev *dev) + { +@@ -7216,6 +7229,7 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE; + uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE; + struct hns3_hw *hw = &hns->hw; ++ uint64_t dev_caps_mask = 0; + struct rte_kvargs *kvlist; + + if (dev->device->devargs == NULL) +@@ -7229,6 +7243,8 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + &hns3_parse_io_hint_func, &rx_func_hint); + rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT, + &hns3_parse_io_hint_func, &tx_func_hint); ++ rte_kvargs_process(kvlist, HNS3_DEVARG_DEV_CAPS_MASK, ++ &hns3_parse_dev_caps_mask, &dev_caps_mask); + rte_kvargs_free(kvlist); + + if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE) +@@ -7239,6 +7255,11 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT, + hns3_get_io_hint_func_name(tx_func_hint)); + hns->tx_func_hint = tx_func_hint; ++ ++ if (dev_caps_mask != 0) ++ hns3_warn(hw, "parsed %s = 0x%" PRIx64 ".", ++ HNS3_DEVARG_DEV_CAPS_MASK, dev_caps_mask); ++ hns->dev_caps_mask = dev_caps_mask; + } + + static const struct eth_dev_ops hns3_eth_dev_ops = { +@@ -7506,6 +7527,7 @@ RTE_PMD_REGISTER_PCI_TABLE(net_hns3, pci_id_hns3_map); + RTE_PMD_REGISTER_KMOD_DEP(net_hns3, "* igb_uio | vfio-pci"); + RTE_PMD_REGISTER_PARAM_STRING(net_hns3, + HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common " +- HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "); ++ HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common " ++ HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> "); + RTE_LOG_REGISTER(hns3_logtype_init, pmd.net.hns3.init, NOTICE); + RTE_LOG_REGISTER(hns3_logtype_driver, pmd.net.hns3.driver, NOTICE); +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 4a855de..271eadb 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -833,6 +833,8 @@ struct hns3_adapter { + uint32_t rx_func_hint; + uint32_t tx_func_hint; + ++ uint64_t dev_caps_mask; ++ + struct hns3_ptype_table ptype_tbl __rte_cache_min_aligned; + }; + +@@ -847,6 +849,8 @@ enum { + #define HNS3_DEVARG_RX_FUNC_HINT "rx_func_hint" + #define HNS3_DEVARG_TX_FUNC_HINT "tx_func_hint" + ++#define HNS3_DEVARG_DEV_CAPS_MASK "dev_caps_mask" ++ + #define HNS3_DEV_SUPPORT_DCB_B 0x0 + #define HNS3_DEV_SUPPORT_COPPER_B 0x1 + #define HNS3_DEV_SUPPORT_UDP_GSO_B 0x2 +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index efc614b..16cc111 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -3075,4 +3075,5 @@ RTE_PMD_REGISTER_PCI_TABLE(net_hns3_vf, pci_id_hns3vf_map); + RTE_PMD_REGISTER_KMOD_DEP(net_hns3_vf, "* igb_uio | vfio-pci"); + RTE_PMD_REGISTER_PARAM_STRING(net_hns3_vf, + HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common " +- HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "); ++ HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common " ++ HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> "); +-- +2.7.4 + diff --git a/0121-net-hns3-simplify-Rx-checksum.patch b/0121-net-hns3-simplify-Rx-checksum.patch new file mode 100644 index 0000000..1f1b83b --- /dev/null +++ b/0121-net-hns3-simplify-Rx-checksum.patch @@ -0,0 +1,302 @@ +From d31202d8067fd92a390fc67db148e45f2b719894 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 15 Apr 2021 11:52:01 +0800 +Subject: [PATCH 121/189] net/hns3: simplify Rx checksum + +Currently, the L3L4P/L3E/L4E/OL3E/OL4E fields in Rx descriptor used to +indicate hardware checksum result: +1. L3L4P: indicates hardware has processed L3L4 checksum for this + packet, if this bit is 1 then L3E/L4E/OL3E/OL4E is trustable. +2. L3E: L3 checksum error indication, 1 means with error. +3. L4E: L4 checksum error indication, 1 means with error. +4. OL3E: outer L3 checksum error indication, 1 means with error. +5. OL4E: outer L4 checksum error indication, 1 means with error. + +Driver will set the good checksum flag through packet type and +L3E/L4E/OL3E/OL4E when L3L4P is 1, it runs as follows: +1. If packet type indicates it's tunnel packet: +1.1. If packet type indicates it has inner L3 and L3E is zero, then +mark the IP checksum good. +1.2. If packet type indicates it has inner L4 and L4E is zero, then +mark the L4 checksum good. +1.3. If packet type indicates it has outer L4 and OL4E is zero, then +mark the outer L4 checksum good. +2. If packet type indicates it's not tunnel packet: +2.1. If packet type indicates it has L3 and L3E is zero, then mark the +IP checksum good. +2.2. If packet type indicates it has L4 and L4E is zero, then mark the +L4 checksum good. + +As described above, the good checksum calculation is time consuming, +it impacts the Rx performance. + +By balancing performance and functionality, driver uses the following +scheme to set good checksum flag when L3L4P is 1: +1. If L3E is zero, then mark the IP checksum good. +2. If L4E is zero, then mark the L4 checksum good. + +The performance gains are 3% in small packet iofwd scenarios. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 14 +---- + drivers/net/hns3/hns3_rxtx.h | 103 ++++++++++++++-------------------- + drivers/net/hns3/hns3_rxtx_vec_neon.h | 7 +-- + drivers/net/hns3/hns3_rxtx_vec_sve.c | 6 +- + 4 files changed, 45 insertions(+), 85 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 4873c9c..87416a1 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2402,7 +2402,6 @@ hns3_recv_pkts_simple(void *rx_queue, + struct rte_mbuf *nmb; /* pointer of the new mbuf */ + struct rte_mbuf *rxm; + uint32_t bd_base_info; +- uint32_t cksum_err; + uint32_t l234_info; + uint32_t ol_info; + uint64_t dma_addr; +@@ -2477,8 +2476,7 @@ hns3_recv_pkts_simple(void *rx_queue, + /* Load remained descriptor data and extract necessary fields */ + l234_info = rte_le_to_cpu_32(rxd.rx.l234_info); + ol_info = rte_le_to_cpu_32(rxd.rx.ol_info); +- ret = hns3_handle_bdinfo(rxq, rxm, bd_base_info, +- l234_info, &cksum_err); ++ ret = hns3_handle_bdinfo(rxq, rxm, bd_base_info, l234_info); + if (unlikely(ret)) + goto pkt_err; + +@@ -2487,9 +2485,6 @@ hns3_recv_pkts_simple(void *rx_queue, + if (rxm->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) + rxm->ol_flags |= PKT_RX_IEEE1588_PTP; + +- if (likely(bd_base_info & BIT(HNS3_RXD_L3L4P_B))) +- hns3_rx_set_cksum_flag(rxm, rxm->packet_type, +- cksum_err); + hns3_rxd_to_vlan_tci(rxq, rxm, l234_info, &rxd); + + /* Increment bytes counter */ +@@ -2528,7 +2523,6 @@ hns3_recv_scattered_pkts(void *rx_queue, + struct rte_mbuf *rxm; + struct rte_eth_dev *dev; + uint32_t bd_base_info; +- uint32_t cksum_err; + uint32_t l234_info; + uint32_t gro_size; + uint32_t ol_info; +@@ -2702,17 +2696,13 @@ hns3_recv_scattered_pkts(void *rx_queue, + l234_info = rte_le_to_cpu_32(rxd.rx.l234_info); + ol_info = rte_le_to_cpu_32(rxd.rx.ol_info); + ret = hns3_handle_bdinfo(rxq, first_seg, bd_base_info, +- l234_info, &cksum_err); ++ l234_info); + if (unlikely(ret)) + goto pkt_err; + + first_seg->packet_type = hns3_rx_calc_ptype(rxq, + l234_info, ol_info); + +- if (bd_base_info & BIT(HNS3_RXD_L3L4P_B)) +- hns3_rx_set_cksum_flag(first_seg, +- first_seg->packet_type, +- cksum_err); + hns3_rxd_to_vlan_tci(rxq, first_seg, l234_info, &rxd); + + /* Increment bytes counter */ +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index d25edc4..ac14802 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -539,19 +539,50 @@ enum hns3_cksum_status { + extern uint64_t hns3_timestamp_rx_dynflag; + extern int hns3_timestamp_dynfield_offset; + +-static inline int +-hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm, +- uint32_t bd_base_info, uint32_t l234_info, +- uint32_t *cksum_err) ++static inline void ++hns3_rx_set_cksum_flag(struct hns3_rx_queue *rxq, ++ struct rte_mbuf *rxm, ++ uint32_t l234_info) + { +-#define L2E_TRUNC_ERR_FLAG (BIT(HNS3_RXD_L2E_B) | \ +- BIT(HNS3_RXD_TRUNCATE_B)) +-#define CHECKSUM_ERR_FLAG (BIT(HNS3_RXD_L3E_B) | \ ++#define HNS3_RXD_CKSUM_ERR_MASK (BIT(HNS3_RXD_L3E_B) | \ + BIT(HNS3_RXD_L4E_B) | \ + BIT(HNS3_RXD_OL3E_B) | \ + BIT(HNS3_RXD_OL4E_B)) + +- uint32_t tmp = 0; ++ if (likely((l234_info & HNS3_RXD_CKSUM_ERR_MASK) == 0)) { ++ rxm->ol_flags |= (PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD); ++ return; ++ } ++ ++ if (unlikely(l234_info & BIT(HNS3_RXD_L3E_B))) { ++ rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD; ++ rxq->dfx_stats.l3_csum_errors++; ++ } else { ++ rxm->ol_flags |= PKT_RX_IP_CKSUM_GOOD; ++ } ++ ++ if (unlikely(l234_info & BIT(HNS3_RXD_L4E_B))) { ++ rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD; ++ rxq->dfx_stats.l4_csum_errors++; ++ } else { ++ rxm->ol_flags |= PKT_RX_L4_CKSUM_GOOD; ++ } ++ ++ if (unlikely(l234_info & BIT(HNS3_RXD_OL3E_B))) ++ rxq->dfx_stats.ol3_csum_errors++; ++ ++ if (unlikely(l234_info & BIT(HNS3_RXD_OL4E_B))) { ++ rxm->ol_flags |= PKT_RX_OUTER_L4_CKSUM_BAD; ++ rxq->dfx_stats.ol4_csum_errors++; ++ } ++} ++ ++static inline int ++hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm, ++ uint32_t bd_base_info, uint32_t l234_info) ++{ ++#define L2E_TRUNC_ERR_FLAG (BIT(HNS3_RXD_L2E_B) | \ ++ BIT(HNS3_RXD_TRUNCATE_B)) + + /* + * If packet len bigger than mtu when recv with no-scattered algorithm, +@@ -570,64 +601,12 @@ hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm, + return -EINVAL; + } + +- if (bd_base_info & BIT(HNS3_RXD_L3L4P_B)) { +- if (likely((l234_info & CHECKSUM_ERR_FLAG) == 0)) { +- *cksum_err = 0; +- return 0; +- } +- +- if (unlikely(l234_info & BIT(HNS3_RXD_L3E_B))) { +- rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD; +- rxq->dfx_stats.l3_csum_errors++; +- tmp |= HNS3_L3_CKSUM_ERR; +- } +- +- if (unlikely(l234_info & BIT(HNS3_RXD_L4E_B))) { +- rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD; +- rxq->dfx_stats.l4_csum_errors++; +- tmp |= HNS3_L4_CKSUM_ERR; +- } +- +- if (unlikely(l234_info & BIT(HNS3_RXD_OL3E_B))) { +- rxq->dfx_stats.ol3_csum_errors++; +- tmp |= HNS3_OUTER_L3_CKSUM_ERR; +- } +- +- if (unlikely(l234_info & BIT(HNS3_RXD_OL4E_B))) { +- rxm->ol_flags |= PKT_RX_OUTER_L4_CKSUM_BAD; +- rxq->dfx_stats.ol4_csum_errors++; +- tmp |= HNS3_OUTER_L4_CKSUM_ERR; +- } +- } +- *cksum_err = tmp; ++ if (bd_base_info & BIT(HNS3_RXD_L3L4P_B)) ++ hns3_rx_set_cksum_flag(rxq, rxm, l234_info); + + return 0; + } + +-static inline void +-hns3_rx_set_cksum_flag(struct rte_mbuf *rxm, const uint64_t packet_type, +- const uint32_t cksum_err) +-{ +- if (unlikely((packet_type & RTE_PTYPE_TUNNEL_MASK))) { +- if (likely(packet_type & RTE_PTYPE_INNER_L3_MASK) && +- (cksum_err & HNS3_L3_CKSUM_ERR) == 0) +- rxm->ol_flags |= PKT_RX_IP_CKSUM_GOOD; +- if (likely(packet_type & RTE_PTYPE_INNER_L4_MASK) && +- (cksum_err & HNS3_L4_CKSUM_ERR) == 0) +- rxm->ol_flags |= PKT_RX_L4_CKSUM_GOOD; +- if (likely(packet_type & RTE_PTYPE_L4_MASK) && +- (cksum_err & HNS3_OUTER_L4_CKSUM_ERR) == 0) +- rxm->ol_flags |= PKT_RX_OUTER_L4_CKSUM_GOOD; +- } else { +- if (likely(packet_type & RTE_PTYPE_L3_MASK) && +- (cksum_err & HNS3_L3_CKSUM_ERR) == 0) +- rxm->ol_flags |= PKT_RX_IP_CKSUM_GOOD; +- if (likely(packet_type & RTE_PTYPE_L4_MASK) && +- (cksum_err & HNS3_L4_CKSUM_ERR) == 0) +- rxm->ol_flags |= PKT_RX_L4_CKSUM_GOOD; +- } +-} +- + static inline uint32_t + hns3_rx_calc_ptype(struct hns3_rx_queue *rxq, const uint32_t l234_info, + const uint32_t ol_info) +diff --git a/drivers/net/hns3/hns3_rxtx_vec_neon.h b/drivers/net/hns3/hns3_rxtx_vec_neon.h +index 68f098f..4699a62 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_neon.h ++++ b/drivers/net/hns3/hns3_rxtx_vec_neon.h +@@ -98,7 +98,6 @@ hns3_desc_parse_field(struct hns3_rx_queue *rxq, + uint32_t l234_info, ol_info, bd_base_info; + struct rte_mbuf *pkt; + uint32_t retcode = 0; +- uint32_t cksum_err; + uint32_t i; + int ret; + +@@ -111,17 +110,13 @@ hns3_desc_parse_field(struct hns3_rx_queue *rxq, + l234_info = rxdp[i].rx.l234_info; + ol_info = rxdp[i].rx.ol_info; + bd_base_info = rxdp[i].rx.bd_base_info; +- ret = hns3_handle_bdinfo(rxq, pkt, bd_base_info, +- l234_info, &cksum_err); ++ ret = hns3_handle_bdinfo(rxq, pkt, bd_base_info, l234_info); + if (unlikely(ret)) { + retcode |= 1u << i; + continue; + } + + pkt->packet_type = hns3_rx_calc_ptype(rxq, l234_info, ol_info); +- if (likely(bd_base_info & BIT(HNS3_RXD_L3L4P_B))) +- hns3_rx_set_cksum_flag(pkt, pkt->packet_type, +- cksum_err); + + /* Increment bytes counter */ + rxq->basic_stats.bytes += pkt->pkt_len; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index 2700e6e..bc5577b 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -39,7 +39,6 @@ hns3_desc_parse_field_sve(struct hns3_rx_queue *rxq, + uint32_t bd_vld_num) + { + uint32_t retcode = 0; +- uint32_t cksum_err; + int ret, i; + + for (i = 0; i < (int)bd_vld_num; i++) { +@@ -47,7 +46,7 @@ hns3_desc_parse_field_sve(struct hns3_rx_queue *rxq, + rx_pkts[i]->ol_flags = PKT_RX_RSS_HASH; + + ret = hns3_handle_bdinfo(rxq, rx_pkts[i], key->bd_base_info[i], +- key->l234_info[i], &cksum_err); ++ key->l234_info[i]); + if (unlikely(ret)) { + retcode |= 1u << i; + continue; +@@ -55,9 +54,6 @@ hns3_desc_parse_field_sve(struct hns3_rx_queue *rxq, + + rx_pkts[i]->packet_type = hns3_rx_calc_ptype(rxq, + key->l234_info[i], key->ol_info[i]); +- if (likely(key->bd_base_info[i] & BIT(HNS3_RXD_L3L4P_B))) +- hns3_rx_set_cksum_flag(rx_pkts[i], +- rx_pkts[i]->packet_type, cksum_err); + + /* Increment bytes counter */ + rxq->basic_stats.bytes += rx_pkts[i]->pkt_len; +-- +2.7.4 + diff --git a/0122-net-hns3-check-max-SIMD-bitwidth.patch b/0122-net-hns3-check-max-SIMD-bitwidth.patch new file mode 100644 index 0000000..9421f25 --- /dev/null +++ b/0122-net-hns3-check-max-SIMD-bitwidth.patch @@ -0,0 +1,47 @@ +From 65e9bf664b7758d9e0e722ce0b4b15869a177f19 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 15 Apr 2021 11:52:02 +0800 +Subject: [PATCH 122/189] net/hns3: check max SIMD bitwidth + +This patch supports check max SIMD bitwidth when choosing NEON and SVE +vector path. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 87416a1..92d377b 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -13,6 +13,7 @@ + #include + #if defined(RTE_ARCH_ARM64) + #include ++#include + #endif + + #include "hns3_ethdev.h" +@@ -2790,6 +2791,8 @@ static bool + hns3_get_default_vec_support(void) + { + #if defined(RTE_ARCH_ARM64) ++ if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128) ++ return false; + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) + return true; + #endif +@@ -2800,6 +2803,8 @@ static bool + hns3_get_sve_support(void) + { + #if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_SVE) ++ if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_256) ++ return false; + if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SVE)) + return true; + #endif +-- +2.7.4 + diff --git a/0123-net-hns3-add-compile-time-verification-on-Rx-vector.patch b/0123-net-hns3-add-compile-time-verification-on-Rx-vector.patch new file mode 100644 index 0000000..97b0935 --- /dev/null +++ b/0123-net-hns3-add-compile-time-verification-on-Rx-vector.patch @@ -0,0 +1,89 @@ +From 81ac96b3d326444b3ec1dc5e72819056a94b9e2f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 17 Apr 2021 17:54:54 +0800 +Subject: [PATCH 123/189] net/hns3: add compile-time verification on Rx vector + +Rx vector implementation depends on the mbuf fields +(such as rearm_data/rx_descriptor_fields1) layout, this patch adds +compile-time verification for this. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx_vec.c | 22 ++++++++++++++++++++++ + drivers/net/hns3/hns3_rxtx_vec_neon.h | 8 ++++++++ + drivers/net/hns3/hns3_rxtx_vec_sve.c | 6 ++++++ + 3 files changed, 36 insertions(+) + +diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c +index fd7b272..d6636df 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.c ++++ b/drivers/net/hns3/hns3_rxtx_vec.c +@@ -147,6 +147,28 @@ hns3_rxq_vec_setup_rearm_data(struct hns3_rx_queue *rxq) + mb_def.port = rxq->port_id; + rte_mbuf_refcnt_set(&mb_def, 1); + ++ /* compile-time verifies the rearm_data first 8bytes */ ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) < ++ offsetof(struct rte_mbuf, rearm_data)); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) < ++ offsetof(struct rte_mbuf, rearm_data)); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) < ++ offsetof(struct rte_mbuf, rearm_data)); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, nb_segs) < ++ offsetof(struct rte_mbuf, rearm_data)); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) < ++ offsetof(struct rte_mbuf, rearm_data)); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) - ++ offsetof(struct rte_mbuf, rearm_data) > 6); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) - ++ offsetof(struct rte_mbuf, rearm_data) > 6); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) - ++ offsetof(struct rte_mbuf, rearm_data) > 6); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, nb_segs) - ++ offsetof(struct rte_mbuf, rearm_data) > 6); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) - ++ offsetof(struct rte_mbuf, rearm_data) > 6); ++ + /* prevent compiler reordering: rearm_data covers previous fields */ + rte_compiler_barrier(); + p = (uintptr_t)&mb_def.rearm_data; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_neon.h b/drivers/net/hns3/hns3_rxtx_vec_neon.h +index 4699a62..35fef12 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_neon.h ++++ b/drivers/net/hns3/hns3_rxtx_vec_neon.h +@@ -156,6 +156,14 @@ hns3_recv_burst_vec(struct hns3_rx_queue *__restrict rxq, + 0, 0, 0, /* ignore non-length fields */ + }; + ++ /* compile-time verifies the shuffle mask */ ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) != ++ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) != ++ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash.rss) != ++ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12); ++ + for (pos = 0; pos < nb_pkts; pos += HNS3_DEFAULT_DESCS_PER_LOOP, + rxdp += HNS3_DEFAULT_DESCS_PER_LOOP) { + uint64x2x2_t descs[HNS3_DEFAULT_DESCS_PER_LOOP]; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index bc5577b..e15fd7a 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -118,6 +118,12 @@ hns3_recv_burst_vec_sve(struct hns3_rx_queue *__restrict rxq, + svuint32_t rss_tbl1 = svld1_u32(PG32_256BIT, rss_adjust); + svuint32_t rss_tbl2 = svld1_u32(PG32_256BIT, &rss_adjust[8]); + ++ /* compile-time verifies the xlen_adjust mask */ ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) != ++ offsetof(struct rte_mbuf, pkt_len) + 4); ++ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) != ++ offsetof(struct rte_mbuf, data_len) + 2); ++ + for (pos = 0; pos < nb_pkts; pos += HNS3_SVE_DEFAULT_DESCS_PER_LOOP, + rxdp += HNS3_SVE_DEFAULT_DESCS_PER_LOOP) { + svuint64_t vld_clz, mbp1st, mbp2st, mbuf_init; +-- +2.7.4 + diff --git a/0124-net-hns3-remove-redundant-mailbox-response.patch b/0124-net-hns3-remove-redundant-mailbox-response.patch new file mode 100644 index 0000000..690cb5b --- /dev/null +++ b/0124-net-hns3-remove-redundant-mailbox-response.patch @@ -0,0 +1,58 @@ +From 9450e23dc1f006db7bcc28b7452a838a171453a2 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 17 Apr 2021 17:54:55 +0800 +Subject: [PATCH 124/189] net/hns3: remove redundant mailbox response + +Some mbx messages do not need to reply with data. In this case, +it is no need to set the response data address and the response +length. + +This patch removes these redundant codes from mbx messages that do +not need be replied. + +Fixes: a5475d61fa34 ("net/hns3: support VF") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev_vf.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 16cc111..a4577de 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1511,7 +1511,6 @@ static void + hns3vf_request_link_info(struct hns3_hw *hw) + { + struct hns3_vf *vf = HNS3_DEV_HW_TO_VF(hw); +- uint8_t resp_msg; + bool send_req; + int ret; + +@@ -1524,7 +1523,7 @@ hns3vf_request_link_info(struct hns3_hw *hw) + return; + + ret = hns3_send_mbx_msg(hw, HNS3_MBX_GET_LINK_STATUS, 0, NULL, 0, false, +- &resp_msg, sizeof(resp_msg)); ++ NULL, 0); + if (ret) { + hns3_err(hw, "failed to fetch link status, ret = %d", ret); + return; +@@ -1756,11 +1755,10 @@ hns3vf_keep_alive_handler(void *param) + struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- uint8_t respmsg; + int ret; + + ret = hns3_send_mbx_msg(hw, HNS3_MBX_KEEP_ALIVE, 0, NULL, 0, +- false, &respmsg, sizeof(uint8_t)); ++ false, NULL, 0); + if (ret) + hns3_err(hw, "VF sends keeping alive cmd failed(=%d)", + ret); +-- +2.7.4 + diff --git a/0125-net-hns3-fix-DCB-mode-check.patch b/0125-net-hns3-fix-DCB-mode-check.patch new file mode 100644 index 0000000..3900824 --- /dev/null +++ b/0125-net-hns3-fix-DCB-mode-check.patch @@ -0,0 +1,34 @@ +From 276b4938cbe55ec5deba5d140a6a53f46ea4f399 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 17 Apr 2021 17:54:56 +0800 +Subject: [PATCH 125/189] net/hns3: fix DCB mode check + +Currently, "ONLY DCB" and "DCB+RSS" mode are both supported by HNS3 +PF driver. But the driver verifies only the "DCB+RSS" multiple queues +mode. + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index c75aa9c..7492708 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2239,7 +2239,7 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) + return -EINVAL; + } + +- if (rx_mq_mode == ETH_MQ_RX_DCB_RSS) { ++ if (rx_mq_mode & ETH_MQ_RX_DCB_FLAG) { + if (dcb_rx_conf->nb_tcs > pf->tc_max) { + hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.", + dcb_rx_conf->nb_tcs, pf->tc_max); +-- +2.7.4 + diff --git a/0126-net-hns3-fix-VMDq-mode-check.patch b/0126-net-hns3-fix-VMDq-mode-check.patch new file mode 100644 index 0000000..ac44968 --- /dev/null +++ b/0126-net-hns3-fix-VMDq-mode-check.patch @@ -0,0 +1,77 @@ +From 8732064d03a6d0f46f3120549b31f97990aa81ce Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 17 Apr 2021 17:54:57 +0800 +Subject: [PATCH 126/189] net/hns3: fix VMDq mode check + +HNS3 PF driver only supports RSS, DCB or NONE multiple queues mode. +Currently, driver doesn't verify the VMDq multi-queue mode completely. +This patch fixes the verification for VMDq mode. + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 28 ++++++++++++---------------- + 1 file changed, 12 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7492708..4d63d12 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2222,23 +2222,16 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) + int max_tc = 0; + int i; + +- dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; +- dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; +- +- if (rx_mq_mode == ETH_MQ_RX_VMDQ_DCB_RSS) { +- hns3_err(hw, "ETH_MQ_RX_VMDQ_DCB_RSS is not supported. " +- "rx_mq_mode = %d", rx_mq_mode); +- return -EINVAL; +- } +- +- if (rx_mq_mode == ETH_MQ_RX_VMDQ_DCB || +- tx_mq_mode == ETH_MQ_TX_VMDQ_DCB) { +- hns3_err(hw, "ETH_MQ_RX_VMDQ_DCB and ETH_MQ_TX_VMDQ_DCB " +- "is not supported. rx_mq_mode = %d, tx_mq_mode = %d", ++ if ((rx_mq_mode & ETH_MQ_RX_VMDQ_FLAG) || ++ (tx_mq_mode == ETH_MQ_TX_VMDQ_DCB || ++ tx_mq_mode == ETH_MQ_TX_VMDQ_ONLY)) { ++ hns3_err(hw, "VMDQ is not supported, rx_mq_mode = %d, tx_mq_mode = %d.", + rx_mq_mode, tx_mq_mode); +- return -EINVAL; ++ return -EOPNOTSUPP; + } + ++ dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; ++ dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; + if (rx_mq_mode & ETH_MQ_RX_DCB_FLAG) { + if (dcb_rx_conf->nb_tcs > pf->tc_max) { + hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.", +@@ -2297,8 +2290,7 @@ hns3_check_dcb_cfg(struct rte_eth_dev *dev) + return -EOPNOTSUPP; + } + +- /* Check multiple queue mode */ +- return hns3_check_mq_mode(dev); ++ return 0; + } + + static int +@@ -2471,6 +2463,10 @@ hns3_dev_configure(struct rte_eth_dev *dev) + } + + hw->adapter_state = HNS3_NIC_CONFIGURING; ++ ret = hns3_check_mq_mode(dev); ++ if (ret) ++ goto cfg_err; ++ + if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) { + ret = hns3_check_dcb_cfg(dev); + if (ret) +-- +2.7.4 + diff --git a/0127-net-hns3-fix-flow-director-lock.patch b/0127-net-hns3-fix-flow-director-lock.patch new file mode 100644 index 0000000..c2d75c6 --- /dev/null +++ b/0127-net-hns3-fix-flow-director-lock.patch @@ -0,0 +1,350 @@ +From bdd72afbcc9fbd25812b4ba873875eca26f14b4b Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 17 Apr 2021 17:54:58 +0800 +Subject: [PATCH 127/189] net/hns3: fix flow director lock + +Currently, the fdir lock was used to protect concurrent access in +multiple processes, it has the following problems: +1) Lack of protection for fdir reset recover. +2) Only part of data is protected, eg. the filterlist is not protected. + +We use the following scheme: +1) Del the fdir lock. +2) Add a flow lock and provides rte flow driver ops API-level + protection. +3) Declare support RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 4 +- + drivers/net/hns3/hns3_ethdev.h | 4 ++ + drivers/net/hns3/hns3_ethdev_vf.c | 3 +- + drivers/net/hns3/hns3_fdir.c | 28 ++++++------ + drivers/net/hns3/hns3_fdir.h | 3 +- + drivers/net/hns3/hns3_flow.c | 96 ++++++++++++++++++++++++++++++++++++--- + 6 files changed, 111 insertions(+), 27 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 4d63d12..ccafe60 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -7356,8 +7356,8 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) + PMD_INIT_LOG(ERR, "Failed to alloc memory for process private"); + return -ENOMEM; + } +- /* initialize flow filter lists */ +- hns3_filterlist_init(eth_dev); ++ ++ hns3_flow_init(eth_dev); + + hns3_set_rxtx_function(eth_dev); + eth_dev->dev_ops = &hns3_eth_dev_ops; +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 271eadb..8191c53 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -5,6 +5,7 @@ + #ifndef _HNS3_ETHDEV_H_ + #define _HNS3_ETHDEV_H_ + ++#include + #include + #include + #include +@@ -624,6 +625,9 @@ struct hns3_hw { + uint8_t udp_cksum_mode; + + struct hns3_port_base_vlan_config port_base_vlan_cfg; ++ ++ pthread_mutex_t flows_lock; /* rte_flow ops lock */ ++ + /* + * PMD setup and configuration is not thread safe. Since it is not + * performance sensitive, it is better to guarantee thread-safety +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index a4577de..a278146 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2911,8 +2911,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) + return -ENOMEM; + } + +- /* initialize flow filter lists */ +- hns3_filterlist_init(eth_dev); ++ hns3_flow_init(eth_dev); + + hns3_set_rxtx_function(eth_dev); + eth_dev->dev_ops = &hns3vf_eth_dev_ops; +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index 857cc94..06c9a94 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -830,7 +830,6 @@ int hns3_fdir_filter_init(struct hns3_adapter *hns) + + fdir_hash_params.socket_id = rte_socket_id(); + TAILQ_INIT(&fdir_info->fdir_list); +- rte_spinlock_init(&fdir_info->flows_lock); + snprintf(fdir_hash_name, RTE_HASH_NAMESIZE, "%s", hns->hw.data->name); + fdir_info->hash_handle = rte_hash_create(&fdir_hash_params); + if (fdir_info->hash_handle == NULL) { +@@ -856,7 +855,6 @@ void hns3_fdir_filter_uninit(struct hns3_adapter *hns) + struct hns3_fdir_info *fdir_info = &pf->fdir; + struct hns3_fdir_rule_ele *fdir_filter; + +- rte_spinlock_lock(&fdir_info->flows_lock); + if (fdir_info->hash_map) { + rte_free(fdir_info->hash_map); + fdir_info->hash_map = NULL; +@@ -865,7 +863,6 @@ void hns3_fdir_filter_uninit(struct hns3_adapter *hns) + rte_hash_free(fdir_info->hash_handle); + fdir_info->hash_handle = NULL; + } +- rte_spinlock_unlock(&fdir_info->flows_lock); + + fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); + while (fdir_filter) { +@@ -891,10 +888,8 @@ static int hns3_fdir_filter_lookup(struct hns3_fdir_info *fdir_info, + hash_sig_t sig; + int ret; + +- rte_spinlock_lock(&fdir_info->flows_lock); + sig = rte_hash_crc(key, sizeof(*key), 0); + ret = rte_hash_lookup_with_hash(fdir_info->hash_handle, key, sig); +- rte_spinlock_unlock(&fdir_info->flows_lock); + + return ret; + } +@@ -908,11 +903,9 @@ static int hns3_insert_fdir_filter(struct hns3_hw *hw, + int ret; + + key = &fdir_filter->fdir_conf.key_conf; +- rte_spinlock_lock(&fdir_info->flows_lock); + sig = rte_hash_crc(key, sizeof(*key), 0); + ret = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig); + if (ret < 0) { +- rte_spinlock_unlock(&fdir_info->flows_lock); + hns3_err(hw, "Hash table full? err:%d(%s)!", ret, + strerror(-ret)); + return ret; +@@ -920,7 +913,6 @@ static int hns3_insert_fdir_filter(struct hns3_hw *hw, + + fdir_info->hash_map[ret] = fdir_filter; + TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries); +- rte_spinlock_unlock(&fdir_info->flows_lock); + + return ret; + } +@@ -933,11 +925,9 @@ static int hns3_remove_fdir_filter(struct hns3_hw *hw, + hash_sig_t sig; + int ret; + +- rte_spinlock_lock(&fdir_info->flows_lock); + sig = rte_hash_crc(key, sizeof(*key), 0); + ret = rte_hash_del_key_with_hash(fdir_info->hash_handle, key, sig); + if (ret < 0) { +- rte_spinlock_unlock(&fdir_info->flows_lock); + hns3_err(hw, "Delete hash key fail ret=%d", ret); + return ret; + } +@@ -945,7 +935,6 @@ static int hns3_remove_fdir_filter(struct hns3_hw *hw, + fdir_filter = fdir_info->hash_map[ret]; + fdir_info->hash_map[ret] = NULL; + TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); +- rte_spinlock_unlock(&fdir_info->flows_lock); + + rte_free(fdir_filter); + +@@ -1000,11 +989,9 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns, + rule->location = ret; + node->fdir_conf.location = ret; + +- rte_spinlock_lock(&fdir_info->flows_lock); + ret = hns3_config_action(hw, rule); + if (!ret) + ret = hns3_config_key(hns, rule); +- rte_spinlock_unlock(&fdir_info->flows_lock); + if (ret) { + hns3_err(hw, "Failed to config fdir: %u src_ip:%x dst_ip:%x " + "src_port:%u dst_port:%u ret = %d", +@@ -1029,9 +1016,7 @@ int hns3_clear_all_fdir_filter(struct hns3_adapter *hns) + int ret = 0; + + /* flush flow director */ +- rte_spinlock_lock(&fdir_info->flows_lock); + rte_hash_reset(fdir_info->hash_handle); +- rte_spinlock_unlock(&fdir_info->flows_lock); + + fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); + while (fdir_filter) { +@@ -1059,6 +1044,17 @@ int hns3_restore_all_fdir_filter(struct hns3_adapter *hns) + bool err = false; + int ret; + ++ /* ++ * This API is called in the reset recovery process, the parent function ++ * must hold hw->lock. ++ * There maybe deadlock if acquire hw->flows_lock directly because rte ++ * flow driver ops first acquire hw->flows_lock and then may acquire ++ * hw->lock. ++ * So here first release the hw->lock and then acquire the ++ * hw->flows_lock to avoid deadlock. ++ */ ++ rte_spinlock_unlock(&hw->lock); ++ pthread_mutex_lock(&hw->flows_lock); + TAILQ_FOREACH(fdir_filter, &fdir_info->fdir_list, entries) { + ret = hns3_config_action(hw, &fdir_filter->fdir_conf); + if (!ret) +@@ -1069,6 +1065,8 @@ int hns3_restore_all_fdir_filter(struct hns3_adapter *hns) + break; + } + } ++ pthread_mutex_unlock(&hw->flows_lock); ++ rte_spinlock_lock(&hw->lock); + + if (err) { + hns3_err(hw, "Fail to restore FDIR filter, ret = %d", ret); +diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h +index a5760a3..d64af85 100644 +--- a/drivers/net/hns3/hns3_fdir.h ++++ b/drivers/net/hns3/hns3_fdir.h +@@ -199,7 +199,6 @@ struct hns3_process_private { + * A structure used to define fields of a FDIR related info. + */ + struct hns3_fdir_info { +- rte_spinlock_t flows_lock; + struct hns3_fdir_rule_list fdir_list; + struct hns3_fdir_rule_ele **hash_map; + struct rte_hash *hash_handle; +@@ -220,7 +219,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns, + struct hns3_fdir_rule *rule, bool del); + int hns3_clear_all_fdir_filter(struct hns3_adapter *hns); + int hns3_get_count(struct hns3_hw *hw, uint32_t id, uint64_t *value); +-void hns3_filterlist_init(struct rte_eth_dev *dev); ++void hns3_flow_init(struct rte_eth_dev *dev); + int hns3_restore_all_fdir_filter(struct hns3_adapter *hns); + + #endif /* _HNS3_FDIR_H_ */ +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 3cca416..c07929f 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1214,9 +1214,18 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + } + + void +-hns3_filterlist_init(struct rte_eth_dev *dev) ++hns3_flow_init(struct rte_eth_dev *dev) + { ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_process_private *process_list = dev->process_private; ++ pthread_mutexattr_t attr; ++ ++ if (rte_eal_process_type() == RTE_PROC_PRIMARY) { ++ pthread_mutexattr_init(&attr); ++ pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); ++ pthread_mutex_init(&hw->flows_lock, &attr); ++ dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE; ++ } + + TAILQ_INIT(&process_list->fdir_list); + TAILQ_INIT(&process_list->filter_rss_list); +@@ -2002,12 +2011,87 @@ hns3_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, + return 0; + } + ++static int ++hns3_flow_validate_wrap(struct rte_eth_dev *dev, ++ const struct rte_flow_attr *attr, ++ const struct rte_flow_item pattern[], ++ const struct rte_flow_action actions[], ++ struct rte_flow_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ pthread_mutex_lock(&hw->flows_lock); ++ ret = hns3_flow_validate(dev, attr, pattern, actions, error); ++ pthread_mutex_unlock(&hw->flows_lock); ++ ++ return ret; ++} ++ ++static struct rte_flow * ++hns3_flow_create_wrap(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, ++ const struct rte_flow_item pattern[], ++ const struct rte_flow_action actions[], ++ struct rte_flow_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct rte_flow *flow; ++ ++ pthread_mutex_lock(&hw->flows_lock); ++ flow = hns3_flow_create(dev, attr, pattern, actions, error); ++ pthread_mutex_unlock(&hw->flows_lock); ++ ++ return flow; ++} ++ ++static int ++hns3_flow_destroy_wrap(struct rte_eth_dev *dev, struct rte_flow *flow, ++ struct rte_flow_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ pthread_mutex_lock(&hw->flows_lock); ++ ret = hns3_flow_destroy(dev, flow, error); ++ pthread_mutex_unlock(&hw->flows_lock); ++ ++ return ret; ++} ++ ++static int ++hns3_flow_flush_wrap(struct rte_eth_dev *dev, struct rte_flow_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ pthread_mutex_lock(&hw->flows_lock); ++ ret = hns3_flow_flush(dev, error); ++ pthread_mutex_unlock(&hw->flows_lock); ++ ++ return ret; ++} ++ ++static int ++hns3_flow_query_wrap(struct rte_eth_dev *dev, struct rte_flow *flow, ++ const struct rte_flow_action *actions, void *data, ++ struct rte_flow_error *error) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ pthread_mutex_lock(&hw->flows_lock); ++ ret = hns3_flow_query(dev, flow, actions, data, error); ++ pthread_mutex_unlock(&hw->flows_lock); ++ ++ return ret; ++} ++ + static const struct rte_flow_ops hns3_flow_ops = { +- .validate = hns3_flow_validate, +- .create = hns3_flow_create, +- .destroy = hns3_flow_destroy, +- .flush = hns3_flow_flush, +- .query = hns3_flow_query, ++ .validate = hns3_flow_validate_wrap, ++ .create = hns3_flow_create_wrap, ++ .destroy = hns3_flow_destroy_wrap, ++ .flush = hns3_flow_flush_wrap, ++ .query = hns3_flow_query_wrap, + .isolate = NULL, + }; + +-- +2.7.4 + diff --git a/0128-net-hns3-move-link-speeds-check-to-configure.patch b/0128-net-hns3-move-link-speeds-check-to-configure.patch new file mode 100644 index 0000000..32d2548 --- /dev/null +++ b/0128-net-hns3-move-link-speeds-check-to-configure.patch @@ -0,0 +1,124 @@ +From 96ea5f9a0b53ec1f701d3aec5342cd363871bb15 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 17 Apr 2021 17:54:59 +0800 +Subject: [PATCH 128/189] net/hns3: move link speeds check to configure + +This patch moves the check for "link_speeds" in dev_conf to +dev_configure, so that users know whether "link_speeds" is valid in +advance. + +Fixes: bdaf190f8235 ("net/hns3: support link speed autoneg for PF") +Fixes: 400d307e1a60 ("net/hns3: support fixed link speed") + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 57 +++++++++++++++++++++++++++++++++--------- + 1 file changed, 45 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index ccafe60..e2a96c1 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -105,6 +105,7 @@ static int hns3_remove_mc_addr(struct hns3_hw *hw, + static int hns3_restore_fec(struct hns3_hw *hw); + static int hns3_query_dev_fec_info(struct hns3_hw *hw); + static int hns3_do_stop(struct hns3_adapter *hns); ++static int hns3_check_port_speed(struct hns3_hw *hw, uint32_t link_speeds); + + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr) +@@ -2429,6 +2430,46 @@ hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf) + } + + static int ++hns3_check_link_speed(struct hns3_hw *hw, uint32_t link_speeds) ++{ ++ int ret; ++ ++ /* ++ * Some hardware doesn't support auto-negotiation, but users may not ++ * configure link_speeds (default 0), which means auto-negotiation. ++ * In this case, a warning message need to be printed, instead of ++ * an error. ++ */ ++ if (link_speeds == ETH_LINK_SPEED_AUTONEG && ++ hw->mac.support_autoneg == 0) { ++ hns3_warn(hw, "auto-negotiation is not supported, use default fixed speed!"); ++ return 0; ++ } ++ ++ if (link_speeds != ETH_LINK_SPEED_AUTONEG) { ++ ret = hns3_check_port_speed(hw, link_speeds); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_check_dev_conf(struct rte_eth_dev *dev) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ struct rte_eth_conf *conf = &dev->data->dev_conf; ++ int ret; ++ ++ ret = hns3_check_mq_mode(dev); ++ if (ret) ++ return ret; ++ ++ return hns3_check_link_speed(hw, conf->link_speeds); ++} ++ ++static int + hns3_dev_configure(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; +@@ -2463,7 +2504,7 @@ hns3_dev_configure(struct rte_eth_dev *dev) + } + + hw->adapter_state = HNS3_NIC_CONFIGURING; +- ret = hns3_check_mq_mode(dev); ++ ret = hns3_check_dev_conf(dev); + if (ret) + goto cfg_err; + +@@ -5464,14 +5505,11 @@ hns3_set_fiber_port_link_speed(struct hns3_hw *hw, + + /* + * Some hardware doesn't support auto-negotiation, but users may not +- * configure link_speeds (default 0), which means auto-negotiation +- * In this case, a warning message need to be printed, instead of +- * an error. ++ * configure link_speeds (default 0), which means auto-negotiation. ++ * In this case, it should return success. + */ +- if (cfg->autoneg) { +- hns3_warn(hw, "auto-negotiation is not supported."); ++ if (cfg->autoneg) + return 0; +- } + + return hns3_cfg_mac_speed_dup(hw, cfg->speed, cfg->duplex); + } +@@ -5512,16 +5550,11 @@ hns3_apply_link_speed(struct hns3_hw *hw) + { + struct rte_eth_conf *conf = &hw->data->dev_conf; + struct hns3_set_link_speed_cfg cfg; +- int ret; + + memset(&cfg, 0, sizeof(struct hns3_set_link_speed_cfg)); + cfg.autoneg = (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) ? + ETH_LINK_AUTONEG : ETH_LINK_FIXED; + if (cfg.autoneg != ETH_LINK_AUTONEG) { +- ret = hns3_check_port_speed(hw, conf->link_speeds); +- if (ret) +- return ret; +- + cfg.speed = hns3_get_link_speed(conf->link_speeds); + cfg.duplex = hns3_get_link_duplex(conf->link_speeds); + } +-- +2.7.4 + diff --git a/0129-net-hns3-remove-unused-macro.patch b/0129-net-hns3-remove-unused-macro.patch new file mode 100644 index 0000000..929ea93 --- /dev/null +++ b/0129-net-hns3-remove-unused-macro.patch @@ -0,0 +1,31 @@ +From fc5b336c4006b92193b36b61363e39a776bad5cb Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Tue, 20 Apr 2021 16:59:48 +0800 +Subject: [PATCH 129/189] net/hns3: remove unused macro + +'HNS3_RXD_LKBK_B' was defined in previous versions but no used. +This patch deleted it. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index ac14802..92f01ed 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -106,7 +106,6 @@ + #define HNS3_RXD_L3L4P_B 11 + + #define HNS3_RXD_TS_VLD_B 14 +-#define HNS3_RXD_LKBK_B 15 + #define HNS3_RXD_GRO_SIZE_S 16 + #define HNS3_RXD_GRO_SIZE_M (0x3fff << HNS3_RXD_GRO_SIZE_S) + +-- +2.7.4 + diff --git a/0130-net-hns3-fix-traffic-management-support-check.patch b/0130-net-hns3-fix-traffic-management-support-check.patch new file mode 100644 index 0000000..053f14c --- /dev/null +++ b/0130-net-hns3-fix-traffic-management-support-check.patch @@ -0,0 +1,34 @@ +From 67137c61da758dd22b8a5f9cda9e32fcd9034892 Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Tue, 20 Apr 2021 16:59:49 +0800 +Subject: [PATCH 130/189] net/hns3: fix traffic management support check + +params->leaf.cman has enum type which is not isomorphic with boolean +type, however it is used as a boolean expression. + +This patch fixed it. + +Fixes: c09c7847d892 ("net/hns3: support traffic management") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_tm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_tm.c b/drivers/net/hns3/hns3_tm.c +index bcae57a..f7bfc25 100644 +--- a/drivers/net/hns3/hns3_tm.c ++++ b/drivers/net/hns3/hns3_tm.c +@@ -385,7 +385,7 @@ hns3_tm_leaf_node_param_check(struct rte_eth_dev *dev __rte_unused, + return -EINVAL; + } + +- if (params->leaf.cman) { ++ if (params->leaf.cman != RTE_TM_CMAN_TAIL_DROP) { + error->type = RTE_TM_ERROR_TYPE_NODE_PARAMS_CMAN; + error->message = "congestion management not supported"; + return -EINVAL; +-- +2.7.4 + diff --git a/0131-net-hns3-ignore-devargs-parsing-return.patch b/0131-net-hns3-ignore-devargs-parsing-return.patch new file mode 100644 index 0000000..379f1f7 --- /dev/null +++ b/0131-net-hns3-ignore-devargs-parsing-return.patch @@ -0,0 +1,39 @@ +From 395f4bf89616e096fc6fd95d7baed7dd3219525b Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Tue, 20 Apr 2021 16:59:50 +0800 +Subject: [PATCH 131/189] net/hns3: ignore devargs parsing return + +In hns3 PMD, as the handler always return 0, the return value +of a function 'rte_kvargs_process' no need to be checked. But +the API definition has return value, so 'void' could be used +to ignore that. + +Fixes: a124f9e9591b ("net/hns3: add runtime config to select IO burst function") + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index e2a96c1..81c67e2 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -7268,11 +7268,11 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + if (!kvlist) + return; + +- rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT, ++ (void)rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT, + &hns3_parse_io_hint_func, &rx_func_hint); +- rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT, ++ (void)rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT, + &hns3_parse_io_hint_func, &tx_func_hint); +- rte_kvargs_process(kvlist, HNS3_DEVARG_DEV_CAPS_MASK, ++ (void)rte_kvargs_process(kvlist, HNS3_DEVARG_DEV_CAPS_MASK, + &hns3_parse_dev_caps_mask, &dev_caps_mask); + rte_kvargs_free(kvlist); + +-- +2.7.4 + diff --git a/0132-net-hns3-fix-mailbox-error-message.patch b/0132-net-hns3-fix-mailbox-error-message.patch new file mode 100644 index 0000000..c4210f6 --- /dev/null +++ b/0132-net-hns3-fix-mailbox-error-message.patch @@ -0,0 +1,34 @@ +From 4cdaa8769ca9aa1aa558637606de0434bdd343fb Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 22 Apr 2021 09:55:49 +0800 +Subject: [PATCH 132/189] net/hns3: fix mailbox error message + +The hns3_dev_handle_mbx_msg() could be called under both PF and VF, +but the error messages show VF. + +Fixes: 109e4dd1bd7a ("net/hns3: get link state change through mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 9955f27..6203af5 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -528,8 +528,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + hns3_handle_promisc_info(hw, req->msg[1]); + break; + default: +- hns3_err(hw, +- "VF received unsupported(%u) mbx msg from PF", ++ hns3_err(hw, "received unsupported(%u) mbx msg", + req->msg[0]); + break; + } +-- +2.7.4 + diff --git a/0133-net-hns3-fix-processing-link-status-message-on-PF.patch b/0133-net-hns3-fix-processing-link-status-message-on-PF.patch new file mode 100644 index 0000000..730ef9e --- /dev/null +++ b/0133-net-hns3-fix-processing-link-status-message-on-PF.patch @@ -0,0 +1,61 @@ +From 34cf459a8af7788e68e9614c82a1cbcd38d5f55c Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 22 Apr 2021 09:55:50 +0800 +Subject: [PATCH 133/189] net/hns3: fix processing link status message on PF + +The opcode of the link status notification message reported by the +firmware is zero, it will be filtered out because driver treats it as +already processed message. As a result, the PF can't update the link +status in a timely manner. + +Because only VF can set opcode to zero when processing mailbox message, +we add a judgment to make sure the PF messages will not be filtered out. + +Fixes: dbbbad23e380 ("net/hns3: fix VF handling LSC event in secondary process") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 6203af5..ea6c0c3 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -438,16 +438,19 @@ hns3_handle_mbx_msg_out_intr(struct hns3_hw *hw) + void + hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_cmq_ring *crq = &hw->cmq.crq; + struct hns3_mbx_pf_to_vf_cmd *req; + struct hns3_cmd_desc *desc; ++ bool handle_out; + uint8_t opcode; + uint16_t flag; + + rte_spinlock_lock(&hw->cmq.crq.lock); + +- if (rte_eal_process_type() != RTE_PROC_PRIMARY || +- !rte_thread_is_intr()) { ++ handle_out = (rte_eal_process_type() != RTE_PROC_PRIMARY || ++ !rte_thread_is_intr()) && hns->is_vf; ++ if (handle_out) { + /* + * Currently, any threads in the primary and secondary processes + * could send mailbox sync request, so it will need to process +@@ -491,7 +494,8 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + continue; + } + +- if (desc->opcode == 0) { ++ handle_out = hns->is_vf && desc->opcode == 0; ++ if (handle_out) { + /* Message already processed by other thread */ + crq->desc[crq->next_to_use].flag = 0; + hns3_mbx_ring_ptr_move_crq(crq); +-- +2.7.4 + diff --git a/0134-net-hns3-remove-unused-mailbox-macro-and-struct.patch b/0134-net-hns3-remove-unused-mailbox-macro-and-struct.patch new file mode 100644 index 0000000..c478ffa --- /dev/null +++ b/0134-net-hns3-remove-unused-mailbox-macro-and-struct.patch @@ -0,0 +1,55 @@ +From 0a74fe6f54d39e5e09e875266efc365d51a4de68 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Thu, 22 Apr 2021 09:55:52 +0800 +Subject: [PATCH 134/189] net/hns3: remove unused mailbox macro and struct + +In hns3_mbx.h, some macro and structure were defined in previous +versions but never used. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.h | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_mbx.h b/drivers/net/hns3/hns3_mbx.h +index 338c2c2..e84ef6d 100644 +--- a/drivers/net/hns3/hns3_mbx.h ++++ b/drivers/net/hns3/hns3_mbx.h +@@ -5,8 +5,6 @@ + #ifndef _HNS3_MBX_H_ + #define _HNS3_MBX_H_ + +-#define HNS3_MBX_VF_MSG_DATA_NUM 16 +- + enum HNS3_MBX_OPCODE { + HNS3_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ + HNS3_MBX_ASSERTING_RESET, /* (PF -> VF) PF is asserting reset */ +@@ -80,8 +78,6 @@ enum hns3_mbx_link_fail_subcode { + + #define HNS3_MBX_MAX_MSG_SIZE 16 + #define HNS3_MBX_MAX_RESP_DATA_SIZE 8 +-#define HNS3_MBX_RING_MAP_BASIC_MSG_NUM 3 +-#define HNS3_MBX_RING_NODE_VARIABLE_NUM 3 + + enum { + HNS3_MBX_RESP_MATCHING_SCHEME_OF_ORIGINAL = 0, +@@ -147,12 +143,6 @@ struct hns3_vf_bind_vector_msg { + struct hns3_ring_chain_param param[HNS3_MBX_MAX_RING_CHAIN_PARAM_NUM]; + }; + +-struct hns3_vf_rst_cmd { +- uint8_t dest_vfid; +- uint8_t vf_rst; +- uint8_t rsv[22]; +-}; +- + struct hns3_pf_rst_done_cmd { + uint8_t pf_rst_done; + uint8_t rsv[23]; +-- +2.7.4 + diff --git a/0135-net-hns3-fix-typos-on-comments.patch b/0135-net-hns3-fix-typos-on-comments.patch new file mode 100644 index 0000000..6245b79 --- /dev/null +++ b/0135-net-hns3-fix-typos-on-comments.patch @@ -0,0 +1,63 @@ +From ccfb6795b2b2336ea29836d1ac8bdadcf6e635be Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Fri, 23 Apr 2021 17:27:38 +0800 +Subject: [PATCH 135/189] net/hns3: fix typos on comments + +This patch fixed wrong word in comments. + +Fixes: f53a793bb7c2 ("net/hns3: add more hardware error types") +Fixes: d51867db65c1 ("net/hns3: add initialization") +Fixes: 411d23b9eafb ("net/hns3: support VLAN") +Fixes: 5f8845f4ba8f ("net/hns3: process MAC interrupt") +Cc: stable@dpdk.org + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 81c67e2..887c008 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -280,7 +280,7 @@ hns3_handle_mac_tnl(struct hns3_hw *hw) + uint32_t status; + int ret; + +- /* query and clear mac tnl interruptions */ ++ /* query and clear mac tnl interrupt */ + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_TNL_INT, true); + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { +@@ -462,7 +462,7 @@ hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) + * When port base vlan enabled, we use port base vlan as the vlan + * filter condition. In this case, we don't update vlan filter table + * when user add new vlan or remove exist vlan, just update the +- * vlan list. The vlan id in vlan list will be writen in vlan filter ++ * vlan list. The vlan id in vlan list will be written in vlan filter + * table until port base vlan disabled + */ + if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { +@@ -3983,8 +3983,8 @@ hns3_rx_buffer_calc(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc) + * For different application scenes, the enabled port number, TC number + * and no_drop TC number are different. In order to obtain the better + * performance, software could allocate the buffer size and configure +- * the waterline by tring to decrease the private buffer size according +- * to the order, namely, waterline of valided tc, pfc disabled tc, pfc ++ * the waterline by trying to decrease the private buffer size according ++ * to the order, namely, waterline of valid tc, pfc disabled tc, pfc + * enabled tc. + */ + if (hns3_rx_buf_calc_all(hw, false, buf_alloc)) +@@ -5045,7 +5045,7 @@ hns3_config_all_msix_error(struct hns3_hw *hw, bool enable) + * and belong to a different type from the MSI-x errors processed + * by the network driver. + * +- * Network driver should open the new error report on initialition ++ * Network driver should open the new error report on initialization. + */ + val = hns3_read_dev(hw, HNS3_VECTOR0_OTER_EN_REG); + hns3_set_bit(val, HNS3_VECTOR0_ALL_MSIX_ERR_B, enable ? 1 : 0); +-- +2.7.4 + diff --git a/0136-net-hns3-disable-MAC-status-report-interrupt.patch b/0136-net-hns3-disable-MAC-status-report-interrupt.patch new file mode 100644 index 0000000..231bd23 --- /dev/null +++ b/0136-net-hns3-disable-MAC-status-report-interrupt.patch @@ -0,0 +1,33 @@ +From 6f262eb7e4f7682a34b53d5c4328fee1a4d817de Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Fri, 23 Apr 2021 17:56:34 +0800 +Subject: [PATCH 136/189] net/hns3: disable MAC status report interrupt + +Disable the MAC status report interrupt which hns3 driver not concern +currently. + +Fixes: 5f8845f4ba8f ("net/hns3: process MAC interrupt") +Cc: stable@dpdk.org + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + 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 887c008..cea7926 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -4892,8 +4892,6 @@ hns3_update_link_status(struct hns3_hw *hw) + if (state != hw->mac.link_status) { + hw->mac.link_status = state; + hns3_warn(hw, "Link status change to %s!", state ? "up" : "down"); +- hns3_config_mac_tnl_int(hw, +- state == ETH_LINK_UP ? true : false); + return true; + } + +-- +2.7.4 + diff --git a/0137-net-hns3-fix-handling-link-update.patch b/0137-net-hns3-fix-handling-link-update.patch new file mode 100644 index 0000000..6dc3f6e --- /dev/null +++ b/0137-net-hns3-fix-handling-link-update.patch @@ -0,0 +1,49 @@ +From 2f19fbb0dd817a21194fc0764621fe0ad67b90a7 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 27 Apr 2021 20:17:39 +0800 +Subject: [PATCH 137/189] net/hns3: fix handling link update + +The link fails code should be parsed using the structure +hns3_mbx_vf_to_pf_cmd, else it will parse fail. + +Fixes: 109e4dd1bd7a ("net/hns3: get link state change through mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index ea6c0c3..3d019b9 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -347,7 +347,7 @@ hns3_link_fail_parse(struct hns3_hw *hw, uint8_t link_fail_code) + + static void + hns3pf_handle_link_change_event(struct hns3_hw *hw, +- struct hns3_mbx_pf_to_vf_cmd *req) ++ struct hns3_mbx_vf_to_pf_cmd *req) + { + #define LINK_STATUS_OFFSET 1 + #define LINK_FAIL_CODE_OFFSET 2 +@@ -513,7 +513,14 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + hns3_handle_asserting_reset(hw, req); + break; + case HNS3_MBX_PUSH_LINK_STATUS: +- hns3pf_handle_link_change_event(hw, req); ++ /* ++ * This message is reported by the firmware and is ++ * reported in 'struct hns3_mbx_vf_to_pf_cmd' format. ++ * Therefore, we should cast the req variable to ++ * 'struct hns3_mbx_vf_to_pf_cmd' and then process it. ++ */ ++ hns3pf_handle_link_change_event(hw, ++ (struct hns3_mbx_vf_to_pf_cmd *)req); + break; + case HNS3_MBX_PUSH_VLAN_INFO: + /* +-- +2.7.4 + diff --git a/0138-net-hns3-fix-link-status-when-port-is-stopped.patch b/0138-net-hns3-fix-link-status-when-port-is-stopped.patch new file mode 100644 index 0000000..393bef4 --- /dev/null +++ b/0138-net-hns3-fix-link-status-when-port-is-stopped.patch @@ -0,0 +1,51 @@ +From d2fe85e2b088b99decbd4d394071fffbb6d80ff2 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sun, 25 Apr 2021 20:06:28 +0800 +Subject: [PATCH 138/189] net/hns3: fix link status when port is stopped + +When port is stopped, link down should be reported to user. For HNS3 +PF driver, link status comes from link status of hardware. If the port +supports NCSI feature, hardware MAC will not be disabled. At this case, +even if the port is stopped, the link status is still Up. So driver +should set link down when the port is stopped. + +Fixes: 59fad0f32135 ("net/hns3: support link update operation") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index cea7926..eed1a37 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2894,6 +2894,15 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) + struct rte_eth_link new_link; + int ret; + ++ /* When port is stopped, report link down. */ ++ if (eth_dev->data->dev_started == 0) { ++ new_link.link_autoneg = mac->link_autoneg; ++ new_link.link_duplex = mac->link_duplex; ++ new_link.link_speed = ETH_SPEED_NUM_NONE; ++ new_link.link_status = ETH_LINK_DOWN; ++ goto out; ++ } ++ + do { + ret = hns3_update_port_link_info(eth_dev); + if (ret) { +@@ -2911,6 +2920,7 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) + memset(&new_link, 0, sizeof(new_link)); + hns3_setup_linkstatus(eth_dev, &new_link); + ++out: + return rte_eth_linkstatus_set(eth_dev, &new_link); + } + +-- +2.7.4 + diff --git a/0139-net-hns3-fix-link-speed-when-port-is-down.patch b/0139-net-hns3-fix-link-speed-when-port-is-down.patch new file mode 100644 index 0000000..b266e7d --- /dev/null +++ b/0139-net-hns3-fix-link-speed-when-port-is-down.patch @@ -0,0 +1,46 @@ +From 5ebfd9debffcadd8410f92089b4103e888b859b0 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sun, 25 Apr 2021 20:06:29 +0800 +Subject: [PATCH 139/189] net/hns3: fix link speed when port is down + +When the port is link down state, it is meaningless to display the +port link speed. It should be an undefined state. + +Fixes: 59fad0f32135 ("net/hns3: support link update operation") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index eed1a37..8dc9dbe 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2867,16 +2867,18 @@ hns3_setup_linkstatus(struct rte_eth_dev *eth_dev, + case ETH_SPEED_NUM_50G: + case ETH_SPEED_NUM_100G: + case ETH_SPEED_NUM_200G: +- new_link->link_speed = mac->link_speed; ++ if (mac->link_status) ++ new_link->link_speed = mac->link_speed; + break; + default: + if (mac->link_status) + new_link->link_speed = ETH_SPEED_NUM_UNKNOWN; +- else +- new_link->link_speed = ETH_SPEED_NUM_NONE; + break; + } + ++ if (!mac->link_status) ++ new_link->link_speed = ETH_SPEED_NUM_NONE; ++ + new_link->link_duplex = mac->link_duplex; + new_link->link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN; + new_link->link_autoneg = mac->link_autoneg; +-- +2.7.4 + diff --git a/0140-net-hns3-support-preferred-burst-size-and-queues-in-.patch b/0140-net-hns3-support-preferred-burst-size-and-queues-in-.patch new file mode 100644 index 0000000..34fe059 --- /dev/null +++ b/0140-net-hns3-support-preferred-burst-size-and-queues-in-.patch @@ -0,0 +1,64 @@ +From 8ca8c0a70500b13e25d292994ba403729f8671fd Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 28 Apr 2021 15:20:51 +0800 +Subject: [PATCH 140/189] net/hns3: support preferred burst size and queues in + VF + +This patch supports get preferred burst size and queues when call +rte_eth_dev_info_get() API with VF. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 3 --- + drivers/net/hns3/hns3_ethdev.h | 3 +++ + drivers/net/hns3/hns3_ethdev_vf.c | 5 +++++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 8dc9dbe..f532284 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -16,9 +16,6 @@ + #include "hns3_dcb.h" + #include "hns3_mp.h" + +-#define HNS3_DEFAULT_PORT_CONF_BURST_SIZE 32 +-#define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1 +- + #define HNS3_SERVICE_INTERVAL 1000000 /* us */ + #define HNS3_SERVICE_QUICK_INTERVAL 10 + #define HNS3_INVALID_PVID 0xFFFF +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 8191c53..29737c6 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -42,6 +42,9 @@ + #define HNS3_PF_FUNC_ID 0 + #define HNS3_1ST_VF_FUNC_ID 1 + ++#define HNS3_DEFAULT_PORT_CONF_BURST_SIZE 32 ++#define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1 ++ + #define HNS3_SW_SHIFT_AND_DISCARD_MODE 0 + #define HNS3_HW_SHIFT_AND_DISCARD_MODE 1 + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index a278146..324c6b1 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1027,6 +1027,11 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + info->reta_size = hw->rss_ind_tbl_size; + info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; ++ ++ info->default_rxportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE; ++ info->default_txportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE; ++ info->default_rxportconf.nb_queues = HNS3_DEFAULT_PORT_CONF_QUEUES_NUM; ++ info->default_txportconf.nb_queues = HNS3_DEFAULT_PORT_CONF_QUEUES_NUM; + info->default_rxportconf.ring_size = HNS3_DEFAULT_RING_DESC; + info->default_txportconf.ring_size = HNS3_DEFAULT_RING_DESC; + +-- +2.7.4 + diff --git a/0141-net-hns3-log-time-delta-in-decimal-format.patch b/0141-net-hns3-log-time-delta-in-decimal-format.patch new file mode 100644 index 0000000..fe55181 --- /dev/null +++ b/0141-net-hns3-log-time-delta-in-decimal-format.patch @@ -0,0 +1,50 @@ +From 8d44b2b715e6fba4454cfbd754eb155b81060a2a Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 28 Apr 2021 15:20:52 +0800 +Subject: [PATCH 141/189] net/hns3: log time delta in decimal format + +If the reset process cost too much time, driver will log one error +message which formats the time delta, but the formatting is using +hexadecimal which was not readable. + +This patch fixes it by formatting in decimal format. + +Fixes: 2790c6464725 ("net/hns3: support device reset") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 2 +- + drivers/net/hns3/hns3_ethdev_vf.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index f532284..f6f1b3b 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6707,7 +6707,7 @@ hns3_reset_service(void *param) + msec = tv_delta.tv_sec * MSEC_PER_SEC + + tv_delta.tv_usec / USEC_PER_MSEC; + if (msec > HNS3_RESET_PROCESS_MS) +- hns3_err(hw, "%d handle long time delta %" PRIx64 ++ hns3_err(hw, "%d handle long time delta %" PRIu64 + " ms time=%ld.%.6ld", + hw->reset.level, msec, + tv.tv_sec, tv.tv_usec); +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 324c6b1..8ab3732 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2779,7 +2779,7 @@ hns3vf_reset_service(void *param) + msec = tv_delta.tv_sec * MSEC_PER_SEC + + tv_delta.tv_usec / USEC_PER_MSEC; + if (msec > HNS3_RESET_PROCESS_MS) +- hns3_err(hw, "%d handle long time delta %" PRIx64 ++ hns3_err(hw, "%d handle long time delta %" PRIu64 + " ms time=%ld.%.6ld", + hw->reset.level, msec, tv.tv_sec, tv.tv_usec); + } +-- +2.7.4 + diff --git a/0142-net-hns3-fix-time-delta-calculation.patch b/0142-net-hns3-fix-time-delta-calculation.patch new file mode 100644 index 0000000..baac952 --- /dev/null +++ b/0142-net-hns3-fix-time-delta-calculation.patch @@ -0,0 +1,315 @@ +From 4664bc17d0b90fa8935d6e5e6d0ec41a59c7e955 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 28 Apr 2021 15:20:53 +0800 +Subject: [PATCH 142/189] net/hns3: fix time delta calculation + +Currently, driver uses gettimeofday() API to get the time, and +then calculate the time delta, the delta will be used mainly in +judging timeout process. + +But the time which gets from gettimeofday() API isn't monotonically +increasing. The process may fail if the system time is changed. + +We use the following scheme to fix it: +1. Add hns3_clock_gettime() API which will get the monotonically + increasing time. +2. Add hns3_clock_calctime_ms() API which will get the milliseconds of + the monotonically increasing time. +3. Add hns3_clock_calctime_ms() API which will calc the milliseconds of + a given time. + +Fixes: 2790c6464725 ("net/hns3: support device reset") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 46 +++++++++++++++++++++++++++++++++------ + drivers/net/hns3/hns3_ethdev.h | 12 +++------- + drivers/net/hns3/hns3_ethdev_vf.c | 11 +++++----- + drivers/net/hns3/hns3_intr.c | 34 ++++++++++++++--------------- + 4 files changed, 63 insertions(+), 40 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index f6f1b3b..bba4d0f 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6343,7 +6343,7 @@ hns3_wait_hardware_ready(struct hns3_adapter *hns) + if (wait_data->result == HNS3_WAIT_SUCCESS) + return 0; + else if (wait_data->result == HNS3_WAIT_TIMEOUT) { +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + hns3_warn(hw, "Reset step4 hardware not ready after reset time=%ld.%.6ld", + tv.tv_sec, tv.tv_usec); + return -ETIME; +@@ -6353,7 +6353,7 @@ hns3_wait_hardware_ready(struct hns3_adapter *hns) + wait_data->hns = hns; + wait_data->check_completion = is_pf_reset_done; + wait_data->end_ms = (uint64_t)HNS3_RESET_WAIT_CNT * +- HNS3_RESET_WAIT_MS + get_timeofday_ms(); ++ HNS3_RESET_WAIT_MS + hns3_clock_gettime_ms(); + wait_data->interval = HNS3_RESET_WAIT_MS * USEC_PER_MSEC; + wait_data->count = HNS3_RESET_WAIT_CNT; + wait_data->result = HNS3_WAIT_REQUEST; +@@ -6392,7 +6392,7 @@ hns3_msix_process(struct hns3_adapter *hns, enum hns3_reset_level reset_level) + struct timeval tv; + uint32_t val; + +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + if (hns3_read_dev(hw, HNS3_GLOBAL_RESET_REG) || + hns3_read_dev(hw, HNS3_FUN_RST_ING)) { + hns3_warn(hw, "Don't process msix during resetting time=%ld.%.6ld", +@@ -6700,12 +6700,11 @@ hns3_reset_service(void *param) + */ + reset_level = hns3_get_reset_level(hns, &hw->reset.pending); + if (reset_level != HNS3_NONE_RESET) { +- gettimeofday(&tv_start, NULL); ++ hns3_clock_gettime(&tv_start); + ret = hns3_reset_process(hns, reset_level); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + timersub(&tv, &tv_start, &tv_delta); +- msec = tv_delta.tv_sec * MSEC_PER_SEC + +- tv_delta.tv_usec / USEC_PER_MSEC; ++ msec = hns3_clock_calctime_ms(&tv_delta); + if (msec > HNS3_RESET_PROCESS_MS) + hns3_err(hw, "%d handle long time delta %" PRIu64 + " ms time=%ld.%.6ld", +@@ -7205,6 +7204,39 @@ hns3_get_module_info(struct rte_eth_dev *dev, + return 0; + } + ++void ++hns3_clock_gettime(struct timeval *tv) ++{ ++#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */ ++#define CLOCK_TYPE CLOCK_MONOTONIC_RAW ++#else ++#define CLOCK_TYPE CLOCK_MONOTONIC ++#endif ++#define NSEC_TO_USEC_DIV 1000 ++ ++ struct timespec spec; ++ (void)clock_gettime(CLOCK_TYPE, &spec); ++ ++ tv->tv_sec = spec.tv_sec; ++ tv->tv_usec = spec.tv_nsec / NSEC_TO_USEC_DIV; ++} ++ ++uint64_t ++hns3_clock_calctime_ms(struct timeval *tv) ++{ ++ return (uint64_t)tv->tv_sec * MSEC_PER_SEC + ++ tv->tv_usec / USEC_PER_MSEC; ++} ++ ++uint64_t ++hns3_clock_gettime_ms(void) ++{ ++ struct timeval tv; ++ ++ hns3_clock_gettime(&tv); ++ return hns3_clock_calctime_ms(&tv); ++} ++ + static int + hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args) + { +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 29737c6..b65fb39 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -1022,15 +1022,9 @@ static inline uint32_t hns3_read_reg(void *base, uint32_t reg) + #define MSEC_PER_SEC 1000L + #define USEC_PER_MSEC 1000L + +-static inline uint64_t +-get_timeofday_ms(void) +-{ +- struct timeval tv; +- +- (void)gettimeofday(&tv, NULL); +- +- return (uint64_t)tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC; +-} ++void hns3_clock_gettime(struct timeval *tv); ++uint64_t hns3_clock_calctime_ms(struct timeval *tv); ++uint64_t hns3_clock_gettime_ms(void); + + static inline uint64_t + hns3_atomic_test_bit(unsigned int nr, volatile uint64_t *addr) +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 8ab3732..f4d2a9f 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2507,7 +2507,7 @@ hns3vf_wait_hardware_ready(struct hns3_adapter *hns) + hns3_warn(hw, "hardware is ready, delay 1 sec for PF reset complete"); + return -EAGAIN; + } else if (wait_data->result == HNS3_WAIT_TIMEOUT) { +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + hns3_warn(hw, "Reset step4 hardware not ready after reset time=%ld.%.6ld", + tv.tv_sec, tv.tv_usec); + return -ETIME; +@@ -2517,7 +2517,7 @@ hns3vf_wait_hardware_ready(struct hns3_adapter *hns) + wait_data->hns = hns; + wait_data->check_completion = is_vf_reset_done; + wait_data->end_ms = (uint64_t)HNS3VF_RESET_WAIT_CNT * +- HNS3VF_RESET_WAIT_MS + get_timeofday_ms(); ++ HNS3VF_RESET_WAIT_MS + hns3_clock_gettime_ms(); + wait_data->interval = HNS3VF_RESET_WAIT_MS * USEC_PER_MSEC; + wait_data->count = HNS3VF_RESET_WAIT_CNT; + wait_data->result = HNS3_WAIT_REQUEST; +@@ -2772,12 +2772,11 @@ hns3vf_reset_service(void *param) + */ + reset_level = hns3vf_get_reset_level(hw, &hw->reset.pending); + if (reset_level != HNS3_NONE_RESET) { +- gettimeofday(&tv_start, NULL); ++ hns3_clock_gettime(&tv_start); + hns3_reset_process(hns, reset_level); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + timersub(&tv, &tv_start, &tv_delta); +- msec = tv_delta.tv_sec * MSEC_PER_SEC + +- tv_delta.tv_usec / USEC_PER_MSEC; ++ msec = hns3_clock_calctime_ms(&tv_delta); + if (msec > HNS3_RESET_PROCESS_MS) + hns3_err(hw, "%d handle long time delta %" PRIu64 + " ms time=%ld.%.6ld", +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 7385c7b..482541b 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -2465,7 +2465,7 @@ hns3_wait_callback(void *param) + * Check if the current time exceeds the deadline + * or a pending reset coming, or reset during close. + */ +- msec = get_timeofday_ms(); ++ msec = hns3_clock_gettime_ms(); + if (msec > data->end_ms || is_reset_pending(hns) || + hw->adapter_state == HNS3_NIC_CLOSING) { + done = false; +@@ -2650,7 +2650,7 @@ hns3_reset_pre(struct hns3_adapter *hns) + __atomic_store_n(&hns->hw.reset.resetting, 1, __ATOMIC_RELAXED); + hw->reset.stage = RESET_STAGE_DOWN; + ret = hw->reset.ops->stop_service(hns); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + if (ret) { + hns3_warn(hw, "Reset step1 down fail=%d time=%ld.%.6ld", + ret, tv.tv_sec, tv.tv_usec); +@@ -2662,7 +2662,7 @@ hns3_reset_pre(struct hns3_adapter *hns) + } + if (hw->reset.stage == RESET_STAGE_PREWAIT) { + ret = hw->reset.ops->prepare_reset(hns); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + if (ret) { + hns3_warn(hw, + "Reset step2 prepare wait fail=%d time=%ld.%.6ld", +@@ -2700,7 +2700,7 @@ hns3_reset_post(struct hns3_adapter *hns) + } + ret = hw->reset.ops->reinit_dev(hns); + rte_spinlock_unlock(&hw->lock); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + if (ret) { + hns3_warn(hw, "Reset step5 devinit fail=%d retries=%d", + ret, hw->reset.retries); +@@ -2718,7 +2718,7 @@ hns3_reset_post(struct hns3_adapter *hns) + rte_spinlock_lock(&hw->lock); + ret = hw->reset.ops->restore_conf(hns); + rte_spinlock_unlock(&hw->lock); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + if (ret) { + hns3_warn(hw, + "Reset step6 restore fail=%d retries=%d", +@@ -2741,7 +2741,7 @@ hns3_reset_post(struct hns3_adapter *hns) + rte_spinlock_lock(&hw->lock); + hw->reset.ops->start_service(hns); + rte_spinlock_unlock(&hw->lock); +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + timersub(&tv, &hw->reset.start_time, &tv_delta); + hns3_warn(hw, "%s reset done fail_cnt:%" PRIx64 + " success_cnt:%" PRIx64 " global_cnt:%" PRIx64 +@@ -2753,10 +2753,9 @@ hns3_reset_post(struct hns3_adapter *hns) + hw->reset.stats.request_cnt, hw->reset.stats.exec_cnt, + hw->reset.stats.merge_cnt); + hns3_warn(hw, +- "%s reset done delta %ld ms time=%ld.%.6ld", ++ "%s reset done delta %" PRIu64 " ms time=%ld.%.6ld", + reset_string[hw->reset.level], +- tv_delta.tv_sec * MSEC_PER_SEC + +- tv_delta.tv_usec / USEC_PER_MSEC, ++ hns3_clock_calctime_ms(&tv_delta), + tv.tv_sec, tv.tv_usec); + hw->reset.level = HNS3_NONE_RESET; + } +@@ -2796,7 +2795,7 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) + if (hw->reset.level == HNS3_NONE_RESET) { + hw->reset.level = new_level; + hw->reset.stats.exec_cnt++; +- gettimeofday(&hw->reset.start_time, NULL); ++ hns3_clock_gettime(&hw->reset.start_time); + hns3_warn(hw, "Start %s reset time=%ld.%.6ld", + reset_string[hw->reset.level], + hw->reset.start_time.tv_sec, +@@ -2804,7 +2803,7 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) + } + + if (is_reset_pending(hns)) { +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + hns3_warn(hw, + "%s reset is aborted by high level time=%ld.%.6ld", + reset_string[hw->reset.level], tv.tv_sec, tv.tv_usec); +@@ -2822,7 +2821,7 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) + ret = hns3_reset_req_hw_reset(hns); + if (ret == -EAGAIN) + return ret; +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + hns3_warn(hw, + "Reset step3 request IMP reset success time=%ld.%.6ld", + tv.tv_sec, tv.tv_usec); +@@ -2833,7 +2832,7 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) + ret = hw->reset.ops->wait_hardware_ready(hns); + if (ret) + goto retry; +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + hns3_warn(hw, "Reset step4 reset wait success time=%ld.%.6ld", + tv.tv_sec, tv.tv_usec); + hw->reset.stage = RESET_STAGE_DEV_INIT; +@@ -2861,12 +2860,11 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) + rte_spinlock_unlock(&hw->lock); + __atomic_store_n(&hns->hw.reset.resetting, 0, __ATOMIC_RELAXED); + hw->reset.stage = RESET_STAGE_NONE; +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + timersub(&tv, &hw->reset.start_time, &tv_delta); +- hns3_warn(hw, "%s reset fail delta %ld ms time=%ld.%.6ld", ++ hns3_warn(hw, "%s reset fail delta %" PRIu64 " ms time=%ld.%.6ld", + reset_string[hw->reset.level], +- tv_delta.tv_sec * MSEC_PER_SEC + +- tv_delta.tv_usec / USEC_PER_MSEC, ++ hns3_clock_calctime_ms(&tv_delta), + tv.tv_sec, tv.tv_usec); + hw->reset.level = HNS3_NONE_RESET; + } +@@ -2898,7 +2896,7 @@ hns3_reset_abort(struct hns3_adapter *hns) + rte_eal_alarm_cancel(hns3_wait_callback, hw->reset.wait_data); + + if (hw->reset.level != HNS3_NONE_RESET) { +- gettimeofday(&tv, NULL); ++ hns3_clock_gettime(&tv); + hns3_err(hw, "Failed to terminate reset: %s time=%ld.%.6ld", + reset_string[hw->reset.level], tv.tv_sec, tv.tv_usec); + } +-- +2.7.4 + diff --git a/0143-net-hns3-select-Tx-prepare-based-on-Tx-offload.patch b/0143-net-hns3-select-Tx-prepare-based-on-Tx-offload.patch new file mode 100644 index 0000000..0de4aca --- /dev/null +++ b/0143-net-hns3-select-Tx-prepare-based-on-Tx-offload.patch @@ -0,0 +1,110 @@ +From 9392190f55c0eeef207370b4fcbc7f7249ee5231 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Wed, 28 Apr 2021 15:20:55 +0800 +Subject: [PATCH 143/189] net/hns3: select Tx prepare based on Tx offload + +Tx prepare should be called only when necessary to reduce the impact on +performance. + +For partial TX offload, users need to call rte_eth_tx_prepare() to +invoke the tx_prepare callback of PMDs. In this callback, the PMDs +adjust the packet based on the offloading used by the user. (e.g. For +some PMDs, pseudo-headers need to be calculated when the TX cksum is +offloaded.) + +However, for the users, they cannot grasp all the hardware and PMDs +characteristics. As a result, users cannot decide when they need to +actually call tx_prepare. Therefore, we should assume that the user +calls rte_eth_tx_prepare() when using any Tx offloading to ensure that +related functions work properly. Whether packets need to be adjusted +should be determined by PMDs. They can make judgments in the +dev_configure or queue_setup phase. When the related function is not +used, the pointer of tx_prepare should be set to NULL to reduce the +performance loss caused by invoking rte_eth_tx_repare(). + +In this patch, if tx_prepare is not required for the offloading used by +the users, the tx_prepare pointer will be set to NULL. + +Fixes: bba636698316 ("net/hns3: support Rx/Tx and related operations") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 36 +++++++++++++++++++++++++++++++++--- + 1 file changed, 33 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 92d377b..f4df3e2 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4203,17 +4203,45 @@ hns3_tx_check_simple_support(struct rte_eth_dev *dev) + return (offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE)); + } + ++static bool ++hns3_get_tx_prep_needed(struct rte_eth_dev *dev) ++{ ++#ifdef RTE_LIBRTE_ETHDEV_DEBUG ++ /* always perform tx_prepare when debug */ ++ return true; ++#else ++#define HNS3_DEV_TX_CSKUM_TSO_OFFLOAD_MASK (\ ++ DEV_TX_OFFLOAD_IPV4_CKSUM | \ ++ DEV_TX_OFFLOAD_TCP_CKSUM | \ ++ DEV_TX_OFFLOAD_UDP_CKSUM | \ ++ DEV_TX_OFFLOAD_SCTP_CKSUM | \ ++ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | \ ++ DEV_TX_OFFLOAD_OUTER_UDP_CKSUM | \ ++ DEV_TX_OFFLOAD_TCP_TSO | \ ++ DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \ ++ DEV_TX_OFFLOAD_GRE_TNL_TSO | \ ++ DEV_TX_OFFLOAD_GENEVE_TNL_TSO) ++ ++ uint64_t tx_offload = dev->data->dev_conf.txmode.offloads; ++ if (tx_offload & HNS3_DEV_TX_CSKUM_TSO_OFFLOAD_MASK) ++ return true; ++ ++ return false; ++#endif ++} ++ + static eth_tx_burst_t + hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + { + struct hns3_adapter *hns = dev->data->dev_private; + bool vec_allowed, sve_allowed, simple_allowed; +- bool vec_support; ++ bool vec_support, tx_prepare_needed; + + vec_support = hns3_tx_check_vec_support(dev) == 0; + vec_allowed = vec_support && hns3_get_default_vec_support(); + sve_allowed = vec_support && hns3_get_sve_support(); + simple_allowed = hns3_tx_check_simple_support(dev); ++ tx_prepare_needed = hns3_get_tx_prep_needed(dev); + + *prep = NULL; + +@@ -4224,7 +4252,8 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_SIMPLE && simple_allowed) + return hns3_xmit_pkts_simple; + if (hns->tx_func_hint == HNS3_IO_FUNC_HINT_COMMON) { +- *prep = hns3_prep_pkts; ++ if (tx_prepare_needed) ++ *prep = hns3_prep_pkts; + return hns3_xmit_pkts; + } + +@@ -4233,7 +4262,8 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + if (simple_allowed) + return hns3_xmit_pkts_simple; + +- *prep = hns3_prep_pkts; ++ if (tx_prepare_needed) ++ *prep = hns3_prep_pkts; + return hns3_xmit_pkts; + } + +-- +2.7.4 + diff --git a/0144-net-hns3-fix-MAC-enable-failure-rollback.patch b/0144-net-hns3-fix-MAC-enable-failure-rollback.patch new file mode 100644 index 0000000..6409e63 --- /dev/null +++ b/0144-net-hns3-fix-MAC-enable-failure-rollback.patch @@ -0,0 +1,40 @@ +From 16635e5c21b02e649d7babe0db6364bfaba71bc3 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 29 Apr 2021 17:03:59 +0800 +Subject: [PATCH 144/189] net/hns3: fix MAC enable failure rollback + +If driver fails to enable MAC, it does not need to rollback the MAC +configuration. This patch fixes it. + +Fixes: bdaf190f8235 ("net/hns3: support link speed autoneg for PF") + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index bba4d0f..f5160ed 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -5605,12 +5605,14 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + + ret = hns3_apply_link_speed(hw); + if (ret) +- goto err_config_mac_mode; ++ goto err_set_link_speed; + + return 0; + +-err_config_mac_mode: ++err_set_link_speed: + (void)hns3_cfg_mac_mode(hw, false); ++ ++err_config_mac_mode: + hns3_dev_release_mbufs(hns); + /* + * Here is exception handling, hns3_reset_all_tqps will have the +-- +2.7.4 + diff --git a/0145-net-hns3-fix-IEEE-1588-PTP-for-scalar-scattered-Rx.patch b/0145-net-hns3-fix-IEEE-1588-PTP-for-scalar-scattered-Rx.patch new file mode 100644 index 0000000..1969daf --- /dev/null +++ b/0145-net-hns3-fix-IEEE-1588-PTP-for-scalar-scattered-Rx.patch @@ -0,0 +1,45 @@ +From 3ac46c2a0e35e79fd2e9f9a8c0b05c71e944caae Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 29 Apr 2021 17:19:03 +0800 +Subject: [PATCH 145/189] net/hns3: fix IEEE 1588 PTP for scalar scattered Rx + +When jumbo frame is enabled, Rx function will choose 'Scalar Scattered' +function which has no PTP handling. + +This patch fixes it by adding PTP handling in 'Scalar Scattered' +function. + +Fixes: 38b539d96eb6 ("net/hns3: support IEEE 1588 PTP") + +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index f4df3e2..bc4a9a5 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -2654,6 +2654,9 @@ hns3_recv_scattered_pkts(void *rx_queue, + continue; + } + ++ if (unlikely(bd_base_info & BIT(HNS3_RXD_TS_VLD_B))) ++ hns3_rx_ptp_timestamp_handle(rxq, first_seg, rxdp); ++ + /* + * The last buffer of the received packet. packet len from + * buffer description may contains CRC len, packet len should +@@ -2704,6 +2707,9 @@ hns3_recv_scattered_pkts(void *rx_queue, + first_seg->packet_type = hns3_rx_calc_ptype(rxq, + l234_info, ol_info); + ++ if (first_seg->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) ++ rxm->ol_flags |= PKT_RX_IEEE1588_PTP; ++ + hns3_rxd_to_vlan_tci(rxq, first_seg, l234_info, &rxd); + + /* Increment bytes counter */ +-- +2.7.4 + diff --git a/0146-net-hns3-remove-some-unused-capabilities.patch b/0146-net-hns3-remove-some-unused-capabilities.patch new file mode 100644 index 0000000..0882538 --- /dev/null +++ b/0146-net-hns3-remove-some-unused-capabilities.patch @@ -0,0 +1,157 @@ +From f92b61b4be62100b35e5d3fb7513c12ef1148409 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 14:28:45 +0800 +Subject: [PATCH 146/189] net/hns3: remove some unused capabilities + +This patch deletes some unused capabilities, include: +1. Delete some unused firmware capabilities definition, which are: + UDP_GSO, ATR, INT_QL, SIMPLE_BD, TX_PUSH, FEC and PAUSE. +2. Delete some unused driver capabilities definition, which are: + UDP_GSO, TX_PUSH. +3. Also redefine HNS3_DEV_SUPPORT_* as enum type, and change some of + the values. Note: the HNS3_DEV_SUPPORT_* values is used only inside + the driver, so it's safe to change the values. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 11 ----------- + drivers/net/hns3/hns3_cmd.h | 17 +++++++---------- + drivers/net/hns3/hns3_ethdev.h | 29 +++++++++++------------------ + 3 files changed, 18 insertions(+), 39 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 5eb8789..a43385b 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -423,21 +423,14 @@ hns3_get_caps_name(uint32_t caps_id) + enum HNS3_CAPS_BITS caps; + const char *name; + } dev_caps[] = { +- { HNS3_CAPS_UDP_GSO_B, "udp_gso" }, +- { HNS3_CAPS_ATR_B, "atr" }, + { HNS3_CAPS_FD_QUEUE_REGION_B, "fd_queue_region" }, + { HNS3_CAPS_PTP_B, "ptp" }, +- { HNS3_CAPS_INT_QL_B, "int_ql" }, +- { HNS3_CAPS_SIMPLE_BD_B, "simple_bd" }, +- { HNS3_CAPS_TX_PUSH_B, "tx_push" }, + { HNS3_CAPS_PHY_IMP_B, "phy_imp" }, + { HNS3_CAPS_TQP_TXRX_INDEP_B, "tqp_txrx_indep" }, + { HNS3_CAPS_HW_PAD_B, "hw_pad" }, + { HNS3_CAPS_STASH_B, "stash" }, + { HNS3_CAPS_UDP_TUNNEL_CSUM_B, "udp_tunnel_csum" }, + { HNS3_CAPS_RAS_IMP_B, "ras_imp" }, +- { HNS3_CAPS_FEC_B, "fec" }, +- { HNS3_CAPS_PAUSE_B, "pause" }, + { HNS3_CAPS_RXD_ADV_LAYOUT_B, "rxd_adv_layout" } + }; + uint32_t i; +@@ -484,8 +477,6 @@ hns3_parse_capability(struct hns3_hw *hw, + { + uint32_t caps = rte_le_to_cpu_32(cmd->caps[0]); + +- if (hns3_get_bit(caps, HNS3_CAPS_UDP_GSO_B)) +- hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_UDP_GSO_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_FD_QUEUE_REGION_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B, + 1); +@@ -502,8 +493,6 @@ hns3_parse_capability(struct hns3_hw *hw, + hns3_warn(hw, "ignore PTP capability due to lack of " + "rxd advanced layout capability."); + } +- if (hns3_get_bit(caps, HNS3_CAPS_TX_PUSH_B)) +- hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_TX_PUSH_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B)) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 1); + if (hns3_get_bit(caps, HNS3_CAPS_TQP_TXRX_INDEP_B)) +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index 70aed7b..ac74e4d 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -306,22 +306,19 @@ struct hns3_rx_priv_buff_cmd { + #define HNS3_FW_VERSION_BYTE0_M GENMASK(7, 0) + + enum HNS3_CAPS_BITS { +- HNS3_CAPS_UDP_GSO_B, +- HNS3_CAPS_ATR_B, +- HNS3_CAPS_FD_QUEUE_REGION_B, ++ /* ++ * The following capability index definitions must be the same as those ++ * of the firmware. ++ */ ++ HNS3_CAPS_FD_QUEUE_REGION_B = 2, + HNS3_CAPS_PTP_B, +- HNS3_CAPS_INT_QL_B, +- HNS3_CAPS_SIMPLE_BD_B, +- HNS3_CAPS_TX_PUSH_B, +- HNS3_CAPS_PHY_IMP_B, ++ HNS3_CAPS_PHY_IMP_B = 7, + HNS3_CAPS_TQP_TXRX_INDEP_B, + HNS3_CAPS_HW_PAD_B, + HNS3_CAPS_STASH_B, + HNS3_CAPS_UDP_TUNNEL_CSUM_B, + HNS3_CAPS_RAS_IMP_B, +- HNS3_CAPS_FEC_B, +- HNS3_CAPS_PAUSE_B, +- HNS3_CAPS_RXD_ADV_LAYOUT_B, ++ HNS3_CAPS_RXD_ADV_LAYOUT_B = 15, + }; + + enum HNS3_API_CAP_BITS { +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index b65fb39..a57b20f 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -858,17 +858,17 @@ enum { + + #define HNS3_DEVARG_DEV_CAPS_MASK "dev_caps_mask" + +-#define HNS3_DEV_SUPPORT_DCB_B 0x0 +-#define HNS3_DEV_SUPPORT_COPPER_B 0x1 +-#define HNS3_DEV_SUPPORT_UDP_GSO_B 0x2 +-#define HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B 0x3 +-#define HNS3_DEV_SUPPORT_PTP_B 0x4 +-#define HNS3_DEV_SUPPORT_TX_PUSH_B 0x5 +-#define HNS3_DEV_SUPPORT_INDEP_TXRX_B 0x6 +-#define HNS3_DEV_SUPPORT_STASH_B 0x7 +-#define HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B 0x9 +-#define HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B 0xA +-#define HNS3_DEV_SUPPORT_RAS_IMP_B 0xB ++enum { ++ HNS3_DEV_SUPPORT_DCB_B, ++ HNS3_DEV_SUPPORT_COPPER_B, ++ HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B, ++ HNS3_DEV_SUPPORT_PTP_B, ++ HNS3_DEV_SUPPORT_INDEP_TXRX_B, ++ HNS3_DEV_SUPPORT_STASH_B, ++ HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, ++ HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, ++ HNS3_DEV_SUPPORT_RAS_IMP_B, ++}; + + #define hns3_dev_dcb_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_DCB_B) +@@ -877,10 +877,6 @@ enum { + #define hns3_dev_copper_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_COPPER_B) + +-/* Support UDP GSO offload */ +-#define hns3_dev_udp_gso_supported(hw) \ +- hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_UDP_GSO_B) +- + /* Support the queue region action rule of flow directory */ + #define hns3_dev_fd_queue_region_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B) +@@ -889,9 +885,6 @@ enum { + #define hns3_dev_ptp_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_PTP_B) + +-#define hns3_dev_tx_push_supported(hw) \ +- hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_TX_PUSH_B) +- + /* Support to Independently enable/disable/reset Tx or Rx queues */ + #define hns3_dev_indep_txrx_supported(hw) \ + hns3_get_bit((hw)->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B) +-- +2.7.4 + diff --git a/0147-net-hns3-refactor-optimised-register-write.patch b/0147-net-hns3-refactor-optimised-register-write.patch new file mode 100644 index 0000000..b3a0390 --- /dev/null +++ b/0147-net-hns3-refactor-optimised-register-write.patch @@ -0,0 +1,39 @@ +From b1c34695f2af22dfea670f424d35eb4d65376678 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 14:28:46 +0800 +Subject: [PATCH 147/189] net/hns3: refactor optimised register write + +This patch modifies hns3_write_reg_opt() API implementation because +the rte_write32() already uses rte_io_wmb(). + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index a57b20f..091512e 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -980,13 +980,13 @@ static inline void hns3_write_reg(void *base, uint32_t reg, uint32_t value) + } + + /* +- * The optimized function for writing registers used in the '.rx_pkt_burst' and +- * '.tx_pkt_burst' ops implementation function. ++ * The optimized function for writing registers reduces one address addition ++ * calculation, it was used in the '.rx_pkt_burst' and '.tx_pkt_burst' ops ++ * implementation function. + */ + static inline void hns3_write_reg_opt(volatile void *addr, uint32_t value) + { +- rte_io_wmb(); +- rte_write32_relaxed(rte_cpu_to_le_32(value), addr); ++ rte_write32(rte_cpu_to_le_32(value), addr); + } + + static inline uint32_t hns3_read_reg(void *base, uint32_t reg) +-- +2.7.4 + diff --git a/0148-net-hns3-use-existing-macro-to-get-array-size.patch b/0148-net-hns3-use-existing-macro-to-get-array-size.patch new file mode 100644 index 0000000..d137cb5 --- /dev/null +++ b/0148-net-hns3-use-existing-macro-to-get-array-size.patch @@ -0,0 +1,136 @@ +From 89b2b315c94308c77bdd662fa564c9d4a43bd647 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 14:28:47 +0800 +Subject: [PATCH 148/189] net/hns3: use existing macro to get array size + +This patch uses RTE_DIM() instead of ARRAY_SIZE(). + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.c | 4 ++-- + drivers/net/hns3/hns3_ethdev.h | 2 -- + drivers/net/hns3/hns3_flow.c | 18 +++++++++--------- + drivers/net/hns3/hns3_intr.c | 4 ++-- + 4 files changed, 13 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index a43385b..5f4d74d 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -245,7 +245,7 @@ hns3_is_special_opcode(uint16_t opcode) + HNS3_OPC_QUERY_ALL_ERR_INFO,}; + uint32_t i; + +- for (i = 0; i < ARRAY_SIZE(spec_opcode); i++) ++ for (i = 0; i < RTE_DIM(spec_opcode); i++) + if (spec_opcode[i] == opcode) + return true; + +@@ -276,7 +276,7 @@ hns3_cmd_convert_err_code(uint16_t desc_ret) + + uint32_t i; + +- for (i = 0; i < ARRAY_SIZE(hns3_cmdq_status); i++) ++ for (i = 0; i < RTE_DIM(hns3_cmdq_status); i++) + if (hns3_cmdq_status[i].imp_errcode == desc_ret) + return hns3_cmdq_status[i].linux_errcode; + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 091512e..00fedf0 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -1001,8 +1001,6 @@ static inline uint32_t hns3_read_reg(void *base, uint32_t reg) + #define hns3_read_dev(a, reg) \ + hns3_read_reg((a)->io_base, (reg)) + +-#define ARRAY_SIZE(x) RTE_DIM(x) +- + #define NEXT_ITEM_OF_ACTION(act, actions, index) \ + do { \ + act = (actions) + (index); \ +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index c07929f..1513992 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1054,37 +1054,37 @@ hns3_parse_normal(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + case RTE_FLOW_ITEM_TYPE_ETH: + ret = hns3_parse_eth(item, rule, error); + step_mngr->items = L2_next_items; +- step_mngr->count = ARRAY_SIZE(L2_next_items); ++ step_mngr->count = RTE_DIM(L2_next_items); + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + ret = hns3_parse_vlan(item, rule, error); + step_mngr->items = L2_next_items; +- step_mngr->count = ARRAY_SIZE(L2_next_items); ++ step_mngr->count = RTE_DIM(L2_next_items); + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + ret = hns3_parse_ipv4(item, rule, error); + step_mngr->items = L3_next_items; +- step_mngr->count = ARRAY_SIZE(L3_next_items); ++ step_mngr->count = RTE_DIM(L3_next_items); + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + ret = hns3_parse_ipv6(item, rule, error); + step_mngr->items = L3_next_items; +- step_mngr->count = ARRAY_SIZE(L3_next_items); ++ step_mngr->count = RTE_DIM(L3_next_items); + break; + case RTE_FLOW_ITEM_TYPE_TCP: + ret = hns3_parse_tcp(item, rule, error); + step_mngr->items = L4_next_items; +- step_mngr->count = ARRAY_SIZE(L4_next_items); ++ step_mngr->count = RTE_DIM(L4_next_items); + break; + case RTE_FLOW_ITEM_TYPE_UDP: + ret = hns3_parse_udp(item, rule, error); + step_mngr->items = L4_next_items; +- step_mngr->count = ARRAY_SIZE(L4_next_items); ++ step_mngr->count = RTE_DIM(L4_next_items); + break; + case RTE_FLOW_ITEM_TYPE_SCTP: + ret = hns3_parse_sctp(item, rule, error); + step_mngr->items = L4_next_items; +- step_mngr->count = ARRAY_SIZE(L4_next_items); ++ step_mngr->count = RTE_DIM(L4_next_items); + break; + default: + return rte_flow_error_set(error, ENOTSUP, +@@ -1188,7 +1188,7 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + "Fdir not supported in VF"); + + step_mngr.items = first_items; +- step_mngr.count = ARRAY_SIZE(first_items); ++ step_mngr.count = RTE_DIM(first_items); + for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { + if (item->type == RTE_FLOW_ITEM_TYPE_VOID) + continue; +@@ -1202,7 +1202,7 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + if (ret) + return ret; + step_mngr.items = tunnel_next_items; +- step_mngr.count = ARRAY_SIZE(tunnel_next_items); ++ step_mngr.count = RTE_DIM(tunnel_next_items); + } else { + ret = hns3_parse_normal(item, rule, &step_mngr, error); + if (ret) +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 482541b..e216788 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -2206,8 +2206,8 @@ hns3_handle_type_reg_error_data(struct hns3_hw *hw, + type_id = err_info->type_id & HNS3_ERR_TYPE_MASK; + is_ras = err_info->type_id >> HNS3_ERR_TYPE_IS_RAS_OFFSET; + +- total_module = ARRAY_SIZE(hns3_hw_module_name); +- total_type = ARRAY_SIZE(hns3_hw_error_type); ++ total_module = RTE_DIM(hns3_hw_module_name); ++ total_type = RTE_DIM(hns3_hw_error_type); + + hns3_err(hw, "total_module:%u, total_type:%u", + total_module, total_type); +-- +2.7.4 + diff --git a/0149-net-hns3-improve-IO-path-data-cache-usage.patch b/0149-net-hns3-improve-IO-path-data-cache-usage.patch new file mode 100644 index 0000000..4b8d033 --- /dev/null +++ b/0149-net-hns3-improve-IO-path-data-cache-usage.patch @@ -0,0 +1,259 @@ +From 73fce35c11863c8cccc5444f054e5820f303e9bd Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 14:28:48 +0800 +Subject: [PATCH 149/189] net/hns3: improve IO path data cache usage + +This patch improves data cache usage by: +1. Rearrange the rxq frequency accessed fields in the IO path to the + first 128B. +2. Rearrange the txq frequency accessed fields in the IO path to the + first 64B. +3. Make sure ptype table align cacheline size which is 128B instead of + min cacheline size which is 64B because the L1/L2 is 64B and L3 is + 128B on Kunpeng ARM platform. + +The performance gains are 1.5% in 64B packet macfwd scenarios. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 4 +- + drivers/net/hns3/hns3_rxtx.h | 126 ++++++++++++++++++++++++----------------- + 2 files changed, 77 insertions(+), 53 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 00fedf0..c70950a 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -738,7 +738,7 @@ struct hns3_ptype_table { + * descriptor, it functions only when firmware report the capability of + * HNS3_CAPS_RXD_ADV_LAYOUT_B and driver enabled it. + */ +- uint32_t ptype[HNS3_PTYPE_NUM] __rte_cache_min_aligned; ++ uint32_t ptype[HNS3_PTYPE_NUM] __rte_cache_aligned; + }; + + #define HNS3_FIXED_MAX_TQP_NUM_MODE 0 +@@ -842,7 +842,7 @@ struct hns3_adapter { + + uint64_t dev_caps_mask; + +- struct hns3_ptype_table ptype_tbl __rte_cache_min_aligned; ++ struct hns3_ptype_table ptype_tbl __rte_cache_aligned; + }; + + enum { +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 92f01ed..811be96 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -289,22 +289,14 @@ struct hns3_rx_bd_errors_stats { + }; + + struct hns3_rx_queue { +- void *io_base; + volatile void *io_head_reg; +- struct hns3_adapter *hns; + struct hns3_ptype_table *ptype_tbl; + struct rte_mempool *mb_pool; + struct hns3_desc *rx_ring; +- uint64_t rx_ring_phys_addr; /* RX ring DMA address */ +- const struct rte_memzone *mz; + struct hns3_entry *sw_ring; +- struct rte_mbuf *pkt_first_seg; +- struct rte_mbuf *pkt_last_seg; + +- uint16_t queue_id; + uint16_t port_id; + uint16_t nb_rx_desc; +- uint16_t rx_buf_len; + /* + * threshold for the number of BDs waited to passed to hardware. If the + * number exceeds the threshold, driver will pass these BDs to hardware. +@@ -318,8 +310,6 @@ struct hns3_rx_queue { + /* 4 if DEV_RX_OFFLOAD_KEEP_CRC offload set, 0 otherwise */ + uint8_t crc_len; + +- bool rx_deferred_start; /* don't start this queue in dev start */ +- bool configured; /* indicate if rx queue has been configured */ + /* + * Indicate whether ignore the outer VLAN field in the Rx BD reported + * by the Hardware. Because the outer VLAN is the PVID if the PVID is +@@ -331,23 +321,45 @@ struct hns3_rx_queue { + * driver does not need to perform PVID-related operation in Rx. At this + * point, the pvid_sw_discard_en will be false. + */ +- bool pvid_sw_discard_en; +- bool ptype_en; /* indicate if the ptype field enabled */ +- bool enabled; /* indicate if Rx queue has been enabled */ ++ uint8_t pvid_sw_discard_en:1; ++ uint8_t ptype_en:1; /* indicate if the ptype field enabled */ ++ ++ uint64_t mbuf_initializer; /* value to init mbufs used with vector rx */ ++ /* offset_table: used for vector, to solve execute re-order problem */ ++ uint8_t offset_table[HNS3_VECTOR_RX_OFFSET_TABLE_LEN + 1]; ++ ++ uint16_t bulk_mbuf_num; /* indicate bulk_mbuf valid nums */ + + struct hns3_rx_basic_stats basic_stats; ++ ++ struct rte_mbuf *pkt_first_seg; ++ struct rte_mbuf *pkt_last_seg; ++ ++ struct rte_mbuf *bulk_mbuf[HNS3_BULK_ALLOC_MBUF_NUM]; ++ + /* DFX statistics that driver does not need to discard packets */ + struct hns3_rx_dfx_stats dfx_stats; + /* Error statistics that driver needs to discard packets */ + struct hns3_rx_bd_errors_stats err_stats; + +- struct rte_mbuf *bulk_mbuf[HNS3_BULK_ALLOC_MBUF_NUM]; +- uint16_t bulk_mbuf_num; +- +- /* offset_table: used for vector, to solve execute re-order problem */ +- uint8_t offset_table[HNS3_VECTOR_RX_OFFSET_TABLE_LEN + 1]; +- uint64_t mbuf_initializer; /* value to init mbufs used with vector rx */ + struct rte_mbuf fake_mbuf; /* fake mbuf used with vector rx */ ++ ++ ++ /* ++ * The following fields are not accessed in the I/O path, so they are ++ * placed at the end. ++ */ ++ void *io_base; ++ struct hns3_adapter *hns; ++ uint64_t rx_ring_phys_addr; /* RX ring DMA address */ ++ const struct rte_memzone *mz; ++ ++ uint16_t queue_id; ++ uint16_t rx_buf_len; ++ ++ bool configured; /* indicate if rx queue has been configured */ ++ bool rx_deferred_start; /* don't start this queue in dev start */ ++ bool enabled; /* indicate if Rx queue has been enabled */ + }; + + struct hns3_tx_basic_stats { +@@ -407,16 +419,10 @@ struct hns3_tx_dfx_stats { + }; + + struct hns3_tx_queue { +- void *io_base; + volatile void *io_tail_reg; +- struct hns3_adapter *hns; + struct hns3_desc *tx_ring; +- uint64_t tx_ring_phys_addr; /* TX ring DMA address */ +- const struct rte_memzone *mz; + struct hns3_entry *sw_ring; + +- uint16_t queue_id; +- uint16_t port_id; + uint16_t nb_tx_desc; + /* + * index of next BD whose corresponding rte_mbuf can be released by +@@ -432,21 +438,12 @@ struct hns3_tx_queue { + uint16_t tx_free_thresh; + + /* +- * For better performance in tx datapath, releasing mbuf in batches is +- * required. +- * Only checking the VLD bit of the last descriptor in a batch of the +- * thresh descriptors does not mean that these descriptors are all sent +- * by hardware successfully. So we need to check that the VLD bits of +- * all descriptors are cleared. and then free all mbufs in the batch. +- * - tx_rs_thresh +- * Number of mbufs released at a time. +- * +- * - free +- * Tx mbuf free array used for preserving temporarily address of mbuf +- * released back to mempool, when releasing mbuf in batches. ++ * The minimum length of the packet supported by hardware in the Tx ++ * direction. + */ +- uint16_t tx_rs_thresh; +- struct rte_mbuf **free; ++ uint8_t min_tx_pkt_len; ++ ++ uint8_t max_non_tso_bd_num; /* max BD number of one non-TSO packet */ + + /* + * tso mode. +@@ -464,7 +461,7 @@ struct hns3_tx_queue { + * checksum of packets that need TSO, so network driver software + * not need to recalculate it. + */ +- uint8_t tso_mode; ++ uint16_t tso_mode:1; + /* + * udp checksum mode. + * value range: +@@ -480,16 +477,10 @@ struct hns3_tx_queue { + * In this mode, HW does not have the preceding problems and can + * directly calculate the checksum of these UDP packets. + */ +- uint8_t udp_cksum_mode; +- /* +- * The minimum length of the packet supported by hardware in the Tx +- * direction. +- */ +- uint32_t min_tx_pkt_len; ++ uint16_t udp_cksum_mode:1; + +- uint8_t max_non_tso_bd_num; /* max BD number of one non-TSO packet */ +- bool tx_deferred_start; /* don't start this queue in dev start */ +- bool configured; /* indicate if tx queue has been configured */ ++ uint16_t simple_bd_enable:1; ++ uint16_t tx_push_enable:1; /* check whether the tx push is enabled */ + /* + * Indicate whether add the vlan_tci of the mbuf to the inner VLAN field + * of Tx BD. Because the outer VLAN will always be the PVID when the +@@ -502,11 +493,44 @@ struct hns3_tx_queue { + * PVID-related operations in Tx. And pvid_sw_shift_en will be false at + * this point. + */ +- bool pvid_sw_shift_en; +- bool enabled; /* indicate if Tx queue has been enabled */ ++ uint16_t pvid_sw_shift_en:1; ++ ++ /* ++ * For better performance in tx datapath, releasing mbuf in batches is ++ * required. ++ * Only checking the VLD bit of the last descriptor in a batch of the ++ * thresh descriptors does not mean that these descriptors are all sent ++ * by hardware successfully. So we need to check that the VLD bits of ++ * all descriptors are cleared. and then free all mbufs in the batch. ++ * - tx_rs_thresh ++ * Number of mbufs released at a time. ++ * ++ * - free ++ * Tx mbuf free array used for preserving temporarily address of mbuf ++ * released back to mempool, when releasing mbuf in batches. ++ */ ++ uint16_t tx_rs_thresh; ++ struct rte_mbuf **free; + + struct hns3_tx_basic_stats basic_stats; + struct hns3_tx_dfx_stats dfx_stats; ++ ++ ++ /* ++ * The following fields are not accessed in the I/O path, so they are ++ * placed at the end. ++ */ ++ void *io_base; ++ struct hns3_adapter *hns; ++ uint64_t tx_ring_phys_addr; /* TX ring DMA address */ ++ const struct rte_memzone *mz; ++ ++ uint16_t port_id; ++ uint16_t queue_id; ++ ++ bool configured; /* indicate if tx queue has been configured */ ++ bool tx_deferred_start; /* don't start this queue in dev start */ ++ bool enabled; /* indicate if Tx queue has been enabled */ + }; + + #define HNS3_GET_TX_QUEUE_PEND_BD_NUM(txq) \ +-- +2.7.4 + diff --git a/0150-net-hns3-log-flow-director-configuration.patch b/0150-net-hns3-log-flow-director-configuration.patch new file mode 100644 index 0000000..dc5d53e --- /dev/null +++ b/0150-net-hns3-log-flow-director-configuration.patch @@ -0,0 +1,63 @@ +From e1dc71a6850185aef917b37495c41a6da8017cee Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 14:28:49 +0800 +Subject: [PATCH 150/189] net/hns3: log flow director configuration + +The rte flow interface does not support the API of the capability +set. Therefore, fdir configuration logs are added to facilitate +debugging. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_fdir.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index 06c9a94..06dd51b 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -336,6 +336,8 @@ int hns3_init_fd_config(struct hns3_adapter *hns) + BIT(INNER_IP_PROTO) | BIT(INNER_IP_TOS) | + BIT(INNER_SRC_IP) | BIT(INNER_DST_IP) | + BIT(INNER_SRC_PORT) | BIT(INNER_DST_PORT); ++ hns3_dbg(hw, "fdir tuple: inner"); + + /* If use max 400bit key, we can support tuples for ether type */ + if (pf->fdir.fd_cfg.max_key_length == MAX_KEY_LENGTH) { +@@ -345,6 +347,9 @@ int hns3_init_fd_config(struct hns3_adapter *hns) + BIT(OUTER_DST_PORT) | BIT(INNER_VLAN_TAG2) | + BIT(OUTER_TUN_VNI) | BIT(OUTER_TUN_FLOW_ID) | + BIT(OUTER_ETH_TYPE) | BIT(OUTER_IP_PROTO); ++ hns3_dbg(hw, "fdir tuple more: inner outer"); + } + + /* roce_type is used to filter roce frames +@@ -352,6 +357,7 @@ int hns3_init_fd_config(struct hns3_adapter *hns) + */ + key_cfg->meta_data_active = BIT(DST_VPORT) | BIT(TUNNEL_PACKET) | + BIT(VLAN_NUMBER); ++ hns3_dbg(hw, "fdir meta data: dst_vport tunnel_packet vlan_number"); + + ret = hns3_get_fd_allocation(hw, + &pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1], +@@ -361,6 +367,13 @@ int hns3_init_fd_config(struct hns3_adapter *hns) + if (ret) + return ret; + ++ hns3_dbg(hw, "fdir: stage1 stage2", ++ pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1], ++ pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1], ++ pf->fdir.fd_cfg.rule_num[HNS3_FD_STAGE_2], ++ pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_2]); ++ + return hns3_set_fd_key_config(hns); + } + +-- +2.7.4 + diff --git a/0151-net-hns3-fix-vector-Rx-burst-limitation.patch b/0151-net-hns3-fix-vector-Rx-burst-limitation.patch new file mode 100644 index 0000000..e59039c --- /dev/null +++ b/0151-net-hns3-fix-vector-Rx-burst-limitation.patch @@ -0,0 +1,167 @@ +From 2cd4eb1717633e841cb1e20ba123a20adf550638 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 14:28:50 +0800 +Subject: [PATCH 151/189] net/hns3: fix vector Rx burst limitation + +Currently, driver uses the macro HNS3_DEFAULT_RX_BURST whose value is +32 to limit the vector Rx burst size, as a result, the burst size +can't exceed 32. + +This patch fixes this problem by support big burst size. +Also adjust HNS3_DEFAULT_RX_BURST to 64 as it performs better than 32. + +Fixes: a3d4f4d291d7 ("net/hns3: support NEON Rx") +Fixes: 952ebacce4f2 ("net/hns3: support SVE Rx") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_rxtx.h | 2 +- + drivers/net/hns3/hns3_rxtx_vec.c | 36 ++++++++++++++++++++++++++++-------- + drivers/net/hns3/hns3_rxtx_vec.h | 3 +++ + drivers/net/hns3/hns3_rxtx_vec_sve.c | 32 ++++++++++++++++++++++++++------ + 4 files changed, 58 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 811be96..a42ab71 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -20,7 +20,7 @@ + #define HNS3_DEFAULT_TX_RS_THRESH 32 + #define HNS3_TX_FAST_FREE_AHEAD 64 + +-#define HNS3_DEFAULT_RX_BURST 32 ++#define HNS3_DEFAULT_RX_BURST 64 + #if (HNS3_DEFAULT_RX_BURST > 64) + #error "PMD HNS3: HNS3_DEFAULT_RX_BURST must <= 64\n" + #endif +diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c +index d6636df..5fdc1d5 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.c ++++ b/drivers/net/hns3/hns3_rxtx_vec.c +@@ -108,14 +108,13 @@ hns3_recv_pkts_vec(void *__restrict rx_queue, + { + struct hns3_rx_queue *rxq = rx_queue; + struct hns3_desc *rxdp = &rxq->rx_ring[rxq->next_to_use]; +- uint64_t bd_err_mask; /* bit mask indicate whick pkts is error */ ++ uint64_t pkt_err_mask; /* bit mask indicate whick pkts is error */ + uint16_t nb_rx; + +- nb_pkts = RTE_MIN(nb_pkts, HNS3_DEFAULT_RX_BURST); +- nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, HNS3_DEFAULT_DESCS_PER_LOOP); +- + rte_prefetch_non_temporal(rxdp); + ++ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, HNS3_DEFAULT_DESCS_PER_LOOP); ++ + if (rxq->rx_rearm_nb > HNS3_DEFAULT_RXQ_REARM_THRESH) + hns3_rxq_rearm_mbuf(rxq); + +@@ -128,10 +127,31 @@ hns3_recv_pkts_vec(void *__restrict rx_queue, + rte_prefetch0(rxq->sw_ring[rxq->next_to_use + 2].mbuf); + rte_prefetch0(rxq->sw_ring[rxq->next_to_use + 3].mbuf); + +- bd_err_mask = 0; +- nb_rx = hns3_recv_burst_vec(rxq, rx_pkts, nb_pkts, &bd_err_mask); +- if (unlikely(bd_err_mask)) +- nb_rx = hns3_rx_reassemble_pkts(rx_pkts, nb_rx, bd_err_mask); ++ if (likely(nb_pkts <= HNS3_DEFAULT_RX_BURST)) { ++ pkt_err_mask = 0; ++ nb_rx = hns3_recv_burst_vec(rxq, rx_pkts, nb_pkts, ++ &pkt_err_mask); ++ nb_rx = hns3_rx_reassemble_pkts(rx_pkts, nb_rx, pkt_err_mask); ++ return nb_rx; ++ } ++ ++ nb_rx = 0; ++ while (nb_pkts > 0) { ++ uint16_t ret, n; ++ ++ n = RTE_MIN(nb_pkts, HNS3_DEFAULT_RX_BURST); ++ pkt_err_mask = 0; ++ ret = hns3_recv_burst_vec(rxq, &rx_pkts[nb_rx], n, ++ &pkt_err_mask); ++ nb_pkts -= ret; ++ nb_rx += hns3_rx_reassemble_pkts(&rx_pkts[nb_rx], ret, ++ pkt_err_mask); ++ if (ret < n) ++ break; ++ ++ if (rxq->rx_rearm_nb > HNS3_DEFAULT_RXQ_REARM_THRESH) ++ hns3_rxq_rearm_mbuf(rxq); ++ } + + return nb_rx; + } +diff --git a/drivers/net/hns3/hns3_rxtx_vec.h b/drivers/net/hns3/hns3_rxtx_vec.h +index 35d9903..872ba22 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec.h ++++ b/drivers/net/hns3/hns3_rxtx_vec.h +@@ -71,6 +71,9 @@ hns3_rx_reassemble_pkts(struct rte_mbuf **rx_pkts, + uint16_t count, i; + uint64_t mask; + ++ if (likely(pkt_err_mask == 0)) ++ return nb_pkts; ++ + count = 0; + for (i = 0; i < nb_pkts; i++) { + mask = ((uint64_t)1u) << i; +diff --git a/drivers/net/hns3/hns3_rxtx_vec_sve.c b/drivers/net/hns3/hns3_rxtx_vec_sve.c +index e15fd7a..be9a4ff 100644 +--- a/drivers/net/hns3/hns3_rxtx_vec_sve.c ++++ b/drivers/net/hns3/hns3_rxtx_vec_sve.c +@@ -292,12 +292,11 @@ hns3_recv_pkts_vec_sve(void *__restrict rx_queue, + { + struct hns3_rx_queue *rxq = rx_queue; + struct hns3_desc *rxdp = &rxq->rx_ring[rxq->next_to_use]; +- uint64_t bd_err_mask; /* bit mask indicate whick pkts is error */ ++ uint64_t pkt_err_mask; /* bit mask indicate whick pkts is error */ + uint16_t nb_rx; + + rte_prefetch_non_temporal(rxdp); + +- nb_pkts = RTE_MIN(nb_pkts, HNS3_DEFAULT_RX_BURST); + nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, HNS3_SVE_DEFAULT_DESCS_PER_LOOP); + + if (rxq->rx_rearm_nb > HNS3_DEFAULT_RXQ_REARM_THRESH) +@@ -309,10 +308,31 @@ hns3_recv_pkts_vec_sve(void *__restrict rx_queue, + + hns3_rx_prefetch_mbuf_sve(&rxq->sw_ring[rxq->next_to_use]); + +- bd_err_mask = 0; +- nb_rx = hns3_recv_burst_vec_sve(rxq, rx_pkts, nb_pkts, &bd_err_mask); +- if (unlikely(bd_err_mask)) +- nb_rx = hns3_rx_reassemble_pkts(rx_pkts, nb_rx, bd_err_mask); ++ if (likely(nb_pkts <= HNS3_DEFAULT_RX_BURST)) { ++ pkt_err_mask = 0; ++ nb_rx = hns3_recv_burst_vec_sve(rxq, rx_pkts, nb_pkts, ++ &pkt_err_mask); ++ nb_rx = hns3_rx_reassemble_pkts(rx_pkts, nb_rx, pkt_err_mask); ++ return nb_rx; ++ } ++ ++ nb_rx = 0; ++ while (nb_pkts > 0) { ++ uint16_t ret, n; ++ ++ n = RTE_MIN(nb_pkts, HNS3_DEFAULT_RX_BURST); ++ pkt_err_mask = 0; ++ ret = hns3_recv_burst_vec_sve(rxq, &rx_pkts[nb_rx], n, ++ &pkt_err_mask); ++ nb_pkts -= ret; ++ nb_rx += hns3_rx_reassemble_pkts(&rx_pkts[nb_rx], ret, ++ pkt_err_mask); ++ if (ret < n) ++ break; ++ ++ if (rxq->rx_rearm_nb > HNS3_DEFAULT_RXQ_REARM_THRESH) ++ hns3_rxq_rearm_mbuf_sve(rxq); ++ } + + return nb_rx; + } +-- +2.7.4 + diff --git a/0152-net-hns3-remove-read-when-enabling-TM-QCN-error-even.patch b/0152-net-hns3-remove-read-when-enabling-TM-QCN-error-even.patch new file mode 100644 index 0000000..ef7023a --- /dev/null +++ b/0152-net-hns3-remove-read-when-enabling-TM-QCN-error-even.patch @@ -0,0 +1,41 @@ +From 44d86d6218b9da9d8218a629011ddd432a27a67c Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 17:04:02 +0800 +Subject: [PATCH 152/189] net/hns3: remove read when enabling TM QCN error + event + +According to the HW manual, the read operation is unnecessary when +enabling TM QCN error event, so remove it. + +Fixes: f53a793bb7c2 ("net/hns3: add more hardware error types") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_intr.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index e216788..87afce2 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -1782,14 +1782,7 @@ enable_tm_err_intr(struct hns3_adapter *hns, bool en) + } + + /* configure TM QCN hw errors */ +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_TM_QCN_MEM_INT_CFG, true); +- ret = hns3_cmd_send(hw, &desc, 1); +- if (ret) { +- hns3_err(hw, "fail to read TM QCN CFG status, ret = %d\n", ret); +- return ret; +- } +- +- hns3_cmd_reuse_desc(&desc, false); ++ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_TM_QCN_MEM_INT_CFG, false); + if (en) + desc.data[1] = rte_cpu_to_le_32(HNS3_TM_QCN_MEM_ERR_INT_EN); + +-- +2.7.4 + diff --git a/0153-net-hns3-remove-unused-VMDq-code.patch b/0153-net-hns3-remove-unused-VMDq-code.patch new file mode 100644 index 0000000..91e8b18 --- /dev/null +++ b/0153-net-hns3-remove-unused-VMDq-code.patch @@ -0,0 +1,83 @@ +From 4a924045f23a81a07b59233f7bc12c1e38daa234 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 17:04:03 +0800 +Subject: [PATCH 153/189] net/hns3: remove unused VMDq code + +VMDq is not supported yet, so remove the unused code. + +Fixes: d51867db65c1 ("net/hns3: add initialization") +Fixes: 1265b5372d9d ("net/hns3: add some definitions for data structure and macro") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_cmd.h | 2 -- + drivers/net/hns3/hns3_ethdev.c | 4 ---- + drivers/net/hns3/hns3_ethdev.h | 1 - + drivers/net/hns3/hns3_ethdev_vf.c | 2 -- + 4 files changed, 9 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h +index ac74e4d..a249a7a 100644 +--- a/drivers/net/hns3/hns3_cmd.h ++++ b/drivers/net/hns3/hns3_cmd.h +@@ -457,8 +457,6 @@ struct hns3_umv_spc_alc_cmd { + #define HNS3_CFG_RD_LEN_BYTES 16 + #define HNS3_CFG_RD_LEN_UNIT 4 + +-#define HNS3_CFG_VMDQ_S 0 +-#define HNS3_CFG_VMDQ_M GENMASK(7, 0) + #define HNS3_CFG_TC_NUM_S 8 + #define HNS3_CFG_TC_NUM_M GENMASK(15, 8) + #define HNS3_CFG_TQP_DESC_N_S 16 +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index f5160ed..44e6c5b 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2791,8 +2791,6 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + .offloads = 0, + }; + +- info->vmdq_queue_num = 0; +- + info->reta_size = hw->rss_ind_tbl_size; + info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; +@@ -3072,8 +3070,6 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) + req = (struct hns3_cfg_param_cmd *)desc[0].data; + + /* get the configuration */ +- cfg->vmdq_vport_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), +- HNS3_CFG_VMDQ_M, HNS3_CFG_VMDQ_S); + cfg->tc_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), + HNS3_CFG_TC_NUM_M, HNS3_CFG_TC_NUM_S); + cfg->tqp_desc_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index c70950a..53dc498 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -155,7 +155,6 @@ struct hns3_tc_queue_info { + }; + + struct hns3_cfg { +- uint8_t vmdq_vport_num; + uint8_t tc_num; + uint16_t tqp_desc_num; + uint16_t rx_buf_len; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index f4d2a9f..c4419fb 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1022,8 +1022,6 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) + .offloads = 0, + }; + +- info->vmdq_queue_num = 0; +- + info->reta_size = hw->rss_ind_tbl_size; + info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; +-- +2.7.4 + diff --git a/0154-net-hns3-increase-readability-in-logs.patch b/0154-net-hns3-increase-readability-in-logs.patch new file mode 100644 index 0000000..7a0ec42 --- /dev/null +++ b/0154-net-hns3-increase-readability-in-logs.patch @@ -0,0 +1,131 @@ +From c693525d0f4a24e9717d80d13a9690ae1b4dc01d Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 30 Apr 2021 17:04:04 +0800 +Subject: [PATCH 154/189] net/hns3: increase readability in logs + +Some logs format u64 variables, mostly using hexadecimal which was not +readable. +This patch formats most u64 variables in decimal, and add '0x' prefix +to the ones that are not adjusted. + +Fixes: c37ca66f2b27 ("net/hns3: support RSS") +Fixes: 2790c6464725 ("net/hns3: support device reset") +Fixes: 8839c5e202f3 ("net/hns3: support device stats") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_flow.c | 2 +- + drivers/net/hns3/hns3_intr.c | 20 ++++++++++---------- + drivers/net/hns3/hns3_stats.c | 8 ++++---- + 3 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 1513992..15ecaf4 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1556,7 +1556,7 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, + hw->rss_info.conf.types; + if (flow_types != rss_flow_conf.types) + hns3_warn(hw, "modified RSS types based on hardware support, " +- "requested:%" PRIx64 " configured:%" PRIx64, ++ "requested:0x%" PRIx64 " configured:0x%" PRIx64, + rss_flow_conf.types, flow_types); + /* Update the useful flow types */ + rss_flow_conf.types = flow_types; +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 87afce2..0140260 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -2570,7 +2570,7 @@ hns3_clear_reset_level(struct hns3_hw *hw, uint64_t *levels) + if (merge_cnt != hw->reset.stats.merge_cnt) + hns3_warn(hw, + "No need to do low-level reset after %s reset. " +- "merge cnt: %" PRIx64 " total merge cnt: %" PRIx64, ++ "merge cnt: %" PRIu64 " total merge cnt: %" PRIu64, + reset_string[hw->reset.level], + hw->reset.stats.merge_cnt - merge_cnt, + hw->reset.stats.merge_cnt); +@@ -2590,7 +2590,7 @@ hns3_reset_err_handle(struct hns3_adapter *hns) + hw->reset.attempts = 0; + hw->reset.stats.fail_cnt++; + hns3_warn(hw, "%s reset fail because new Reset is pending " +- "attempts:%" PRIx64, ++ "attempts:%" PRIu64, + reset_string[hw->reset.level], + hw->reset.stats.fail_cnt); + hw->reset.level = HNS3_NONE_RESET; +@@ -2617,10 +2617,10 @@ hns3_reset_err_handle(struct hns3_adapter *hns) + reset_fail: + hw->reset.attempts = 0; + hw->reset.stats.fail_cnt++; +- hns3_warn(hw, "%s reset fail fail_cnt:%" PRIx64 " success_cnt:%" PRIx64 +- " global_cnt:%" PRIx64 " imp_cnt:%" PRIx64 +- " request_cnt:%" PRIx64 " exec_cnt:%" PRIx64 +- " merge_cnt:%" PRIx64 "adapter_state:%d", ++ hns3_warn(hw, "%s reset fail fail_cnt:%" PRIu64 " success_cnt:%" PRIu64 ++ " global_cnt:%" PRIu64 " imp_cnt:%" PRIu64 ++ " request_cnt:%" PRIu64 " exec_cnt:%" PRIu64 ++ " merge_cnt:%" PRIu64 "adapter_state:%d", + reset_string[hw->reset.level], hw->reset.stats.fail_cnt, + hw->reset.stats.success_cnt, hw->reset.stats.global_cnt, + hw->reset.stats.imp_cnt, hw->reset.stats.request_cnt, +@@ -2736,10 +2736,10 @@ hns3_reset_post(struct hns3_adapter *hns) + rte_spinlock_unlock(&hw->lock); + hns3_clock_gettime(&tv); + timersub(&tv, &hw->reset.start_time, &tv_delta); +- hns3_warn(hw, "%s reset done fail_cnt:%" PRIx64 +- " success_cnt:%" PRIx64 " global_cnt:%" PRIx64 +- " imp_cnt:%" PRIx64 " request_cnt:%" PRIx64 +- " exec_cnt:%" PRIx64 " merge_cnt:%" PRIx64, ++ hns3_warn(hw, "%s reset done fail_cnt:%" PRIu64 ++ " success_cnt:%" PRIu64 " global_cnt:%" PRIu64 ++ " imp_cnt:%" PRIu64 " request_cnt:%" PRIu64 ++ " exec_cnt:%" PRIu64 " merge_cnt:%" PRIu64, + reset_string[hw->reset.level], + hw->reset.stats.fail_cnt, hw->reset.stats.success_cnt, + hw->reset.stats.global_cnt, hw->reset.stats.imp_cnt, +diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c +index 1af689f..464a33d 100644 +--- a/drivers/net/hns3/hns3_stats.c ++++ b/drivers/net/hns3/hns3_stats.c +@@ -1325,7 +1325,7 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + 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 " ++ hns3_err(hw, "Failed to allocate 0x%" PRIx64 " bytes needed " + "to store statistics values", len); + return -ENOMEM; + } +@@ -1347,7 +1347,7 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + + for (i = 0; i < size; i++) { + if (ids[i] >= cnt_stats) { +- hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, " ++ hns3_err(hw, "ids[%u] (%" PRIu64 ") is invalid, " + "should < %u", i, ids[i], cnt_stats); + rte_free(values_copy); + return -EINVAL; +@@ -1406,7 +1406,7 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, + len = cnt_stats * sizeof(struct rte_eth_xstat_name); + names_copy = rte_zmalloc("hns3_xstats_names", len, 0); + if (names_copy == NULL) { +- hns3_err(hw, "Failed to allocate %" PRIx64 " bytes needed " ++ hns3_err(hw, "Failed to allocate 0x%" PRIx64 " bytes needed " + "to store statistics names", len); + return -ENOMEM; + } +@@ -1415,7 +1415,7 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, + + for (i = 0; i < size; i++) { + if (ids[i] >= cnt_stats) { +- hns3_err(hw, "ids[%u] (%" PRIx64 ") is invalid, " ++ hns3_err(hw, "ids[%u] (%" PRIu64 ") is invalid, " + "should < %u", i, ids[i], cnt_stats); + rte_free(names_copy); + return -EINVAL; +-- +2.7.4 + diff --git a/0155-net-hns3-fix-debug-build.patch b/0155-net-hns3-fix-debug-build.patch new file mode 100644 index 0000000..858297d --- /dev/null +++ b/0155-net-hns3-fix-debug-build.patch @@ -0,0 +1,37 @@ +From 9b2deee4ca9c9e1e8b2249bf2c8d4d606aff3669 Mon Sep 17 00:00:00 2001 +From: Thomas Monjalon +Date: Fri, 7 May 2021 14:14:13 +0200 +Subject: [PATCH 155/189] net/hns3: fix debug build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The variable "dev" is not used in hns3_get_tx_prep_needed() +in the case of RTE_LIBRTE_ETHDEV_DEBUG: +drivers/net/hns3/hns3_rxtx.c:4213:45: error: unused parameter ‘dev’ + +Fixes: d7ec2c076579 ("net/hns3: select Tx prepare based on Tx offload") +Cc: stable@dpdk.org + +Reported-by: David Marchand +Signed-off-by: Thomas Monjalon +Acked-by: David Marchand +--- + drivers/net/hns3/hns3_rxtx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index bc4a9a5..6aa2887 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4213,6 +4213,7 @@ static bool + hns3_get_tx_prep_needed(struct rte_eth_dev *dev) + { + #ifdef RTE_LIBRTE_ETHDEV_DEBUG ++ RTE_SET_USED(dev); + /* always perform tx_prepare when debug */ + return true; + #else +-- +2.7.4 + diff --git a/0156-net-hns3-return-error-on-PCI-config-write-failure.patch b/0156-net-hns3-return-error-on-PCI-config-write-failure.patch new file mode 100644 index 0000000..6deb162 --- /dev/null +++ b/0156-net-hns3-return-error-on-PCI-config-write-failure.patch @@ -0,0 +1,36 @@ +From e04c10fe75d5a5015fdb84387eb952fc1c05301f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 7 May 2021 17:08:14 +0800 +Subject: [PATCH 156/189] net/hns3: return error on PCI config write failure + +This patch returns error code when calling rte_pci_write_config() API. + +Fixes: 6dd32ded17d8 ("net/hns3: check PCI config space write") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev_vf.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index c4419fb..182e83b 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -156,9 +156,12 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op) + if (ret < 0) { + PMD_INIT_LOG(ERR, "failed to write PCI offset 0x%x", + (pos + PCI_MSIX_FLAGS)); ++ return -ENXIO; + } ++ + return 0; + } ++ + return -ENXIO; + } + +-- +2.7.4 + diff --git a/0157-net-hns3-fix-log-on-flow-director-clear.patch b/0157-net-hns3-fix-log-on-flow-director-clear.patch new file mode 100644 index 0000000..000c162 --- /dev/null +++ b/0157-net-hns3-fix-log-on-flow-director-clear.patch @@ -0,0 +1,65 @@ +From f3a62e370e72558eb1fe41b540b9aad7036b9679 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 7 May 2021 17:08:15 +0800 +Subject: [PATCH 157/189] net/hns3: fix log on flow director clear + +If clear FDIR rules fail, the error code was logged, but the error code +was useless because it was the sum of all fail code. + +This patch fixes it by log the success cnt and fail cnt. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Fixes: 8eed8acc812e ("net/hns3: add error code to some logs") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_fdir.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index 06dd51b..e87e064 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -1026,6 +1026,8 @@ int hns3_clear_all_fdir_filter(struct hns3_adapter *hns) + struct hns3_fdir_info *fdir_info = &pf->fdir; + struct hns3_fdir_rule_ele *fdir_filter; + struct hns3_hw *hw = &hns->hw; ++ int succ_cnt = 0; ++ int fail_cnt = 0; + int ret = 0; + + /* flush flow director */ +@@ -1034,17 +1036,23 @@ int hns3_clear_all_fdir_filter(struct hns3_adapter *hns) + fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); + while (fdir_filter) { + TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); +- ret += hns3_fd_tcam_config(hw, true, +- fdir_filter->fdir_conf.location, +- NULL, false); ++ ret = hns3_fd_tcam_config(hw, true, ++ fdir_filter->fdir_conf.location, ++ NULL, false); ++ if (ret == 0) ++ succ_cnt++; ++ else ++ fail_cnt++; + rte_free(fdir_filter); + fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); + } + +- if (ret) { +- hns3_err(hw, "Fail to delete FDIR filter, ret = %d", ret); ++ if (fail_cnt > 0) { ++ hns3_err(hw, "fail to delete all FDIR filter, success num = %d " ++ "fail num = %d", succ_cnt, fail_cnt); + ret = -EIO; + } ++ + return ret; + } + +-- +2.7.4 + diff --git a/0158-net-hns3-clear-hash-map-on-flow-director-clear.patch b/0158-net-hns3-clear-hash-map-on-flow-director-clear.patch new file mode 100644 index 0000000..2d6e78b --- /dev/null +++ b/0158-net-hns3-clear-hash-map-on-flow-director-clear.patch @@ -0,0 +1,35 @@ +From 72f412363f33c14750b3d5250315f67a06259033 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 7 May 2021 17:08:16 +0800 +Subject: [PATCH 158/189] net/hns3: clear hash map on flow director clear + +The fdir hash map hold the pointers of fdir rule elements, it needs to +be set to NULL when clear all fdir rules. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_fdir.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index e87e064..8ab5fd6 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -1033,6 +1033,10 @@ int hns3_clear_all_fdir_filter(struct hns3_adapter *hns) + /* flush flow director */ + rte_hash_reset(fdir_info->hash_handle); + ++ memset(fdir_info->hash_map, 0, ++ sizeof(struct hns3_fdir_rule_ele *) * ++ fdir_info->fd_cfg.rule_num[HNS3_FD_STAGE_1]); ++ + fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); + while (fdir_filter) { + TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); +-- +2.7.4 + diff --git a/0159-net-hns3-fix-VF-alive-notification-after-config-rest.patch b/0159-net-hns3-fix-VF-alive-notification-after-config-rest.patch new file mode 100644 index 0000000..4020951 --- /dev/null +++ b/0159-net-hns3-fix-VF-alive-notification-after-config-rest.patch @@ -0,0 +1,69 @@ +From 6950c0629725d5659a0e74960ae7ca71865bf32e Mon Sep 17 00:00:00 2001 +From: Hongbo Zheng +Date: Fri, 7 May 2021 17:08:17 +0800 +Subject: [PATCH 159/189] net/hns3: fix VF alive notification after config + restore + +Currently in the VF reset scenario, the VF performs the set +alive operation before restoring the configuration completed, +which may cause the hardware to work in an abnormal state. + +This patch fix this problem by set VF alive after restoring +the configuration is completed. + +Fixes: a5475d61fa34 ("net/hns3: support VF") +Cc: stable@dpdk.org + +Signed-off-by: Hongbo Zheng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev_vf.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 182e83b..dbd823f 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1891,12 +1891,6 @@ hns3vf_init_hardware(struct hns3_adapter *hns) + goto err_init_hardware; + } + +- ret = hns3vf_set_alive(hw, true); +- if (ret) { +- PMD_INIT_LOG(ERR, "Failed to VF send alive to PF: %d", ret); +- goto err_init_hardware; +- } +- + return 0; + + err_init_hardware: +@@ -1995,6 +1989,12 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) + + hns3_rss_set_default_args(hw); + ++ ret = hns3vf_set_alive(hw, true); ++ if (ret) { ++ PMD_INIT_LOG(ERR, "Failed to VF send alive to PF: %d", ret); ++ goto err_set_tc_queue; ++ } ++ + return 0; + + err_set_tc_queue: +@@ -2703,6 +2703,13 @@ hns3vf_restore_conf(struct hns3_adapter *hns) + hns3_info(hw, "hns3vf dev restart successful!"); + } else if (hw->adapter_state == HNS3_NIC_STOPPING) + hw->adapter_state = HNS3_NIC_CONFIGURED; ++ ++ ret = hns3vf_set_alive(hw, true); ++ if (ret) { ++ hns3_err(hw, "failed to VF send alive to PF: %d", ret); ++ goto err_vlan_table; ++ } ++ + return 0; + + err_vlan_table: +-- +2.7.4 + diff --git a/0160-net-hns3-fix-querying-flow-director-counter-for-out-.patch b/0160-net-hns3-fix-querying-flow-director-counter-for-out-.patch new file mode 100644 index 0000000..b9fb8c3 --- /dev/null +++ b/0160-net-hns3-fix-querying-flow-director-counter-for-out-.patch @@ -0,0 +1,35 @@ +From 738c66f157c398ce78f3ba7c25f4e096d755ce7f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 7 May 2021 17:08:18 +0800 +Subject: [PATCH 160/189] net/hns3: fix querying flow director counter for out + param + +The hardware doesn't support counting the number of bytes that through +the fdir rule. Therefore, the corresponding out parameters (e.g. +bytes_set/bytes) is set to zero. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_flow.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 15ecaf4..d405820 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -223,6 +223,8 @@ hns3_counter_query(struct rte_eth_dev *dev, struct rte_flow *flow, + } + qc->hits_set = 1; + qc->hits = value; ++ qc->bytes_set = 0; ++ qc->bytes = 0; + + return 0; + } +-- +2.7.4 + diff --git a/0161-net-hns3-fix-TM-QCN-error-event-report-by-MSI-X.patch b/0161-net-hns3-fix-TM-QCN-error-event-report-by-MSI-X.patch new file mode 100644 index 0000000..ab61755 --- /dev/null +++ b/0161-net-hns3-fix-TM-QCN-error-event-report-by-MSI-X.patch @@ -0,0 +1,54 @@ +From dbeadbf0ac1368fa07822b025a3f1bf10a450b43 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 8 May 2021 15:40:57 +0800 +Subject: [PATCH 161/189] net/hns3: fix TM QCN error event report by MSI-X + +The TM QCN error event should report by RAS other than MSIX. + +Also this patch adds fifo int enable configuration before the TM QCN +error event is enabled. + +Fixes: f53a793bb7c2 ("net/hns3: add more hardware error types") +Fixes: 3903c05382c5 ("net/hns3: remove read when enabling TM QCN error event") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_intr.c | 5 ++++- + drivers/net/hns3/hns3_intr.h | 2 ++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 0140260..854cb1d 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -1783,8 +1783,11 @@ enable_tm_err_intr(struct hns3_adapter *hns, bool en) + + /* configure TM QCN hw errors */ + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_TM_QCN_MEM_INT_CFG, false); +- if (en) ++ desc.data[0] = rte_cpu_to_le_32(HNS3_TM_QCN_ERR_INT_TYPE); ++ if (en) { ++ desc.data[0] |= rte_cpu_to_le_32(HNS3_TM_QCN_FIFO_INT_EN); + desc.data[1] = rte_cpu_to_le_32(HNS3_TM_QCN_MEM_ERR_INT_EN); ++ } + + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) +diff --git a/drivers/net/hns3/hns3_intr.h b/drivers/net/hns3/hns3_intr.h +index a140ca1..4dfc807 100644 +--- a/drivers/net/hns3/hns3_intr.h ++++ b/drivers/net/hns3/hns3_intr.h +@@ -77,6 +77,8 @@ + #define HNS3_NCSI_ERR_INT_EN 0x3 + + #define HNS3_TM_SCH_ECC_ERR_INT_EN 0x3 ++#define HNS3_TM_QCN_ERR_INT_TYPE 0x29 ++#define HNS3_TM_QCN_FIFO_INT_EN 0xFFFF00 + #define HNS3_TM_QCN_MEM_ERR_INT_EN 0xFFFFFF + + #define HNS3_RESET_PROCESS_MS 200 +-- +2.7.4 + diff --git a/0162-net-hns3-fix-mailbox-message-ID-in-log.patch b/0162-net-hns3-fix-mailbox-message-ID-in-log.patch new file mode 100644 index 0000000..6b72250 --- /dev/null +++ b/0162-net-hns3-fix-mailbox-message-ID-in-log.patch @@ -0,0 +1,33 @@ +From e1cf907216bf8fdb15a94a7c9918b1f6772afebb Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Mon, 10 May 2021 21:38:10 +0800 +Subject: [PATCH 162/189] net/hns3: fix mailbox message ID in log + +The mailbox message id is uint8_t, but the unsupported mailbox message +id was logged by uint16. + +Fixes: 463e748964f5 ("net/hns3: support mailbox") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mbx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c +index 3d019b9..0c2e03b 100644 +--- a/drivers/net/hns3/hns3_mbx.c ++++ b/drivers/net/hns3/hns3_mbx.c +@@ -540,7 +540,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) + break; + default: + hns3_err(hw, "received unsupported(%u) mbx msg", +- req->msg[0]); ++ opcode); + break; + } + +-- +2.7.4 + diff --git a/0163-net-hns3-fix-secondary-process-request-start-stop-Rx.patch b/0163-net-hns3-fix-secondary-process-request-start-stop-Rx.patch new file mode 100644 index 0000000..12dec23 --- /dev/null +++ b/0163-net-hns3-fix-secondary-process-request-start-stop-Rx.patch @@ -0,0 +1,34 @@ +From 8f2285bfc5a77da72ddaec4faccfbbdef91cd4a8 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Mon, 10 May 2021 21:38:11 +0800 +Subject: [PATCH 163/189] net/hns3: fix secondary process request start/stop + Rx/Tx + +This secondary process should not send request to start/stop Rx/Tx, +this patch fixes it. + +Fixes: 23d4b61fee5d ("net/hns3: support multiple process") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_mp.c b/drivers/net/hns3/hns3_mp.c +index ed2567a..7d85de3 100644 +--- a/drivers/net/hns3/hns3_mp.c ++++ b/drivers/net/hns3/hns3_mp.c +@@ -130,7 +130,7 @@ mp_req_on_rxtx(struct rte_eth_dev *dev, enum hns3_mp_req_type type) + int ret; + int i; + +- if (!hw->secondary_cnt) ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY || !hw->secondary_cnt) + return; + if (type != HNS3_MP_REQ_START_RXTX && type != HNS3_MP_REQ_STOP_RXTX) { + hns3_err(hw, "port %u unknown request (req_type %d)", +-- +2.7.4 + diff --git a/0164-net-hns3-fix-ordering-in-secondary-process-initializ.patch b/0164-net-hns3-fix-ordering-in-secondary-process-initializ.patch new file mode 100644 index 0000000..44e1183 --- /dev/null +++ b/0164-net-hns3-fix-ordering-in-secondary-process-initializ.patch @@ -0,0 +1,36 @@ +From 0bfe64c5063855fb27785c2f73e98cc8f2893e0b Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Mon, 10 May 2021 21:38:12 +0800 +Subject: [PATCH 164/189] net/hns3: fix ordering in secondary process + initialization + +The memory barrier is used to ensure that the response is returned +only after the Tx/Rx function is set, it should place after the Rx/Tx +function is set. + +Fixes: 23d4b61fee5d ("net/hns3: support multiple process") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_mp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_mp.c b/drivers/net/hns3/hns3_mp.c +index 7d85de3..b5cd5b0 100644 +--- a/drivers/net/hns3/hns3_mp.c ++++ b/drivers/net/hns3/hns3_mp.c +@@ -86,8 +86,8 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + case HNS3_MP_REQ_START_RXTX: + PMD_INIT_LOG(INFO, "port %u starting datapath", + dev->data->port_id); +- rte_mb(); + hns3_set_rxtx_function(dev); ++ rte_mb(); + mp_init_msg(dev, &mp_res, param->type); + res->result = 0; + ret = rte_mp_reply(&mp_res, peer); +-- +2.7.4 + diff --git a/0165-net-hns3-fail-setting-FEC-if-one-bit-mode-is-not-sup.patch b/0165-net-hns3-fail-setting-FEC-if-one-bit-mode-is-not-sup.patch new file mode 100644 index 0000000..09b3d96 --- /dev/null +++ b/0165-net-hns3-fail-setting-FEC-if-one-bit-mode-is-not-sup.patch @@ -0,0 +1,40 @@ +From 6c80dd7d227149ba1e2a06be8a87a2295e5b2e5f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Mon, 10 May 2021 21:38:13 +0800 +Subject: [PATCH 165/189] net/hns3: fail setting FEC if one bit mode is not + supported + +If the FEC mode was not supported, it should return error code. + +This patch also adds a space when log error info. + +Fixes: 9bf2ea8dbc65 ("net/hns3: support FEC") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 44e6c5b..7ecd15b 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6988,9 +6988,11 @@ hns3_fec_set(struct rte_eth_dev *dev, uint32_t mode) + return ret; + + /* HNS3 PMD driver only support one bit set mode, e.g. 0x1, 0x4 */ +- if (!is_fec_mode_one_bit_set(mode)) +- hns3_err(hw, "FEC mode(0x%x) not supported in HNS3 PMD," ++ if (!is_fec_mode_one_bit_set(mode)) { ++ hns3_err(hw, "FEC mode(0x%x) not supported in HNS3 PMD, " + "FEC mode should be only one bit set", mode); ++ return -EINVAL; ++ } + + /* + * Check whether the configured mode is within the FEC capability. +-- +2.7.4 + diff --git a/0166-net-hns3-fix-Rx-Tx-queue-numbers-check.patch b/0166-net-hns3-fix-Rx-Tx-queue-numbers-check.patch new file mode 100644 index 0000000..63bbecb --- /dev/null +++ b/0166-net-hns3-fix-Rx-Tx-queue-numbers-check.patch @@ -0,0 +1,68 @@ +From cecc7bbcaf74f28a947f653069809bab67be42fe Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 15 May 2021 08:52:33 +0800 +Subject: [PATCH 166/189] net/hns3: fix Rx/Tx queue numbers check + +The Rx/Tx queue numbers should be greater than TC number, this patch adds +this check for PF before updating the mapping between TC and queue. + +Fixes: a951c1ed3ab5 ("net/hns3: support different numbers of Rx and Tx queues") +Fixes: 76d794566d43 ("net/hns3: maximize queue number") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_dcb.c | 12 ++++++++++++ + drivers/net/hns3/hns3_ethdev_vf.c | 12 ------------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index 49b8be7..f44e2f0 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -727,6 +727,18 @@ hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, uint16_t nb_tx_q) + { + int ret; + ++ if (nb_rx_q < hw->num_tc) { ++ hns3_err(hw, "number of Rx queues(%u) is less than number of TC(%u).", ++ nb_rx_q, hw->num_tc); ++ return -EINVAL; ++ } ++ ++ if (nb_tx_q < hw->num_tc) { ++ hns3_err(hw, "number of Tx queues(%u) is less than number of TC(%u).", ++ nb_tx_q, hw->num_tc); ++ return -EINVAL; ++ } ++ + ret = hns3_set_rss_size(hw, nb_rx_q); + if (ret) + return ret; +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index dbd823f..7f7da18 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1498,18 +1498,6 @@ hns3vf_set_tc_queue_mapping(struct hns3_adapter *hns, uint16_t nb_rx_q, + { + struct hns3_hw *hw = &hns->hw; + +- if (nb_rx_q < hw->num_tc) { +- hns3_err(hw, "number of Rx queues(%u) is less than tcs(%u).", +- nb_rx_q, hw->num_tc); +- return -EINVAL; +- } +- +- if (nb_tx_q < hw->num_tc) { +- hns3_err(hw, "number of Tx queues(%u) is less than tcs(%u).", +- nb_tx_q, hw->num_tc); +- return -EINVAL; +- } +- + return hns3_queue_to_tc_mapping(hw, nb_rx_q, nb_tx_q); + } + +-- +2.7.4 + diff --git a/0167-net-hns3-fix-requested-FC-mode-rollback.patch b/0167-net-hns3-fix-requested-FC-mode-rollback.patch new file mode 100644 index 0000000..9614aff --- /dev/null +++ b/0167-net-hns3-fix-requested-FC-mode-rollback.patch @@ -0,0 +1,157 @@ +From ce08c5f9d37133ef2e984acb46d0fdf49fed9128 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 15 May 2021 08:52:34 +0800 +Subject: [PATCH 167/189] net/hns3: fix requested FC mode rollback + +Currently, the "requested_fc_mode" lacks rollback when enabling link +FC or PFC fails. +For example, this may result an incorrect FC mode after a reset. + +Fixes: d4fdb71a0e7b ("net/hns3: fix flow control mode") +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_dcb.c | 30 ++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_ethdev.c | 28 ---------------------------- + 2 files changed, 30 insertions(+), 28 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index f44e2f0..3efc2cd 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -1760,6 +1760,30 @@ hns3_dcb_cfg_update(struct hns3_adapter *hns) + return ret; + } + ++static void ++hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) ++{ ++ switch (mode) { ++ case RTE_FC_NONE: ++ hw->requested_fc_mode = HNS3_FC_NONE; ++ break; ++ case RTE_FC_RX_PAUSE: ++ hw->requested_fc_mode = HNS3_FC_RX_PAUSE; ++ break; ++ case RTE_FC_TX_PAUSE: ++ hw->requested_fc_mode = HNS3_FC_TX_PAUSE; ++ break; ++ case RTE_FC_FULL: ++ hw->requested_fc_mode = HNS3_FC_FULL; ++ break; ++ default: ++ hw->requested_fc_mode = HNS3_FC_NONE; ++ hns3_warn(hw, "fc_mode(%u) exceeds member scope and is " ++ "configured to RTE_FC_NONE", mode); ++ break; ++ } ++} ++ + /* + * hns3_dcb_pfc_enable - Enable priority flow control + * @dev: pointer to ethernet device +@@ -1772,6 +1796,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + enum hns3_fc_status fc_status = hw->current_fc_status; ++ enum hns3_fc_mode old_fc_mode = hw->requested_fc_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; + uint8_t pfc_en = hw->dcb_info.pfc_en; + uint8_t priority = pfc_conf->priority; +@@ -1779,6 +1804,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + int ret, status; + + pf->pause_time = pfc_conf->fc.pause_time; ++ hns3_get_fc_mode(hw, pfc_conf->fc.mode); + hw->current_fc_status = HNS3_FC_STATUS_PFC; + hw->dcb_info.pfc_en |= BIT(priority); + hw->dcb_info.hw_pfc_map = +@@ -1800,6 +1826,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + return 0; + + pfc_setup_fail: ++ hw->requested_fc_mode = old_fc_mode; + hw->current_fc_status = fc_status; + pf->pause_time = pause_time; + hw->dcb_info.pfc_en = pfc_en; +@@ -1822,11 +1849,13 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ enum hns3_fc_mode old_fc_mode = hw->requested_fc_mode; + enum hns3_fc_status fc_status = hw->current_fc_status; + uint16_t pause_time = pf->pause_time; + int ret; + + pf->pause_time = fc_conf->pause_time; ++ hns3_get_fc_mode(hw, fc_conf->mode); + + /* + * In fact, current_fc_status is HNS3_FC_STATUS_NONE when mode +@@ -1846,6 +1875,7 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return 0; + + setup_fc_fail: ++ hw->requested_fc_mode = old_fc_mode; + hw->current_fc_status = fc_status; + pf->pause_time = pause_time; + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 7ecd15b..88b2cfd 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6056,30 +6056,6 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return 0; + } + +-static void +-hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) +-{ +- switch (mode) { +- case RTE_FC_NONE: +- hw->requested_fc_mode = HNS3_FC_NONE; +- break; +- case RTE_FC_RX_PAUSE: +- hw->requested_fc_mode = HNS3_FC_RX_PAUSE; +- break; +- case RTE_FC_TX_PAUSE: +- hw->requested_fc_mode = HNS3_FC_TX_PAUSE; +- break; +- case RTE_FC_FULL: +- hw->requested_fc_mode = HNS3_FC_FULL; +- break; +- default: +- hw->requested_fc_mode = HNS3_FC_NONE; +- hns3_warn(hw, "fc_mode(%u) exceeds member scope and is " +- "configured to RTE_FC_NONE", mode); +- break; +- } +-} +- + static int + hns3_check_fc_autoneg_valid(struct hns3_hw *hw, uint8_t autoneg) + { +@@ -6153,8 +6129,6 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return -EOPNOTSUPP; + } + +- hns3_get_fc_mode(hw, fc_conf->mode); +- + rte_spinlock_lock(&hw->lock); + ret = hns3_fc_enable(dev, fc_conf); + rte_spinlock_unlock(&hw->lock); +@@ -6201,8 +6175,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, + return -EOPNOTSUPP; + } + +- hns3_get_fc_mode(hw, pfc_conf->fc.mode); +- + rte_spinlock_lock(&hw->lock); + ret = hns3_dcb_pfc_enable(dev, pfc_conf); + rte_spinlock_unlock(&hw->lock); +-- +2.7.4 + diff --git a/0168-net-hns3-remove-meaningless-packet-buffer-rollback.patch b/0168-net-hns3-remove-meaningless-packet-buffer-rollback.patch new file mode 100644 index 0000000..50e719f --- /dev/null +++ b/0168-net-hns3-remove-meaningless-packet-buffer-rollback.patch @@ -0,0 +1,75 @@ +From 30543af4bf517080e505ce6a99e2d0a3c9211445 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 15 May 2021 08:52:35 +0800 +Subject: [PATCH 168/189] net/hns3: remove meaningless packet buffer rollback + +Packet buffer allocation and hardware pause configuration fail normally +when a reset occurs. If the execution fails, rollback of the packet +buffer still fails. So this rollback is meaningless. + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_dcb.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index 3efc2cd..1547942 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -1543,7 +1543,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + enum hns3_fc_status fc_status = hw->current_fc_status; + enum hns3_fc_mode requested_fc_mode = hw->requested_fc_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; +- int ret, status; ++ int ret; + + if (pf->tx_sch_mode != HNS3_FLAG_TC_BASE_SCH_MODE && + pf->tx_sch_mode != HNS3_FLAG_VNET_BASE_SCH_MODE) +@@ -1568,7 +1568,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + + ret = hns3_buffer_alloc(hw); + if (ret) +- return ret; ++ goto buffer_alloc_fail; + + hw->current_fc_status = HNS3_FC_STATUS_PFC; + hw->requested_fc_mode = HNS3_FC_FULL; +@@ -1594,10 +1594,9 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + pfc_setup_fail: + hw->requested_fc_mode = requested_fc_mode; + hw->current_fc_status = fc_status; ++ ++buffer_alloc_fail: + hw->dcb_info.hw_pfc_map = hw_pfc_map; +- status = hns3_buffer_alloc(hw); +- if (status) +- hns3_err(hw, "recover packet buffer fail! status = %d", status); + + return ret; + } +@@ -1801,7 +1800,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + uint8_t pfc_en = hw->dcb_info.pfc_en; + uint8_t priority = pfc_conf->priority; + uint16_t pause_time = pf->pause_time; +- int ret, status; ++ int ret; + + pf->pause_time = pfc_conf->fc.pause_time; + hns3_get_fc_mode(hw, pfc_conf->fc.mode); +@@ -1831,9 +1830,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + pf->pause_time = pause_time; + hw->dcb_info.pfc_en = pfc_en; + hw->dcb_info.hw_pfc_map = hw_pfc_map; +- status = hns3_buffer_alloc(hw); +- if (status) +- hns3_err(hw, "recover packet buffer fail: %d", status); + + return ret; + } +-- +2.7.4 + diff --git a/0169-net-hns3-fix-DCB-configuration.patch b/0169-net-hns3-fix-DCB-configuration.patch new file mode 100644 index 0000000..e87a40c --- /dev/null +++ b/0169-net-hns3-fix-DCB-configuration.patch @@ -0,0 +1,198 @@ +From c8817a4d8e42476b08fdcfc0a2b931e3d2fecc59 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 15 May 2021 08:52:36 +0800 +Subject: [PATCH 169/189] net/hns3: fix DCB configuration + +Currently, the DCB configuration takes effect in the dev_start stage, and +the mapping between TCs and queues are also updated in this stage. +However, the DCB configuration is delivered in the dev_configure stage. + +If the configuration fails, it should be intercepted in this stage. If +the configuration succeeds, the user should be able to obtain the +corresponding updated information, such as the mapping between TCs and +queues. So this patch moves DCB configuration to dev_configure. + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_dcb.c | 35 +++++--------------------- + drivers/net/hns3/hns3_dcb.h | 2 +- + drivers/net/hns3/hns3_ethdev.c | 56 +++++++++++++++++++++++------------------- + 3 files changed, 38 insertions(+), 55 deletions(-) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index 1547942..624bf40 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -1615,8 +1615,7 @@ hns3_dcb_configure(struct hns3_adapter *hns) + int ret; + + hns3_dcb_cfg_validate(hns, &num_tc, &map_changed); +- if (map_changed || +- __atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED)) { ++ if (map_changed) { + ret = hns3_dcb_info_update(hns, num_tc); + if (ret) { + hns3_err(hw, "dcb info update failed: %d", ret); +@@ -1712,14 +1711,18 @@ hns3_dcb_init(struct hns3_hw *hw) + return 0; + } + +-static int ++int + hns3_update_queue_map_configure(struct hns3_adapter *hns) + { + struct hns3_hw *hw = &hns->hw; ++ enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; + uint16_t nb_rx_q = hw->data->nb_rx_queues; + uint16_t nb_tx_q = hw->data->nb_tx_queues; + int ret; + ++ if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) ++ return 0; ++ + ret = hns3_dcb_update_tc_queue_mapping(hw, nb_rx_q, nb_tx_q); + if (ret) { + hns3_err(hw, "failed to update tc queue mapping, ret = %d.", +@@ -1733,32 +1736,6 @@ hns3_update_queue_map_configure(struct hns3_adapter *hns) + return ret; + } + +-int +-hns3_dcb_cfg_update(struct hns3_adapter *hns) +-{ +- struct hns3_hw *hw = &hns->hw; +- enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; +- int ret; +- +- if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) { +- ret = hns3_dcb_configure(hns); +- if (ret) +- hns3_err(hw, "Failed to config dcb: %d", ret); +- } else { +- /* +- * Update queue map without PFC configuration, +- * due to queues reconfigured by user. +- */ +- ret = hns3_update_queue_map_configure(hns); +- if (ret) +- hns3_err(hw, +- "Failed to update queue mapping configure: %d", +- ret); +- } +- +- return ret; +-} +- + static void + hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) + { +diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h +index 0d25d3b..279f163 100644 +--- a/drivers/net/hns3/hns3_dcb.h ++++ b/drivers/net/hns3/hns3_dcb.h +@@ -207,7 +207,7 @@ int hns3_dcb_pfc_enable(struct rte_eth_dev *dev, + int hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, + uint16_t nb_tx_q); + +-int hns3_dcb_cfg_update(struct hns3_adapter *hns); ++int hns3_update_queue_map_configure(struct hns3_adapter *hns); + int hns3_port_shaper_update(struct hns3_hw *hw, uint32_t speed); + int hns3_pg_shaper_rate_cfg(struct hns3_hw *hw, uint8_t pg_id, uint32_t rate); + int hns3_pri_shaper_rate_cfg(struct hns3_hw *hw, uint8_t tc_no, uint32_t rate); +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 88b2cfd..351dc59 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -2274,24 +2274,6 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) + } + + static int +-hns3_check_dcb_cfg(struct rte_eth_dev *dev) +-{ +- struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- +- if (!hns3_dev_dcb_supported(hw)) { +- hns3_err(hw, "this port does not support dcb configurations."); +- return -EOPNOTSUPP; +- } +- +- if (hw->current_fc_status == HNS3_FC_STATUS_MAC_PAUSE) { +- hns3_err(hw, "MAC pause enabled, cannot config dcb info."); +- return -EOPNOTSUPP; +- } +- +- return 0; +-} +- +-static int + hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en, + enum hns3_ring_type queue_type, uint16_t queue_id) + { +@@ -2427,6 +2409,30 @@ hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf) + } + + static int ++hns3_setup_dcb(struct rte_eth_dev *dev) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ int ret; ++ ++ if (!hns3_dev_dcb_supported(hw)) { ++ hns3_err(hw, "this port does not support dcb configurations."); ++ return -EOPNOTSUPP; ++ } ++ ++ if (hw->current_fc_status == HNS3_FC_STATUS_MAC_PAUSE) { ++ hns3_err(hw, "MAC pause enabled, cannot config dcb info."); ++ return -EOPNOTSUPP; ++ } ++ ++ ret = hns3_dcb_configure(hns); ++ if (ret) ++ hns3_err(hw, "failed to config dcb: %d", ret); ++ ++ return ret; ++} ++ ++static int + hns3_check_link_speed(struct hns3_hw *hw, uint32_t link_speeds) + { + int ret; +@@ -2506,7 +2512,7 @@ hns3_dev_configure(struct rte_eth_dev *dev) + goto cfg_err; + + if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) { +- ret = hns3_check_dcb_cfg(dev); ++ ret = hns3_setup_dcb(dev); + if (ret) + goto cfg_err; + } +@@ -5571,14 +5577,14 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + struct hns3_hw *hw = &hns->hw; + int ret; + +- ret = hns3_dcb_cfg_update(hns); +- if (ret) ++ ret = hns3_update_queue_map_configure(hns); ++ if (ret) { ++ hns3_err(hw, "failed to update queue mapping configuration, ret = %d", ++ ret); + return ret; ++ } + +- /* +- * The hns3_dcb_cfg_update may configure TM module, so +- * hns3_tm_conf_update must called later. +- */ ++ /* Note: hns3_tm_conf_update must be called after configuring DCB. */ + ret = hns3_tm_conf_update(hw); + if (ret) { + PMD_INIT_LOG(ERR, "failed to update tm conf, ret = %d.", ret); +-- +2.7.4 + diff --git a/0170-net-hns3-fix-DCB-reconfiguration.patch b/0170-net-hns3-fix-DCB-reconfiguration.patch new file mode 100644 index 0000000..0710014 --- /dev/null +++ b/0170-net-hns3-fix-DCB-reconfiguration.patch @@ -0,0 +1,41 @@ +From 8e8b04c6f9586cef6a58b6825fee632ebce13c36 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 15 May 2021 08:52:37 +0800 +Subject: [PATCH 170/189] net/hns3: fix DCB reconfiguration + +Whether the enable bit of the pfc ("pfc_en") is changed or not is one of +the conditions for reconfiguring the DCB. Currently, pfc_en is not +rolled back when DCB configuration fails. This patch fixes it. + +Fixes: 62e3ccc2b94c ("net/hns3: support flow control") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_dcb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c +index 624bf40..8778452 100644 +--- a/drivers/net/hns3/hns3_dcb.c ++++ b/drivers/net/hns3/hns3_dcb.c +@@ -1543,6 +1543,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + enum hns3_fc_status fc_status = hw->current_fc_status; + enum hns3_fc_mode requested_fc_mode = hw->requested_fc_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; ++ uint8_t pfc_en = hw->dcb_info.pfc_en; + int ret; + + if (pf->tx_sch_mode != HNS3_FLAG_TC_BASE_SCH_MODE && +@@ -1596,6 +1597,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + hw->current_fc_status = fc_status; + + buffer_alloc_fail: ++ hw->dcb_info.pfc_en = pfc_en; + hw->dcb_info.hw_pfc_map = hw_pfc_map; + + return ret; +-- +2.7.4 + diff --git a/0171-net-hns3-fix-link-speed-when-VF-device-is-down.patch b/0171-net-hns3-fix-link-speed-when-VF-device-is-down.patch new file mode 100644 index 0000000..9440716 --- /dev/null +++ b/0171-net-hns3-fix-link-speed-when-VF-device-is-down.patch @@ -0,0 +1,46 @@ +From 5c44687c2b82e27046dd8c6eb6e3b3c4dc3a7499 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Sat, 15 May 2021 08:52:38 +0800 +Subject: [PATCH 171/189] net/hns3: fix link speed when VF device is down + +When the port is link down state, it is meaningless to display the +port link speed. It should be an undefined state. + +Fixes: 59fad0f32135 ("net/hns3: support link update operation") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev_vf.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c +index 7f7da18..030d63a 100644 +--- a/drivers/net/hns3/hns3_ethdev_vf.c ++++ b/drivers/net/hns3/hns3_ethdev_vf.c +@@ -2202,16 +2202,18 @@ hns3vf_dev_link_update(struct rte_eth_dev *eth_dev, + case ETH_SPEED_NUM_50G: + case ETH_SPEED_NUM_100G: + case ETH_SPEED_NUM_200G: +- new_link.link_speed = mac->link_speed; ++ if (mac->link_status) ++ new_link.link_speed = mac->link_speed; + break; + default: + if (mac->link_status) + new_link.link_speed = ETH_SPEED_NUM_UNKNOWN; +- else +- new_link.link_speed = ETH_SPEED_NUM_NONE; + break; + } + ++ if (!mac->link_status) ++ new_link.link_speed = ETH_SPEED_NUM_NONE; ++ + new_link.link_duplex = mac->link_duplex; + new_link.link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN; + new_link.link_autoneg = +-- +2.7.4 + diff --git a/0172-net-bonding-fix-adding-itself-as-its-slave.patch b/0172-net-bonding-fix-adding-itself-as-its-slave.patch new file mode 100644 index 0000000..553ad5c --- /dev/null +++ b/0172-net-bonding-fix-adding-itself-as-its-slave.patch @@ -0,0 +1,137 @@ +From d91cb3a8f42e016965f7e641f1c33763f29fb722 Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 15 Apr 2021 15:09:54 +0800 +Subject: [PATCH 172/189] net/bonding: fix adding itself as its slave + +Adding the bond device as its own slave should be forbidden. This +will cause a recursive endless loop in many subsequent operations, +and eventually lead to coredump. + +This problem was found in testpmd, the related logs are as follows: +testpmd> create bonded device 1 0 +Created new bonded device net_bonding_testpmd_0 on (port 4). +testpmd> add bonding slave 4 4 +Segmentation fault (core dumped) + +The call stack is as follows: +0x000000000064eb90 in rte_eth_dev_info_get () +0x00000000006df4b4 in bond_ethdev_info () +0x000000000064eb90 in rte_eth_dev_info_get () +0x00000000006df4b4 in bond_ethdev_info () +0x000000000064eb90 in rte_eth_dev_info_get () +0x0000000000564e58 in eth_dev_info_get_print_err () +0x000000000055e8a4 in init_port_config () +0x000000000052730c in cmd_add_bonding_slave_parsed () +0x0000000000646f60 in cmdline_parse () +0x0000000000645e08 in cmdline_valid_buffer () +0x000000000064956c in rdline_char_in () +0x0000000000645ee0 in cmdline_in () +0x00000000006460a4 in cmdline_interact () +0x0000000000531904 in prompt () +0x000000000051cca8 in main () + +Fixes: 2efb58cbab6e ("bond: new link bonding library") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +--- + drivers/net/bonding/eth_bond_private.h | 2 +- + drivers/net/bonding/rte_eth_bond_api.c | 26 +++++++++++++++++--------- + 2 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/bonding/eth_bond_private.h b/drivers/net/bonding/eth_bond_private.h +index 8f198bd..5c7a552 100644 +--- a/drivers/net/bonding/eth_bond_private.h ++++ b/drivers/net/bonding/eth_bond_private.h +@@ -212,7 +212,7 @@ int + valid_bonded_port_id(uint16_t port_id); + + int +-valid_slave_port_id(uint16_t port_id, uint8_t mode); ++valid_slave_port_id(struct bond_dev_private *internals, uint16_t port_id); + + void + deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id); +diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c +index 55c8e31..44775f6 100644 +--- a/drivers/net/bonding/rte_eth_bond_api.c ++++ b/drivers/net/bonding/rte_eth_bond_api.c +@@ -56,19 +56,25 @@ check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev) + } + + int +-valid_slave_port_id(uint16_t port_id, uint8_t mode) ++valid_slave_port_id(struct bond_dev_private *internals, uint16_t slave_port_id) + { +- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); ++ RTE_ETH_VALID_PORTID_OR_ERR_RET(slave_port_id, -1); + +- /* Verify that port_id refers to a non bonded port */ +- if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0 && +- mode == BONDING_MODE_8023AD) { ++ /* Verify that slave_port_id refers to a non bonded port */ ++ if (check_for_bonded_ethdev(&rte_eth_devices[slave_port_id]) == 0 && ++ internals->mode == BONDING_MODE_8023AD) { + RTE_BOND_LOG(ERR, "Cannot add slave to bonded device in 802.3ad" + " mode as slave is also a bonded device, only " + "physical devices can be support in this mode."); + return -1; + } + ++ if (internals->port_id == slave_port_id) { ++ RTE_BOND_LOG(ERR, ++ "Cannot add the bonded device itself as its slave."); ++ return -1; ++ } ++ + return 0; + } + +@@ -456,7 +462,7 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) + bonded_eth_dev = &rte_eth_devices[bonded_port_id]; + internals = bonded_eth_dev->data->dev_private; + +- if (valid_slave_port_id(slave_port_id, internals->mode) != 0) ++ if (valid_slave_port_id(internals, slave_port_id) != 0) + return -1; + + slave_eth_dev = &rte_eth_devices[slave_port_id]; +@@ -605,13 +611,15 @@ rte_eth_bond_slave_add(uint16_t bonded_port_id, uint16_t slave_port_id) + + int retval; + +- /* Verify that port id's are valid bonded and slave ports */ + if (valid_bonded_port_id(bonded_port_id) != 0) + return -1; + + bonded_eth_dev = &rte_eth_devices[bonded_port_id]; + internals = bonded_eth_dev->data->dev_private; + ++ if (valid_slave_port_id(internals, slave_port_id) != 0) ++ return -1; ++ + rte_spinlock_lock(&internals->lock); + + retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id); +@@ -635,7 +643,7 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, + bonded_eth_dev = &rte_eth_devices[bonded_port_id]; + internals = bonded_eth_dev->data->dev_private; + +- if (valid_slave_port_id(slave_port_id, internals->mode) < 0) ++ if (valid_slave_port_id(internals, slave_port_id) < 0) + return -1; + + /* first remove from active slave list */ +@@ -783,7 +791,7 @@ rte_eth_bond_primary_set(uint16_t bonded_port_id, uint16_t slave_port_id) + + internals = rte_eth_devices[bonded_port_id].data->dev_private; + +- if (valid_slave_port_id(slave_port_id, internals->mode) != 0) ++ if (valid_slave_port_id(internals, slave_port_id) != 0) + return -1; + + internals->user_defined_primary_port = 1; +-- +2.7.4 + diff --git a/0173-ipc-use-monotonic-clock.patch b/0173-ipc-use-monotonic-clock.patch new file mode 100644 index 0000000..ef75042 --- /dev/null +++ b/0173-ipc-use-monotonic-clock.patch @@ -0,0 +1,128 @@ +From 5b8e25a80cc320c15477a884ebb5abd15b60a246 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Tue, 11 May 2021 18:41:23 +0800 +Subject: [PATCH 173/189] ipc: use monotonic clock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, the mp uses gettimeofday() API to get the time, and used as +timeout parameter. + +But the time which gets from gettimeofday() API isn't monotonically +increasing. The process may fail if the system time is changed. + +This fixes it by using clock_gettime() API with monotonic attribution. + +Fixes: 783b6e54971d ("eal: add synchronous multi-process communication") +Fixes: f05e26051c15 ("eal: add IPC asynchronous request") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +Acked-by: Morten Brørup +--- + lib/librte_eal/common/eal_common_proc.c | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c +index 6d1af3c..dc4a2ef 100644 +--- a/lib/librte_eal/common/eal_common_proc.c ++++ b/lib/librte_eal/common/eal_common_proc.c +@@ -490,14 +490,11 @@ async_reply_handle_thread_unsafe(void *arg) + struct pending_request *req = (struct pending_request *)arg; + enum async_action action; + struct timespec ts_now; +- struct timeval now; + +- if (gettimeofday(&now, NULL) < 0) { ++ if (clock_gettime(CLOCK_MONOTONIC, &ts_now) < 0) { + RTE_LOG(ERR, EAL, "Cannot get current time\n"); + goto no_trigger; + } +- ts_now.tv_nsec = now.tv_usec * 1000; +- ts_now.tv_sec = now.tv_sec; + + action = process_async_request(req, &ts_now); + +@@ -896,6 +893,7 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req, + struct rte_mp_reply *reply, const struct timespec *ts) + { + int ret; ++ pthread_condattr_t attr; + struct rte_mp_msg msg, *tmp; + struct pending_request pending_req, *exist; + +@@ -904,7 +902,9 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req, + strlcpy(pending_req.dst, dst, sizeof(pending_req.dst)); + pending_req.request = req; + pending_req.reply = &msg; +- pthread_cond_init(&pending_req.sync.cond, NULL); ++ pthread_condattr_init(&attr); ++ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); ++ pthread_cond_init(&pending_req.sync.cond, &attr); + + exist = find_pending_request(dst, req->name); + if (exist) { +@@ -967,8 +967,7 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, + int dir_fd, ret = -1; + DIR *mp_dir; + struct dirent *ent; +- struct timeval now; +- struct timespec end; ++ struct timespec now, end; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); + +@@ -987,15 +986,15 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, + return -1; + } + +- if (gettimeofday(&now, NULL) < 0) { ++ if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) { + RTE_LOG(ERR, EAL, "Failed to get current time\n"); + rte_errno = errno; + goto end; + } + +- end.tv_nsec = (now.tv_usec * 1000 + ts->tv_nsec) % 1000000000; ++ end.tv_nsec = (now.tv_nsec + ts->tv_nsec) % 1000000000; + end.tv_sec = now.tv_sec + ts->tv_sec + +- (now.tv_usec * 1000 + ts->tv_nsec) / 1000000000; ++ (now.tv_nsec + ts->tv_nsec) / 1000000000; + + /* for secondary process, send request to the primary process only */ + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { +@@ -1069,7 +1068,7 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, + int dir_fd, ret = 0; + DIR *mp_dir; + struct dirent *ent; +- struct timeval now; ++ struct timespec now; + struct timespec *end; + bool dummy_used = false; + const struct internal_config *internal_conf = +@@ -1086,7 +1085,7 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, + return -1; + } + +- if (gettimeofday(&now, NULL) < 0) { ++ if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) { + RTE_LOG(ERR, EAL, "Failed to get current time\n"); + rte_errno = errno; + return -1; +@@ -1108,9 +1107,9 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, + end = ¶m->end; + reply = ¶m->user_reply; + +- end->tv_nsec = (now.tv_usec * 1000 + ts->tv_nsec) % 1000000000; ++ end->tv_nsec = (now.tv_nsec + ts->tv_nsec) % 1000000000; + end->tv_sec = now.tv_sec + ts->tv_sec + +- (now.tv_usec * 1000 + ts->tv_nsec) / 1000000000; ++ (now.tv_nsec + ts->tv_nsec) / 1000000000; + reply->nb_sent = 0; + reply->nb_received = 0; + reply->msgs = NULL; +-- +2.7.4 + diff --git a/0174-ethdev-add-queue-state-in-queried-queue-information.patch b/0174-ethdev-add-queue-state-in-queried-queue-information.patch new file mode 100644 index 0000000..8171cfa --- /dev/null +++ b/0174-ethdev-add-queue-state-in-queried-queue-information.patch @@ -0,0 +1,120 @@ +From 7516c1b63b53a27215a0206ae1437a3d5d5d0e08 Mon Sep 17 00:00:00 2001 +From: Lijun Ou +Date: Mon, 19 Apr 2021 16:57:30 +0800 +Subject: [PATCH 174/189] ethdev: add queue state in queried queue information + +Currently, upper-layer application could get queue state only +through pointers such as dev->data->tx_queue_state[queue_id], +this is not the recommended way to access it. So this patch +add get queue state when call rte_eth_rx_queue_info_get and +rte_eth_tx_queue_info_get API. + +Note: After add queue_state field, the 'struct rte_eth_rxq_info' size +remains 128B, and the 'struct rte_eth_txq_info' size remains 64B, so +it could be ABI compatible. + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +Acked-by: Konstantin Ananyev +Acked-by: Thomas Monjalon +Reviewed-by: Ferruh Yigit +--- + devtools/libabigail.abignore | 9 +++++++++ + lib/librte_ethdev/rte_ethdev.c | 3 +++ + lib/librte_ethdev/rte_ethdev.h | 9 +++++++++ + lib/librte_ethdev/rte_ethdev_driver.h | 7 ------- + 4 files changed, 21 insertions(+), 7 deletions(-) + +diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore +index 025f2c0..b649af1 100644 +--- a/devtools/libabigail.abignore ++++ b/devtools/libabigail.abignore +@@ -7,3 +7,12 @@ + symbol_version = INTERNAL + [suppress_variable] + symbol_version = INTERNAL ++; Ignore fields inserted in alignment hole of rte_eth_rxq_info ++[suppress_type] ++ name = rte_eth_rxq_info ++ has_data_member_inserted_at = offset_after(scattered_rx) ++ ++; Ignore fields inserted in cacheline boundary of rte_eth_txq_info ++[suppress_type] ++ name = rte_eth_txq_info ++ has_data_member_inserted_between = {offset_after(nb_desc), end} +diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c +index f311868..87d1b56 100644 +--- a/lib/librte_ethdev/rte_ethdev.c ++++ b/lib/librte_ethdev/rte_ethdev.c +@@ -5023,6 +5023,8 @@ rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id, + + memset(qinfo, 0, sizeof(*qinfo)); + dev->dev_ops->rxq_info_get(dev, queue_id, qinfo); ++ qinfo->queue_state = dev->data->rx_queue_state[queue_id]; ++ + return 0; + } + +@@ -5063,6 +5065,7 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id, + + memset(qinfo, 0, sizeof(*qinfo)); + dev->dev_ops->txq_info_get(dev, queue_id, qinfo); ++ qinfo->queue_state = dev->data->tx_queue_state[queue_id]; + + return 0; + } +diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h +index e89fc50..d9ab66d 100644 +--- a/lib/librte_ethdev/rte_ethdev.h ++++ b/lib/librte_ethdev/rte_ethdev.h +@@ -1562,6 +1562,13 @@ struct rte_eth_dev_info { + }; + + /** ++ * RX/TX queue states ++ */ ++#define RTE_ETH_QUEUE_STATE_STOPPED 0 ++#define RTE_ETH_QUEUE_STATE_STARTED 1 ++#define RTE_ETH_QUEUE_STATE_HAIRPIN 2 ++ ++/** + * Ethernet device RX queue information structure. + * Used to retrieve information about configured queue. + */ +@@ -1569,6 +1576,7 @@ struct rte_eth_rxq_info { + struct rte_mempool *mp; /**< mempool used by that queue. */ + struct rte_eth_rxconf conf; /**< queue config parameters. */ + uint8_t scattered_rx; /**< scattered packets RX supported. */ ++ uint8_t queue_state; /**< one of RTE_ETH_QUEUE_STATE_*. */ + uint16_t nb_desc; /**< configured number of RXDs. */ + uint16_t rx_buf_size; /**< hardware receive buffer size. */ + } __rte_cache_min_aligned; +@@ -1580,6 +1588,7 @@ struct rte_eth_rxq_info { + struct rte_eth_txq_info { + struct rte_eth_txconf conf; /**< queue config parameters. */ + uint16_t nb_desc; /**< configured number of TXDs. */ ++ uint8_t queue_state; /**< one of RTE_ETH_QUEUE_STATE_*. */ + } __rte_cache_min_aligned; + + /* Generic Burst mode flag definition, values can be ORed. */ +diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h +index 0eacfd8..6d928a4 100644 +--- a/lib/librte_ethdev/rte_ethdev_driver.h ++++ b/lib/librte_ethdev/rte_ethdev_driver.h +@@ -920,13 +920,6 @@ struct eth_dev_ops { + }; + + /** +- * RX/TX queue states +- */ +-#define RTE_ETH_QUEUE_STATE_STOPPED 0 +-#define RTE_ETH_QUEUE_STATE_STARTED 1 +-#define RTE_ETH_QUEUE_STATE_HAIRPIN 2 +- +-/** + * @internal + * Check if the selected Rx queue is hairpin queue. + * +-- +2.7.4 + diff --git a/0175-app-testpmd-fix-queue-stats-mapping-configuration.patch b/0175-app-testpmd-fix-queue-stats-mapping-configuration.patch new file mode 100644 index 0000000..d84fc38 --- /dev/null +++ b/0175-app-testpmd-fix-queue-stats-mapping-configuration.patch @@ -0,0 +1,769 @@ +From f09441b0cd817ec53d5f059273e3266607de5bcd Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 2 Dec 2020 20:48:55 +0800 +Subject: [PATCH 175/189] app/testpmd: fix queue stats mapping configuration + +Currently, the queue stats mapping has the following problems: +1) Many PMD drivers don't support queue stats mapping. But there is no + failure message after executing the command "set stat_qmap rx 0 2 2". +2) Once queue mapping is set, unrelated and unmapped queues are also + displayed. +3) The configuration result does not take effect or can not be queried + in real time. +4) The mapping arrays, "tx_queue_stats_mappings_array" & + "rx_queue_stats_mappings_array" are global and their sizes are based + on fixed max port and queue size assumptions. +5) These record structures, 'map_port_queue_stats_mapping_registers()' + and its sub functions are redundant for majority of drivers. +6) The display of the queue stats and queue stats mapping is mixed + together. + +Since xstats is used to obtain queue statistics, we have made the +following simplifications and adjustments: +1) If PMD requires and supports queue stats mapping, configure to driver + in real time by calling ethdev API after executing the command "set + stat_qmap rx/tx ...". If not, the command can not be accepted. +2) Based on the above adjustments, these record structures, + 'map_port_queue_stats_mapping_registers()' and its sub functions can + be removed. "tx-queue-stats-mapping" & "rx-queue-stats-mapping" + parameters, and 'parse_queue_stats_mapping_config()' can be removed + too. +3) remove display of queue stats mapping in 'fwd_stats_display()' & + 'nic_stats_display()', and obtain queue stats by xstats. Since the + record structures are removed, 'nic_stats_mapping_display()' can be + deleted. + +Fixes: 4dccdc789bf4 ("app/testpmd: simplify handling of stats mappings error") +Fixes: 013af9b6b64f ("app/testpmd: various updates") +Fixes: ed30d9b691b2 ("app/testpmd: add stats per queue") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Reviewed-by: Ferruh Yigit +--- + app/test-pmd/cmdline.c | 17 ++--- + app/test-pmd/config.c | 144 +++++----------------------------- + app/test-pmd/parameters.c | 107 -------------------------- + app/test-pmd/testpmd.c | 191 +++++----------------------------------------- + app/test-pmd/testpmd.h | 22 ------ + 5 files changed, 46 insertions(+), 435 deletions(-) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index 0d2d6aa..2ccbaa0 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -163,7 +163,7 @@ static void cmd_help_long_parsed(void *parsed_result, + "Display:\n" + "--------\n\n" + +- "show port (info|stats|summary|xstats|fdir|stat_qmap|dcb_tc|cap) (port_id|all)\n" ++ "show port (info|stats|summary|xstats|fdir|dcb_tc|cap) (port_id|all)\n" + " Display information for port_id, or all.\n\n" + + "show port port_id (module_eeprom|eeprom)\n" +@@ -177,7 +177,7 @@ static void cmd_help_long_parsed(void *parsed_result, + "show port (port_id) rss-hash [key]\n" + " Display the RSS hash functions and RSS hash key of port\n\n" + +- "clear port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n" ++ "clear port (info|stats|xstats|fdir) (port_id|all)\n" + " Clear information for port_id, or all.\n\n" + + "show (rxq|txq) info (port_id) (queue_id)\n" +@@ -7555,9 +7555,6 @@ static void cmd_showportall_parsed(void *parsed_result, + RTE_ETH_FOREACH_DEV(i) + fdir_get_infos(i); + #endif +- else if (!strcmp(res->what, "stat_qmap")) +- RTE_ETH_FOREACH_DEV(i) +- nic_stats_mapping_display(i); + else if (!strcmp(res->what, "dcb_tc")) + RTE_ETH_FOREACH_DEV(i) + port_dcb_info_display(i); +@@ -7573,14 +7570,14 @@ cmdline_parse_token_string_t cmd_showportall_port = + TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port"); + cmdline_parse_token_string_t cmd_showportall_what = + TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what, +- "info#summary#stats#xstats#fdir#stat_qmap#dcb_tc#cap"); ++ "info#summary#stats#xstats#fdir#dcb_tc#cap"); + cmdline_parse_token_string_t cmd_showportall_all = + TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all"); + cmdline_parse_inst_t cmd_showportall = { + .f = cmd_showportall_parsed, + .data = NULL, + .help_str = "show|clear port " +- "info|summary|stats|xstats|fdir|stat_qmap|dcb_tc|cap all", ++ "info|summary|stats|xstats|fdir|dcb_tc|cap all", + .tokens = { + (void *)&cmd_showportall_show, + (void *)&cmd_showportall_port, +@@ -7622,8 +7619,6 @@ static void cmd_showport_parsed(void *parsed_result, + else if (!strcmp(res->what, "fdir")) + fdir_get_infos(res->portnum); + #endif +- else if (!strcmp(res->what, "stat_qmap")) +- nic_stats_mapping_display(res->portnum); + else if (!strcmp(res->what, "dcb_tc")) + port_dcb_info_display(res->portnum); + else if (!strcmp(res->what, "cap")) +@@ -7637,7 +7632,7 @@ cmdline_parse_token_string_t cmd_showport_port = + TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port"); + cmdline_parse_token_string_t cmd_showport_what = + TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what, +- "info#summary#stats#xstats#fdir#stat_qmap#dcb_tc#cap"); ++ "info#summary#stats#xstats#fdir#dcb_tc#cap"); + cmdline_parse_token_num_t cmd_showport_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, RTE_UINT16); + +@@ -7645,7 +7640,7 @@ cmdline_parse_inst_t cmd_showport = { + .f = cmd_showport_parsed, + .data = NULL, + .help_str = "show|clear port " +- "info|summary|stats|xstats|fdir|stat_qmap|dcb_tc|cap " ++ "info|summary|stats|xstats|fdir|dcb_tc|cap " + "", + .tokens = { + (void *)&cmd_showport_show, +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index b51de59..3f6c864 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -183,8 +183,6 @@ nic_stats_display(portid_t port_id) + diff_ns; + uint64_t mpps_rx, mpps_tx, mbps_rx, mbps_tx; + struct rte_eth_stats stats; +- struct rte_port *port = &ports[port_id]; +- uint8_t i; + + static const char *nic_stats_border = "########################"; + +@@ -196,46 +194,12 @@ nic_stats_display(portid_t port_id) + printf("\n %s NIC statistics for port %-2d %s\n", + nic_stats_border, port_id, nic_stats_border); + +- if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { +- printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: " +- "%-"PRIu64"\n", +- stats.ipackets, stats.imissed, stats.ibytes); +- printf(" RX-errors: %-"PRIu64"\n", stats.ierrors); +- printf(" RX-nombuf: %-10"PRIu64"\n", +- stats.rx_nombuf); +- printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: " +- "%-"PRIu64"\n", +- stats.opackets, stats.oerrors, stats.obytes); +- } +- else { +- printf(" RX-packets: %10"PRIu64" RX-errors: %10"PRIu64 +- " RX-bytes: %10"PRIu64"\n", +- stats.ipackets, stats.ierrors, stats.ibytes); +- printf(" RX-errors: %10"PRIu64"\n", stats.ierrors); +- printf(" RX-nombuf: %10"PRIu64"\n", +- stats.rx_nombuf); +- printf(" TX-packets: %10"PRIu64" TX-errors: %10"PRIu64 +- " TX-bytes: %10"PRIu64"\n", +- stats.opackets, stats.oerrors, stats.obytes); +- } +- +- if (port->rx_queue_stats_mapping_enabled) { +- printf("\n"); +- for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { +- printf(" Stats reg %2d RX-packets: %10"PRIu64 +- " RX-errors: %10"PRIu64 +- " RX-bytes: %10"PRIu64"\n", +- i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]); +- } +- } +- if (port->tx_queue_stats_mapping_enabled) { +- printf("\n"); +- for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { +- printf(" Stats reg %2d TX-packets: %10"PRIu64 +- " TX-bytes: %10"PRIu64"\n", +- i, stats.q_opackets[i], stats.q_obytes[i]); +- } +- } ++ printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: " ++ "%-"PRIu64"\n", stats.ipackets, stats.imissed, stats.ibytes); ++ printf(" RX-errors: %-"PRIu64"\n", stats.ierrors); ++ printf(" RX-nombuf: %-10"PRIu64"\n", stats.rx_nombuf); ++ printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: " ++ "%-"PRIu64"\n", stats.opackets, stats.oerrors, stats.obytes); + + diff_ns = 0; + if (clock_gettime(CLOCK_TYPE_ID, &cur_time) == 0) { +@@ -399,54 +363,6 @@ nic_xstats_clear(portid_t port_id) + } + + void +-nic_stats_mapping_display(portid_t port_id) +-{ +- struct rte_port *port = &ports[port_id]; +- uint16_t i; +- +- static const char *nic_stats_mapping_border = "########################"; +- +- if (port_id_is_invalid(port_id, ENABLED_WARN)) { +- print_valid_ports(); +- return; +- } +- +- if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { +- printf("Port id %d - either does not support queue statistic mapping or" +- " no queue statistic mapping set\n", port_id); +- return; +- } +- +- printf("\n %s NIC statistics mapping for port %-2d %s\n", +- nic_stats_mapping_border, port_id, nic_stats_mapping_border); +- +- if (port->rx_queue_stats_mapping_enabled) { +- for (i = 0; i < nb_rx_queue_stats_mappings; i++) { +- if (rx_queue_stats_mappings[i].port_id == port_id) { +- printf(" RX-queue %2d mapped to Stats Reg %2d\n", +- rx_queue_stats_mappings[i].queue_id, +- rx_queue_stats_mappings[i].stats_counter_id); +- } +- } +- printf("\n"); +- } +- +- +- if (port->tx_queue_stats_mapping_enabled) { +- for (i = 0; i < nb_tx_queue_stats_mappings; i++) { +- if (tx_queue_stats_mappings[i].port_id == port_id) { +- printf(" TX-queue %2d mapped to Stats Reg %2d\n", +- tx_queue_stats_mappings[i].queue_id, +- tx_queue_stats_mappings[i].stats_counter_id); +- } +- } +- } +- +- printf(" %s####################################%s\n", +- nic_stats_mapping_border, nic_stats_mapping_border); +-} +- +-void + rx_queue_infos_display(portid_t port_id, uint16_t queue_id) + { + struct rte_eth_burst_mode mode; +@@ -2573,7 +2489,7 @@ tx_queue_id_is_invalid(queueid_t txq_id) + { + if (txq_id < nb_txq) + return 0; +- printf("Invalid TX queue %d (must be < nb_rxq=%d)\n", txq_id, nb_txq); ++ printf("Invalid TX queue %d (must be < nb_txq=%d)\n", txq_id, nb_txq); + return 1; + } + +@@ -4528,8 +4444,7 @@ tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on) + void + set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value) + { +- uint16_t i; +- uint8_t existing_mapping_found = 0; ++ int ret; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; +@@ -4539,40 +4454,23 @@ set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value) + + if (map_value >= RTE_ETHDEV_QUEUE_STAT_CNTRS) { + printf("map_value not in required range 0..%d\n", +- RTE_ETHDEV_QUEUE_STAT_CNTRS - 1); ++ RTE_ETHDEV_QUEUE_STAT_CNTRS - 1); + return; + } + +- if (!is_rx) { /*then tx*/ +- for (i = 0; i < nb_tx_queue_stats_mappings; i++) { +- if ((tx_queue_stats_mappings[i].port_id == port_id) && +- (tx_queue_stats_mappings[i].queue_id == queue_id)) { +- tx_queue_stats_mappings[i].stats_counter_id = map_value; +- existing_mapping_found = 1; +- break; +- } +- } +- if (!existing_mapping_found) { /* A new additional mapping... */ +- tx_queue_stats_mappings[nb_tx_queue_stats_mappings].port_id = port_id; +- tx_queue_stats_mappings[nb_tx_queue_stats_mappings].queue_id = queue_id; +- tx_queue_stats_mappings[nb_tx_queue_stats_mappings].stats_counter_id = map_value; +- nb_tx_queue_stats_mappings++; +- } +- } +- else { /*rx*/ +- for (i = 0; i < nb_rx_queue_stats_mappings; i++) { +- if ((rx_queue_stats_mappings[i].port_id == port_id) && +- (rx_queue_stats_mappings[i].queue_id == queue_id)) { +- rx_queue_stats_mappings[i].stats_counter_id = map_value; +- existing_mapping_found = 1; +- break; +- } ++ if (!is_rx) { /* tx */ ++ ret = rte_eth_dev_set_tx_queue_stats_mapping(port_id, queue_id, ++ map_value); ++ if (ret) { ++ printf("failed to set tx queue stats mapping.\n"); ++ return; + } +- if (!existing_mapping_found) { /* A new additional mapping... */ +- rx_queue_stats_mappings[nb_rx_queue_stats_mappings].port_id = port_id; +- rx_queue_stats_mappings[nb_rx_queue_stats_mappings].queue_id = queue_id; +- rx_queue_stats_mappings[nb_rx_queue_stats_mappings].stats_counter_id = map_value; +- nb_rx_queue_stats_mappings++; ++ } else { /* rx */ ++ ret = rte_eth_dev_set_rx_queue_stats_mapping(port_id, queue_id, ++ map_value); ++ if (ret) { ++ printf("failed to set rx queue stats mapping.\n"); ++ return; + } + } + } +diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c +index bbb68a5..414a006 100644 +--- a/app/test-pmd/parameters.c ++++ b/app/test-pmd/parameters.c +@@ -176,12 +176,6 @@ usage(char* progname) + "(0 <= N <= value of txd).\n"); + printf(" --txrst=N: set the transmit RS bit threshold of TX rings to N " + "(0 <= N <= value of txd).\n"); +- printf(" --tx-queue-stats-mapping=(port,queue,mapping)[,(port,queue,mapping]: " +- "tx queues statistics counters mapping " +- "(0 <= mapping <= %d).\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1); +- printf(" --rx-queue-stats-mapping=(port,queue,mapping)[,(port,queue,mapping]: " +- "rx queues statistics counters mapping " +- "(0 <= mapping <= %d).\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1); + printf(" --no-flush-rx: Don't flush RX streams before forwarding." + " Used mainly with PCAP drivers.\n"); + printf(" --rxoffs=X[,Y]*: set RX segment offsets for split.\n"); +@@ -300,93 +294,6 @@ parse_fwd_portmask(const char *portmask) + set_fwd_ports_mask((uint64_t) pm); + } + +- +-static int +-parse_queue_stats_mapping_config(const char *q_arg, int is_rx) +-{ +- char s[256]; +- const char *p, *p0 = q_arg; +- char *end; +- enum fieldnames { +- FLD_PORT = 0, +- FLD_QUEUE, +- FLD_STATS_COUNTER, +- _NUM_FLD +- }; +- unsigned long int_fld[_NUM_FLD]; +- char *str_fld[_NUM_FLD]; +- int i; +- unsigned size; +- +- /* reset from value set at definition */ +- is_rx ? (nb_rx_queue_stats_mappings = 0) : (nb_tx_queue_stats_mappings = 0); +- +- while ((p = strchr(p0,'(')) != NULL) { +- ++p; +- if((p0 = strchr(p,')')) == NULL) +- return -1; +- +- size = p0 - p; +- if(size >= sizeof(s)) +- return -1; +- +- snprintf(s, sizeof(s), "%.*s", size, p); +- if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD) +- return -1; +- for (i = 0; i < _NUM_FLD; i++){ +- errno = 0; +- int_fld[i] = strtoul(str_fld[i], &end, 0); +- if (errno != 0 || end == str_fld[i] || int_fld[i] > 255) +- return -1; +- } +- /* Check mapping field is in correct range (0..RTE_ETHDEV_QUEUE_STAT_CNTRS-1) */ +- if (int_fld[FLD_STATS_COUNTER] >= RTE_ETHDEV_QUEUE_STAT_CNTRS) { +- printf("Stats counter not in the correct range 0..%d\n", +- RTE_ETHDEV_QUEUE_STAT_CNTRS - 1); +- return -1; +- } +- +- if (!is_rx) { +- if ((nb_tx_queue_stats_mappings >= +- MAX_TX_QUEUE_STATS_MAPPINGS)) { +- printf("exceeded max number of TX queue " +- "statistics mappings: %hu\n", +- nb_tx_queue_stats_mappings); +- return -1; +- } +- tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].port_id = +- (uint8_t)int_fld[FLD_PORT]; +- tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].queue_id = +- (uint8_t)int_fld[FLD_QUEUE]; +- tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].stats_counter_id = +- (uint8_t)int_fld[FLD_STATS_COUNTER]; +- ++nb_tx_queue_stats_mappings; +- } +- else { +- if ((nb_rx_queue_stats_mappings >= +- MAX_RX_QUEUE_STATS_MAPPINGS)) { +- printf("exceeded max number of RX queue " +- "statistics mappings: %hu\n", +- nb_rx_queue_stats_mappings); +- return -1; +- } +- rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].port_id = +- (uint8_t)int_fld[FLD_PORT]; +- rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].queue_id = +- (uint8_t)int_fld[FLD_QUEUE]; +- rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].stats_counter_id = +- (uint8_t)int_fld[FLD_STATS_COUNTER]; +- ++nb_rx_queue_stats_mappings; +- } +- +- } +-/* Reassign the rx/tx_queue_stats_mappings pointer to point to this newly populated array rather */ +-/* than to the default array (that was set at its definition) */ +- is_rx ? (rx_queue_stats_mappings = rx_queue_stats_mappings_array) : +- (tx_queue_stats_mappings = tx_queue_stats_mappings_array); +- return 0; +-} +- + static void + print_invalid_socket_id_error(void) + { +@@ -664,8 +571,6 @@ launch_args_parse(int argc, char** argv) + { "rxht", 1, 0, 0 }, + { "rxwt", 1, 0, 0 }, + { "rxfreet", 1, 0, 0 }, +- { "tx-queue-stats-mapping", 1, 0, 0 }, +- { "rx-queue-stats-mapping", 1, 0, 0 }, + { "no-flush-rx", 0, 0, 0 }, + { "flow-isolate-all", 0, 0, 0 }, + { "rxoffs", 1, 0, 0 }, +@@ -1279,18 +1184,6 @@ launch_args_parse(int argc, char** argv) + else + rte_exit(EXIT_FAILURE, "rxfreet must be >= 0\n"); + } +- if (!strcmp(lgopts[opt_idx].name, "tx-queue-stats-mapping")) { +- if (parse_queue_stats_mapping_config(optarg, TX)) { +- rte_exit(EXIT_FAILURE, +- "invalid TX queue statistics mapping config entered\n"); +- } +- } +- if (!strcmp(lgopts[opt_idx].name, "rx-queue-stats-mapping")) { +- if (parse_queue_stats_mapping_config(optarg, RX)) { +- rte_exit(EXIT_FAILURE, +- "invalid RX queue statistics mapping config entered\n"); +- } +- } + if (!strcmp(lgopts[opt_idx].name, "rxoffs")) { + unsigned int seg_off[MAX_SEGS_BUFFER_SPLIT]; + unsigned int nb_offs; +diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c +index 33fc0fd..33a060d 100644 +--- a/app/test-pmd/testpmd.c ++++ b/app/test-pmd/testpmd.c +@@ -476,15 +476,6 @@ struct rte_fdir_conf fdir_conf = { + + volatile int test_done = 1; /* stop packet forwarding when set to 1. */ + +-struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; +-struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; +- +-struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; +-struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; +- +-uint16_t nb_tx_queue_stats_mappings = 0; +-uint16_t nb_rx_queue_stats_mappings = 0; +- + /* + * Display zero values by default for xstats + */ +@@ -520,8 +511,6 @@ enum rte_eth_rx_mq_mode rx_mq_mode = ETH_MQ_RX_VMDQ_DCB_RSS; + + /* Forward function declarations */ + static void setup_attached_port(portid_t pi); +-static void map_port_queue_stats_mapping_registers(portid_t pi, +- struct rte_port *port); + static void check_all_ports_link_status(uint32_t port_mask); + static int eth_event_callback(portid_t port_id, + enum rte_eth_event_type type, +@@ -1857,8 +1846,6 @@ fwd_stats_display(void) + fwd_cycles += fs->core_cycles; + } + for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { +- uint8_t j; +- + pt_id = fwd_ports_ids[i]; + port = &ports[pt_id]; + +@@ -1881,88 +1868,34 @@ fwd_stats_display(void) + printf("\n %s Forward statistics for port %-2d %s\n", + fwd_stats_border, pt_id, fwd_stats_border); + +- if (!port->rx_queue_stats_mapping_enabled && +- !port->tx_queue_stats_mapping_enabled) { +- printf(" RX-packets: %-14"PRIu64 +- " RX-dropped: %-14"PRIu64 +- "RX-total: %-"PRIu64"\n", +- stats.ipackets, stats.imissed, +- stats.ipackets + stats.imissed); +- +- if (cur_fwd_eng == &csum_fwd_engine) +- printf(" Bad-ipcsum: %-14"PRIu64 +- " Bad-l4csum: %-14"PRIu64 +- "Bad-outer-l4csum: %-14"PRIu64"\n", +- ports_stats[pt_id].rx_bad_ip_csum, +- ports_stats[pt_id].rx_bad_l4_csum, +- ports_stats[pt_id].rx_bad_outer_l4_csum); +- if (stats.ierrors + stats.rx_nombuf > 0) { +- printf(" RX-error: %-"PRIu64"\n", +- stats.ierrors); +- printf(" RX-nombufs: %-14"PRIu64"\n", +- stats.rx_nombuf); +- } ++ printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64 ++ "RX-total: %-"PRIu64"\n", stats.ipackets, stats.imissed, ++ stats.ipackets + stats.imissed); + +- printf(" TX-packets: %-14"PRIu64 +- " TX-dropped: %-14"PRIu64 +- "TX-total: %-"PRIu64"\n", +- stats.opackets, ports_stats[pt_id].tx_dropped, +- stats.opackets + ports_stats[pt_id].tx_dropped); +- } else { +- printf(" RX-packets: %14"PRIu64 +- " RX-dropped:%14"PRIu64 +- " RX-total:%14"PRIu64"\n", +- stats.ipackets, stats.imissed, +- stats.ipackets + stats.imissed); +- +- if (cur_fwd_eng == &csum_fwd_engine) +- printf(" Bad-ipcsum:%14"PRIu64 +- " Bad-l4csum:%14"PRIu64 +- " Bad-outer-l4csum: %-14"PRIu64"\n", +- ports_stats[pt_id].rx_bad_ip_csum, +- ports_stats[pt_id].rx_bad_l4_csum, +- ports_stats[pt_id].rx_bad_outer_l4_csum); +- if ((stats.ierrors + stats.rx_nombuf) > 0) { +- printf(" RX-error:%"PRIu64"\n", stats.ierrors); +- printf(" RX-nombufs: %14"PRIu64"\n", +- stats.rx_nombuf); +- } +- +- printf(" TX-packets: %14"PRIu64 +- " TX-dropped:%14"PRIu64 +- " TX-total:%14"PRIu64"\n", +- stats.opackets, ports_stats[pt_id].tx_dropped, +- stats.opackets + ports_stats[pt_id].tx_dropped); ++ if (cur_fwd_eng == &csum_fwd_engine) ++ printf(" Bad-ipcsum: %-14"PRIu64 ++ " Bad-l4csum: %-14"PRIu64 ++ "Bad-outer-l4csum: %-14"PRIu64"\n", ++ ports_stats[pt_id].rx_bad_ip_csum, ++ ports_stats[pt_id].rx_bad_l4_csum, ++ ports_stats[pt_id].rx_bad_outer_l4_csum); ++ if (stats.ierrors + stats.rx_nombuf > 0) { ++ printf(" RX-error: %-"PRIu64"\n", stats.ierrors); ++ printf(" RX-nombufs: %-14"PRIu64"\n", stats.rx_nombuf); + } + ++ printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64 ++ "TX-total: %-"PRIu64"\n", ++ stats.opackets, ports_stats[pt_id].tx_dropped, ++ stats.opackets + ports_stats[pt_id].tx_dropped); ++ + if (record_burst_stats) { + if (ports_stats[pt_id].rx_stream) + pkt_burst_stats_display("RX", + &ports_stats[pt_id].rx_stream->rx_burst_stats); + if (ports_stats[pt_id].tx_stream) + pkt_burst_stats_display("TX", +- &ports_stats[pt_id].tx_stream->tx_burst_stats); +- } +- +- if (port->rx_queue_stats_mapping_enabled) { +- printf("\n"); +- for (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) { +- printf(" Stats reg %2d RX-packets:%14"PRIu64 +- " RX-errors:%14"PRIu64 +- " RX-bytes:%14"PRIu64"\n", +- j, stats.q_ipackets[j], +- stats.q_errors[j], stats.q_ibytes[j]); +- } +- printf("\n"); +- } +- if (port->tx_queue_stats_mapping_enabled) { +- for (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) { +- printf(" Stats reg %2d TX-packets:%14"PRIu64 +- " TX-bytes:%14" +- PRIu64"\n", +- j, stats.q_opackets[j], +- stats.q_obytes[j]); +- } ++ &ports_stats[pt_id].tx_stream->tx_burst_stats); + } + + printf(" %s--------------------------------%s\n", +@@ -2236,11 +2169,6 @@ start_packet_forwarding(int with_tx_first) + rxtx_config_display(); + + fwd_stats_reset(); +- for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { +- pt_id = fwd_ports_ids[i]; +- port = &ports[pt_id]; +- map_port_queue_stats_mapping_registers(pt_id, port); +- } + if (with_tx_first) { + port_fwd_begin = tx_only_engine.port_fwd_begin; + if (port_fwd_begin != NULL) { +@@ -3352,84 +3280,6 @@ dev_event_callback(const char *device_name, enum rte_dev_event_type type, + } + } + +-static int +-set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) +-{ +- uint16_t i; +- int diag; +- uint8_t mapping_found = 0; +- +- for (i = 0; i < nb_tx_queue_stats_mappings; i++) { +- if ((tx_queue_stats_mappings[i].port_id == port_id) && +- (tx_queue_stats_mappings[i].queue_id < nb_txq )) { +- diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, +- tx_queue_stats_mappings[i].queue_id, +- tx_queue_stats_mappings[i].stats_counter_id); +- if (diag != 0) +- return diag; +- mapping_found = 1; +- } +- } +- if (mapping_found) +- port->tx_queue_stats_mapping_enabled = 1; +- return 0; +-} +- +-static int +-set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) +-{ +- uint16_t i; +- int diag; +- uint8_t mapping_found = 0; +- +- for (i = 0; i < nb_rx_queue_stats_mappings; i++) { +- if ((rx_queue_stats_mappings[i].port_id == port_id) && +- (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { +- diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, +- rx_queue_stats_mappings[i].queue_id, +- rx_queue_stats_mappings[i].stats_counter_id); +- if (diag != 0) +- return diag; +- mapping_found = 1; +- } +- } +- if (mapping_found) +- port->rx_queue_stats_mapping_enabled = 1; +- return 0; +-} +- +-static void +-map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port) +-{ +- int diag = 0; +- +- diag = set_tx_queue_stats_mapping_registers(pi, port); +- if (diag != 0) { +- if (diag == -ENOTSUP) { +- port->tx_queue_stats_mapping_enabled = 0; +- printf("TX queue stats mapping not supported port id=%d\n", pi); +- } +- else +- rte_exit(EXIT_FAILURE, +- "set_tx_queue_stats_mapping_registers " +- "failed for port id=%d diag=%d\n", +- pi, diag); +- } +- +- diag = set_rx_queue_stats_mapping_registers(pi, port); +- if (diag != 0) { +- if (diag == -ENOTSUP) { +- port->rx_queue_stats_mapping_enabled = 0; +- printf("RX queue stats mapping not supported port id=%d\n", pi); +- } +- else +- rte_exit(EXIT_FAILURE, +- "set_rx_queue_stats_mapping_registers " +- "failed for port id=%d diag=%d\n", +- pi, diag); +- } +-} +- + static void + rxtx_port_config(struct rte_port *port) + { +@@ -3526,7 +3376,6 @@ init_port_config(void) + if (ret != 0) + return; + +- map_port_queue_stats_mapping_registers(pid, port); + #if defined RTE_NET_IXGBE && defined RTE_LIBRTE_IXGBE_BYPASS + rte_pmd_ixgbe_bypass_init(pid); + #endif +@@ -3737,8 +3586,6 @@ init_port_dcb_config(portid_t pid, + if (retval != 0) + return retval; + +- map_port_queue_stats_mapping_registers(pid, rte_port); +- + rte_port->dcb_flag = 1; + + return 0; +diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h +index 6b901a8..5f23162 100644 +--- a/app/test-pmd/testpmd.h ++++ b/app/test-pmd/testpmd.h +@@ -206,8 +206,6 @@ struct rte_port { + uint16_t tunnel_tso_segsz; /**< Segmentation offload MSS for tunneled pkts. */ + uint16_t tx_vlan_id;/**< The tag ID */ + uint16_t tx_vlan_id_outer;/**< The outer tag ID */ +- uint8_t tx_queue_stats_mapping_enabled; +- uint8_t rx_queue_stats_mapping_enabled; + volatile uint16_t port_status; /**< port started or not */ + uint8_t need_setup; /**< port just attached */ + uint8_t need_reconfig; /**< need reconfiguring port or not */ +@@ -326,25 +324,6 @@ enum dcb_mode_enable + DCB_ENABLED + }; + +-#define MAX_TX_QUEUE_STATS_MAPPINGS 1024 /* MAX_PORT of 32 @ 32 tx_queues/port */ +-#define MAX_RX_QUEUE_STATS_MAPPINGS 4096 /* MAX_PORT of 32 @ 128 rx_queues/port */ +- +-struct queue_stats_mappings { +- portid_t port_id; +- uint16_t queue_id; +- uint8_t stats_counter_id; +-} __rte_cache_aligned; +- +-extern struct queue_stats_mappings tx_queue_stats_mappings_array[]; +-extern struct queue_stats_mappings rx_queue_stats_mappings_array[]; +- +-/* Assign both tx and rx queue stats mappings to the same default values */ +-extern struct queue_stats_mappings *tx_queue_stats_mappings; +-extern struct queue_stats_mappings *rx_queue_stats_mappings; +- +-extern uint16_t nb_tx_queue_stats_mappings; +-extern uint16_t nb_rx_queue_stats_mappings; +- + extern uint8_t xstats_hide_zero; /**< Hide zero values for xstats display */ + + /* globals used for configuration */ +@@ -790,7 +769,6 @@ void nic_stats_display(portid_t port_id); + void nic_stats_clear(portid_t port_id); + void nic_xstats_display(portid_t port_id); + void nic_xstats_clear(portid_t port_id); +-void nic_stats_mapping_display(portid_t port_id); + void device_infos_display(const char *identifier); + void port_infos_display(portid_t port_id); + void port_summary_display(portid_t port_id); +-- +2.7.4 + diff --git a/0176-app-testpmd-fix-bitmap-of-link-speeds-when-force-spe.patch b/0176-app-testpmd-fix-bitmap-of-link-speeds-when-force-spe.patch new file mode 100644 index 0000000..c38659e --- /dev/null +++ b/0176-app-testpmd-fix-bitmap-of-link-speeds-when-force-spe.patch @@ -0,0 +1,38 @@ +From 3674253a345d4f953044369ca906212af2f04819 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 14 Apr 2021 11:02:05 +0800 +Subject: [PATCH 176/189] app/testpmd: fix bitmap of link speeds when force + speed + +Currently, when the user sets force link speed through 'link_speeds', +bit(0) of 'link_speeds' is not set to 1(ETH_LINK_SPEED_FIXED), +which conflicts with the definition. + +Fixes: 88fbedcd5e5a ("app/testpmd: move speed and duplex parsing in a function") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +Acked-by: Ferruh Yigit +Acked-by: Ajit Khaparde +--- + app/test-pmd/cmdline.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index 2ccbaa0..8446ecc 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -1521,6 +1521,9 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed) + } + } + ++ if (*speed != ETH_LINK_SPEED_AUTONEG) ++ *speed |= ETH_LINK_SPEED_FIXED; ++ + return 0; + } + +-- +2.7.4 + diff --git a/0177-app-testpmd-add-link-autoneg-status-display.patch b/0177-app-testpmd-add-link-autoneg-status-display.patch new file mode 100644 index 0000000..fb8807c --- /dev/null +++ b/0177-app-testpmd-add-link-autoneg-status-display.patch @@ -0,0 +1,30 @@ +From 465efdb2120519aba339a2754afaf71e7bf34ec5 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Thu, 15 Apr 2021 14:45:15 +0800 +Subject: [PATCH 177/189] app/testpmd: add link autoneg status display + +This patch adds link autoneg status display in port_infos_display(). + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +Acked-by: Xiaoyun Li +--- + app/test-pmd/config.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index 3f6c864..d4ec3ff 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -618,6 +618,8 @@ port_infos_display(portid_t port_id) + printf("Link speed: %s\n", rte_eth_link_speed_to_str(link.link_speed)); + printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex")); ++ printf("Autoneg status: %s\n", (link.link_autoneg == ETH_LINK_AUTONEG) ? ++ ("On") : ("Off")); + + if (!rte_eth_dev_get_mtu(port_id, &mtu)) + printf("MTU: %u\n", mtu); +-- +2.7.4 + diff --git a/0178-app-testpmd-support-cleanup-Tx-queue-mbufs.patch b/0178-app-testpmd-support-cleanup-Tx-queue-mbufs.patch new file mode 100644 index 0000000..8cb49f4 --- /dev/null +++ b/0178-app-testpmd-support-cleanup-Tx-queue-mbufs.patch @@ -0,0 +1,152 @@ +From 495e9454badc1ee809923d412db13f8e5bae1dca Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 21 Apr 2021 16:45:02 +0800 +Subject: [PATCH 178/189] app/testpmd: support cleanup Tx queue mbufs + +This patch supports cleanup txq mbufs command: +port cleanup (port_id) txq (queue_id) (free_cnt) + +Signed-off-by: Chengwen Feng +Signed-off-by: Lijun Ou +Reviewed-by: Ferruh Yigit +--- + app/test-pmd/cmdline.c | 88 +++++++++++++++++++++++++++++ + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 9 +++ + 2 files changed, 97 insertions(+) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index 8446ecc..8832416 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -898,6 +898,9 @@ static void cmd_help_long_parsed(void *parsed_result, + " Register a dynf and Set/clear this flag on Tx. " + "Testpmd will set this value to any Tx packet " + "sent from this port\n\n" ++ ++ "port cleanup (port_id) txq (queue_id) (free_cnt)\n" ++ " Cleanup txq mbufs for a specific Tx queue\n\n" + ); + } + +@@ -2439,6 +2442,90 @@ cmdline_parse_inst_t cmd_config_rss_hash_key = { + }, + }; + ++/* *** cleanup txq mbufs *** */ ++struct cmd_cleanup_txq_mbufs_result { ++ cmdline_fixed_string_t port; ++ cmdline_fixed_string_t keyword; ++ cmdline_fixed_string_t name; ++ uint16_t port_id; ++ uint16_t queue_id; ++ uint32_t free_cnt; ++}; ++ ++static void ++cmd_cleanup_txq_mbufs_parsed(void *parsed_result, ++ __rte_unused struct cmdline *cl, ++ __rte_unused void *data) ++{ ++ struct cmd_cleanup_txq_mbufs_result *res = parsed_result; ++ uint16_t port_id = res->port_id; ++ uint16_t queue_id = res->queue_id; ++ uint32_t free_cnt = res->free_cnt; ++ struct rte_eth_txq_info qinfo; ++ int ret; ++ ++ if (test_done == 0) { ++ printf("Please stop forwarding first\n"); ++ return; ++ } ++ ++ if (rte_eth_tx_queue_info_get(port_id, queue_id, &qinfo)) { ++ printf("Failed to get port %u Tx queue %u info\n", ++ port_id, queue_id); ++ return; ++ } ++ ++ if (qinfo.queue_state != RTE_ETH_QUEUE_STATE_STARTED) { ++ printf("Tx queue %u not started\n", queue_id); ++ return; ++ } ++ ++ ret = rte_eth_tx_done_cleanup(port_id, queue_id, free_cnt); ++ if (ret < 0) { ++ printf("Failed to cleanup mbuf for port %u Tx queue %u " ++ "error desc: %s(%d)\n", ++ port_id, queue_id, strerror(-ret), ret); ++ return; ++ } ++ ++ printf("Cleanup port %u Tx queue %u mbuf nums: %u\n", ++ port_id, queue_id, ret); ++} ++ ++cmdline_parse_token_string_t cmd_cleanup_txq_mbufs_port = ++ TOKEN_STRING_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, port, ++ "port"); ++cmdline_parse_token_string_t cmd_cleanup_txq_mbufs_cleanup = ++ TOKEN_STRING_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, keyword, ++ "cleanup"); ++cmdline_parse_token_num_t cmd_cleanup_txq_mbufs_port_id = ++ TOKEN_NUM_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, port_id, ++ RTE_UINT16); ++cmdline_parse_token_string_t cmd_cleanup_txq_mbufs_txq = ++ TOKEN_STRING_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, name, ++ "txq"); ++cmdline_parse_token_num_t cmd_cleanup_txq_mbufs_queue_id = ++ TOKEN_NUM_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, queue_id, ++ RTE_UINT16); ++cmdline_parse_token_num_t cmd_cleanup_txq_mbufs_free_cnt = ++ TOKEN_NUM_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, free_cnt, ++ RTE_UINT32); ++ ++cmdline_parse_inst_t cmd_cleanup_txq_mbufs = { ++ .f = cmd_cleanup_txq_mbufs_parsed, ++ .data = NULL, ++ .help_str = "port cleanup txq ", ++ .tokens = { ++ (void *)&cmd_cleanup_txq_mbufs_port, ++ (void *)&cmd_cleanup_txq_mbufs_cleanup, ++ (void *)&cmd_cleanup_txq_mbufs_port_id, ++ (void *)&cmd_cleanup_txq_mbufs_txq, ++ (void *)&cmd_cleanup_txq_mbufs_queue_id, ++ (void *)&cmd_cleanup_txq_mbufs_free_cnt, ++ NULL, ++ }, ++}; ++ + /* *** configure port rxq/txq ring size *** */ + struct cmd_config_rxtx_ring_size { + cmdline_fixed_string_t port; +@@ -16947,6 +17034,7 @@ cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_showport_rss_hash, + (cmdline_parse_inst_t *)&cmd_showport_rss_hash_key, + (cmdline_parse_inst_t *)&cmd_config_rss_hash_key, ++ (cmdline_parse_inst_t *)&cmd_cleanup_txq_mbufs, + (cmdline_parse_inst_t *)&cmd_dump, + (cmdline_parse_inst_t *)&cmd_dump_one, + #ifdef RTE_NET_I40E +diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst +index 9be4500..de90726 100644 +--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst ++++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst +@@ -2415,6 +2415,15 @@ hash of input [IP] packets received on port:: + ipv6-udp-ex ) + ++port cleanup txq mbufs ++~~~~~~~~~~~~~~~~~~~~~~ ++ ++To cleanup txq mbufs currently cached by driver:: ++ ++ testpmd> port cleanup (port_id) txq (queue_id) (free_cnt) ++ ++If the value of ``free_cnt`` is 0, driver should free all cached mbufs. ++ + Device Functions + ---------------- + +-- +2.7.4 + diff --git a/0179-app-testpmd-show-link-flow-control-info.patch b/0179-app-testpmd-show-link-flow-control-info.patch new file mode 100644 index 0000000..0af1255 --- /dev/null +++ b/0179-app-testpmd-show-link-flow-control-info.patch @@ -0,0 +1,144 @@ +From f67e3735b1020d516340b8a6ab2cf7c396dc9fac Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 21 Apr 2021 17:41:31 +0800 +Subject: [PATCH 179/189] app/testpmd: show link flow control info + +This patch supports the query of the link flow control parameter +on a port. + +The command format is as follows: +show port flow_ctrl + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +Acked-by: Xiaoyun Li +Acked-by: Kevin Traynor +--- + app/test-pmd/cmdline.c | 78 +++++++++++++++++++++++++++++ + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 +++ + 2 files changed, 85 insertions(+) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index 8832416..a64b493 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -254,6 +254,9 @@ static void cmd_help_long_parsed(void *parsed_result, + + "show port (port_id) fec_mode" + " Show fec mode of a port.\n\n" ++ ++ "show port (port_id) flow_ctrl" ++ " Show flow control info of a port.\n\n" + ); + } + +@@ -6935,6 +6938,80 @@ cmdline_parse_inst_t cmd_set_allmulti_mode_one = { + }, + }; + ++/* *** GET CURRENT ETHERNET LINK FLOW CONTROL *** */ ++struct cmd_link_flow_ctrl_show { ++ cmdline_fixed_string_t show; ++ cmdline_fixed_string_t port; ++ portid_t port_id; ++ cmdline_fixed_string_t flow_ctrl; ++}; ++ ++cmdline_parse_token_string_t cmd_lfc_show_show = ++ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_show, ++ show, "show"); ++cmdline_parse_token_string_t cmd_lfc_show_port = ++ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_show, ++ port, "port"); ++cmdline_parse_token_num_t cmd_lfc_show_portid = ++ TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_show, ++ port_id, RTE_UINT16); ++cmdline_parse_token_string_t cmd_lfc_show_flow_ctrl = ++ TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_show, ++ flow_ctrl, "flow_ctrl"); ++ ++static void ++cmd_link_flow_ctrl_show_parsed(void *parsed_result, ++ __rte_unused struct cmdline *cl, ++ __rte_unused void *data) ++{ ++ struct cmd_link_flow_ctrl_show *res = parsed_result; ++ static const char *info_border = "*********************"; ++ struct rte_eth_fc_conf fc_conf; ++ bool rx_fc_en = false; ++ bool tx_fc_en = false; ++ int ret; ++ ++ ret = rte_eth_dev_flow_ctrl_get(res->port_id, &fc_conf); ++ if (ret != 0) { ++ printf("Failed to get current flow ctrl information: err = %d\n", ++ ret); ++ return; ++ } ++ ++ if (fc_conf.mode == RTE_FC_RX_PAUSE || fc_conf.mode == RTE_FC_FULL) ++ rx_fc_en = true; ++ if (fc_conf.mode == RTE_FC_TX_PAUSE || fc_conf.mode == RTE_FC_FULL) ++ tx_fc_en = true; ++ ++ printf("\n%s Flow control infos for port %-2d %s\n", ++ info_border, res->port_id, info_border); ++ printf("FC mode:\n"); ++ printf(" Rx pause: %s\n", rx_fc_en ? "on" : "off"); ++ printf(" Tx pause: %s\n", tx_fc_en ? "on" : "off"); ++ printf("Autoneg: %s\n", fc_conf.autoneg ? "on" : "off"); ++ printf("Pause time: 0x%x\n", fc_conf.pause_time); ++ printf("High waterline: 0x%x\n", fc_conf.high_water); ++ printf("Low waterline: 0x%x\n", fc_conf.low_water); ++ printf("Send XON: %s\n", fc_conf.send_xon ? "on" : "off"); ++ printf("Forward MAC control frames: %s\n", ++ fc_conf.mac_ctrl_frame_fwd ? "on" : "off"); ++ printf("\n%s************** End ***********%s\n", ++ info_border, info_border); ++} ++ ++cmdline_parse_inst_t cmd_link_flow_control_show = { ++ .f = cmd_link_flow_ctrl_show_parsed, ++ .data = NULL, ++ .help_str = "show port flow_ctrl", ++ .tokens = { ++ (void *)&cmd_lfc_show_show, ++ (void *)&cmd_lfc_show_port, ++ (void *)&cmd_lfc_show_portid, ++ (void *)&cmd_lfc_show_flow_ctrl, ++ NULL, ++ }, ++}; ++ + /* *** SETUP ETHERNET LINK FLOW CONTROL *** */ + struct cmd_link_flow_ctrl_set_result { + cmdline_fixed_string_t set; +@@ -16981,6 +17058,7 @@ cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_link_flow_control_set_xon, + (cmdline_parse_inst_t *)&cmd_link_flow_control_set_macfwd, + (cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg, ++ (cmdline_parse_inst_t *)&cmd_link_flow_control_show, + (cmdline_parse_inst_t *)&cmd_priority_flow_control_set, + (cmdline_parse_inst_t *)&cmd_config_dcb, + (cmdline_parse_inst_t *)&cmd_read_reg, +diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst +index de90726..f0e0423 100644 +--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst ++++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst +@@ -1521,6 +1521,13 @@ Where: + + * ``autoneg``: Change the auto-negotiation parameter. + ++show flow control ++~~~~~~~~~~~~~~~~~ ++ ++show the link flow control parameter on a port:: ++ ++ testpmd> show port flow_ctrl ++ + set pfc_ctrl rx + ~~~~~~~~~~~~~~~ + +-- +2.7.4 + diff --git a/0180-app-testpmd-support-display-queue-state.patch b/0180-app-testpmd-support-display-queue-state.patch new file mode 100644 index 0000000..d49fd07 --- /dev/null +++ b/0180-app-testpmd-support-display-queue-state.patch @@ -0,0 +1,57 @@ +From c36dad2a8570ffadd1fd802c85d0566260ff1daf Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 21 Apr 2021 11:24:59 +0800 +Subject: [PATCH 180/189] app/testpmd: support display queue state + +This patch supports display queue state in "show rxq/txq" commands. + +Signed-off-by: Chengwen Feng +Signed-off-by: Min Hu (Connor) +Reviewed-by: Ferruh Yigit +--- + app/test-pmd/config.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index d4ec3ff..baae44e 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -362,6 +362,19 @@ nic_xstats_clear(portid_t port_id) + } + } + ++static const char * ++get_queue_state_name(uint8_t queue_state) ++{ ++ if (queue_state == RTE_ETH_QUEUE_STATE_STOPPED) ++ return "stopped"; ++ else if (queue_state == RTE_ETH_QUEUE_STATE_STARTED) ++ return "started"; ++ else if (queue_state == RTE_ETH_QUEUE_STATE_HAIRPIN) ++ return "hairpin"; ++ else ++ return "unknown"; ++} ++ + void + rx_queue_infos_display(portid_t port_id, uint16_t queue_id) + { +@@ -392,6 +405,7 @@ rx_queue_infos_display(portid_t port_id, uint16_t queue_id) + (qinfo.conf.rx_deferred_start != 0) ? "on" : "off"); + printf("\nRX scattered packets: %s", + (qinfo.scattered_rx != 0) ? "on" : "off"); ++ printf("\nRx queue state: %s", get_queue_state_name(qinfo.queue_state)); + if (qinfo.rx_buf_size != 0) + printf("\nRX buffer size: %hu", qinfo.rx_buf_size); + printf("\nNumber of RXDs: %hu", qinfo.nb_desc); +@@ -432,6 +446,7 @@ tx_queue_infos_display(portid_t port_id, uint16_t queue_id) + printf("\nTX deferred start: %s", + (qinfo.conf.tx_deferred_start != 0) ? "on" : "off"); + printf("\nNumber of TXDs: %hu", qinfo.nb_desc); ++ printf("\nTx queue state: %s", get_queue_state_name(qinfo.queue_state)); + + if (rte_eth_tx_burst_mode_get(port_id, queue_id, &mode) == 0) + printf("\nBurst mode: %s%s", +-- +2.7.4 + diff --git a/0181-app-testpmd-fix-max-queue-number-for-Tx-offloads.patch b/0181-app-testpmd-fix-max-queue-number-for-Tx-offloads.patch new file mode 100644 index 0000000..99db55c --- /dev/null +++ b/0181-app-testpmd-fix-max-queue-number-for-Tx-offloads.patch @@ -0,0 +1,34 @@ +From 91cdc3204aec2d95d138d8fd88a16ea9af123a5f Mon Sep 17 00:00:00 2001 +From: Chengchang Tang +Date: Thu, 22 Apr 2021 15:03:31 +0800 +Subject: [PATCH 181/189] app/testpmd: fix max queue number for Tx offloads + +When txq offload is configured, max rxq is used as the max queue. This +patch fixes it. + +Fixes: 74453ac9ef67 ("app/testpmd: fix queue offload configuration") +Cc: stable@dpdk.org + +Signed-off-by: Chengchang Tang +Signed-off-by: Min Hu (Connor) +Acked-by: Xiaoyun Li +--- + app/test-pmd/cmdline.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index a64b493..59c4f7e 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -4645,7 +4645,7 @@ cmd_config_queue_tx_offloads(struct rte_port *port) + int k; + + /* Apply queue tx offloads configuration */ +- for (k = 0; k < port->dev_info.max_rx_queues; k++) ++ for (k = 0; k < port->dev_info.max_tx_queues; k++) + port->tx_conf[k].offloads = + port->dev_conf.txmode.offloads; + } +-- +2.7.4 + diff --git a/0182-app-testpmd-fix-forward-lcores-number-for-DCB.patch b/0182-app-testpmd-fix-forward-lcores-number-for-DCB.patch new file mode 100644 index 0000000..5fabbb7 --- /dev/null +++ b/0182-app-testpmd-fix-forward-lcores-number-for-DCB.patch @@ -0,0 +1,70 @@ +From fd91f2f494b8dd91eda34ffa3d28b6e44d5988aa Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:40 +0800 +Subject: [PATCH 182/189] app/testpmd: fix forward lcores number for DCB + +For the DCB forwarding test, each core is assigned to each traffic class. +Number of forwarding cores for DCB test must be equal or less than number +of total TC. Otherwise, the following problems may occur: +1/ Redundant polling threads will be created when forwarding cores number + is greater than total TC number. +2/ Two cores would try to use a same queue on a port when Rx/Tx queue + number is greater than the used TC number, which is not allowed. + +Fixes: 900550de04a7 ("app/testpmd: add dcb support") +Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/config.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index baae44e..075929c 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -3154,6 +3154,21 @@ rss_fwd_config_setup(void) + } + } + ++static uint16_t ++get_fwd_port_total_tc_num(void) ++{ ++ struct rte_eth_dcb_info dcb_info; ++ uint16_t total_tc_num = 0; ++ unsigned int i; ++ ++ for (i = 0; i < nb_fwd_ports; i++) { ++ (void)rte_eth_dev_get_dcb_info(fwd_ports_ids[i], &dcb_info); ++ total_tc_num += dcb_info.nb_tcs; ++ } ++ ++ return total_tc_num; ++} ++ + /** + * For the DCB forwarding test, each core is assigned on each traffic class. + * +@@ -3173,12 +3188,16 @@ dcb_fwd_config_setup(void) + lcoreid_t lc_id; + uint16_t nb_rx_queue, nb_tx_queue; + uint16_t i, j, k, sm_id = 0; ++ uint16_t total_tc_num; + uint8_t tc = 0; + + cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; + cur_fwd_config.nb_fwd_ports = nb_fwd_ports; + cur_fwd_config.nb_fwd_streams = + (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports); ++ total_tc_num = get_fwd_port_total_tc_num(); ++ if (cur_fwd_config.nb_fwd_lcores > total_tc_num) ++ cur_fwd_config.nb_fwd_lcores = total_tc_num; + + /* reinitialize forwarding streams */ + init_fwd_streams(); +-- +2.7.4 + diff --git a/0183-app-testpmd-fix-DCB-forwarding-configuration.patch b/0183-app-testpmd-fix-DCB-forwarding-configuration.patch new file mode 100644 index 0000000..49b9a4c --- /dev/null +++ b/0183-app-testpmd-fix-DCB-forwarding-configuration.patch @@ -0,0 +1,113 @@ +From 670af503ac76c38183c532f3d6163a3a832f51d9 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:41 +0800 +Subject: [PATCH 183/189] app/testpmd: fix DCB forwarding configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After DCB mode is configured, the operations of port stop and port start +change the value of the global variable "dcb_test", As a result, the +forwarding configuration from DCB to RSS mode, namely, +“dcb_fwd_config_setup()” to "rss_fwd_config_setup()". + +Currently, the 'dcb_flag' field in struct 'rte_port' indicates whether +the port is configured with DCB. And it is sufficient to have +'dcb_config' as a global variable to control the DCB test status. So +this patch deletes the "dcb_test". + +In addition, setting 'dcb_config' at the end of init_port_dcb_config() +in case that ports fail to enter DCB mode. + +Fixes: 900550de04a7 ("app/testpmd: add dcb support") +Fixes: ce8d561418d4 ("app/testpmd: add port configuration settings") +Fixes: 7741e4cf16c0 ("app/testpmd: VMDq and DCB updates") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/testpmd.c | 18 ++++-------------- + app/test-pmd/testpmd.h | 1 - + 2 files changed, 4 insertions(+), 15 deletions(-) + +diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c +index 33a060d..e55d986 100644 +--- a/app/test-pmd/testpmd.c ++++ b/app/test-pmd/testpmd.c +@@ -245,9 +245,6 @@ uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ + /* current configuration is in DCB or not,0 means it is not in DCB mode */ + uint8_t dcb_config = 0; + +-/* Whether the dcb is in testing status */ +-uint8_t dcb_test = 0; +- + /* + * Configurable number of RX/TX queues. + */ +@@ -2141,8 +2138,7 @@ start_packet_forwarding(int with_tx_first) + return; + } + +- +- if(dcb_test) { ++ if (dcb_config) { + for (i = 0; i < nb_fwd_ports; i++) { + pt_id = fwd_ports_ids[i]; + port = &ports[pt_id]; +@@ -2450,8 +2446,6 @@ start_port(portid_t pid) + if (port_id_is_invalid(pid, ENABLED_WARN)) + return 0; + +- if(dcb_config) +- dcb_test = 1; + RTE_ETH_FOREACH_DEV(pi) { + if (pid != pi && pid != (portid_t)RTE_PORT_ALL) + continue; +@@ -2689,11 +2683,6 @@ stop_port(portid_t pid) + portid_t peer_pl[RTE_MAX_ETHPORTS]; + int peer_pi; + +- if (dcb_test) { +- dcb_test = 0; +- dcb_config = 0; +- } +- + if (port_id_is_invalid(pid, ENABLED_WARN)) + return; + +@@ -3519,8 +3508,6 @@ init_port_dcb_config(portid_t pid, + rte_port = &ports[pid]; + + memset(&port_conf, 0, sizeof(struct rte_eth_conf)); +- /* Enter DCB configuration status */ +- dcb_config = 1; + + port_conf.rxmode = rte_port->dev_conf.rxmode; + port_conf.txmode = rte_port->dev_conf.txmode; +@@ -3588,6 +3575,9 @@ init_port_dcb_config(portid_t pid, + + rte_port->dcb_flag = 1; + ++ /* Enter DCB configuration status */ ++ dcb_config = 1; ++ + return 0; + } + +diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h +index 5f23162..303bed8 100644 +--- a/app/test-pmd/testpmd.h ++++ b/app/test-pmd/testpmd.h +@@ -423,7 +423,6 @@ extern uint64_t noisy_lkup_num_reads; + extern uint64_t noisy_lkup_num_reads_writes; + + extern uint8_t dcb_config; +-extern uint8_t dcb_test; + + extern uint32_t mbuf_data_size_n; + extern uint16_t mbuf_data_size[MAX_SEGS_BUFFER_SPLIT]; +-- +2.7.4 + diff --git a/0184-app-testpmd-fix-DCB-re-configuration.patch b/0184-app-testpmd-fix-DCB-re-configuration.patch new file mode 100644 index 0000000..419a829 --- /dev/null +++ b/0184-app-testpmd-fix-DCB-re-configuration.patch @@ -0,0 +1,75 @@ +From 4a7456ce2099cd58f1408449520a9d66e6baa81c Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:42 +0800 +Subject: [PATCH 184/189] app/testpmd: fix DCB re-configuration + +After DCB mode is configured, if we decrease the number of RX and TX +queues, fwd_config_setup() will be called to setup the DCB forwarding +configuration. And forwarding streams are updated based on new queue +numbers in fwd_config_setup(), but the mapping between the TC and +queues obtained by rte_eth_dev_get_dcb_info() is still old queue +numbers (old queue numbers are greater than new queue numbers). +In this case, the segment fault happens. So rte_eth_dev_configure() +should be called again to update the mapping between the TC and +queues before rte_eth_dev_get_dcb_info(). + +Like: +set nbcore 4 +port stop all +port config 0 dcb vt off 4 pfc on +port start all +port stop all +port config all rxq 8 +port config all txq 8 + +Fixes: 900550de04a7 ("app/testpmd: add dcb support") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/config.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index 075929c..c3f9431 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -3189,7 +3189,33 @@ dcb_fwd_config_setup(void) + uint16_t nb_rx_queue, nb_tx_queue; + uint16_t i, j, k, sm_id = 0; + uint16_t total_tc_num; ++ struct rte_port *port; + uint8_t tc = 0; ++ portid_t pid; ++ int ret; ++ ++ /* ++ * The fwd_config_setup() is called when the port is RTE_PORT_STARTED ++ * or RTE_PORT_STOPPED. ++ * ++ * Re-configure ports to get updated mapping between tc and queue in ++ * case the queue number of the port is changed. Skip for started ports ++ * since modifying queue number and calling dev_configure need to stop ++ * ports first. ++ */ ++ for (pid = 0; pid < nb_fwd_ports; pid++) { ++ if (port_is_started(pid) == 1) ++ continue; ++ ++ port = &ports[pid]; ++ ret = rte_eth_dev_configure(pid, nb_rxq, nb_txq, ++ &port->dev_conf); ++ if (ret < 0) { ++ printf("Failed to re-configure port %d, ret = %d.\n", ++ pid, ret); ++ return; ++ } ++ } + + cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; + cur_fwd_config.nb_fwd_ports = nb_fwd_ports; +-- +2.7.4 + diff --git a/0185-app-testpmd-check-DCB-info-support-for-configuration.patch b/0185-app-testpmd-check-DCB-info-support-for-configuration.patch new file mode 100644 index 0000000..5e05e3e --- /dev/null +++ b/0185-app-testpmd-check-DCB-info-support-for-configuration.patch @@ -0,0 +1,48 @@ +From f53ebd40c6c205fc06fab74a0f9456551a8656c1 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:43 +0800 +Subject: [PATCH 185/189] app/testpmd: check DCB info support for configuration + +Currently, '.get_dcb_info' must be supported for the port doing DCB +test, or all information in 'rte_eth_dcb_info' are zero. It should be +prevented when user run cmd "port config 0 dcb vt off 4 pfc off". + +This patch adds the check for support of reporting dcb info. + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/cmdline.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index 59c4f7e..40a6871 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -3247,6 +3247,7 @@ cmd_config_dcb_parsed(void *parsed_result, + __rte_unused void *data) + { + struct cmd_config_dcb *res = parsed_result; ++ struct rte_eth_dcb_info dcb_info; + portid_t port_id = res->port_id; + struct rte_port *port; + uint8_t pfc_en; +@@ -3269,6 +3270,14 @@ cmd_config_dcb_parsed(void *parsed_result, + printf("nb_cores shouldn't be less than number of TCs.\n"); + return; + } ++ ++ /* Check whether the port supports the report of DCB info. */ ++ ret = rte_eth_dev_get_dcb_info(port_id, &dcb_info); ++ if (ret == -ENOTSUP) { ++ printf("rte_eth_dev_get_dcb_info not supported.\n"); ++ return; ++ } ++ + if (!strncmp(res->pfc_en, "on", 2)) + pfc_en = 1; + else +-- +2.7.4 + diff --git a/0186-app-testpmd-verify-DCB-config-during-forward-config.patch b/0186-app-testpmd-verify-DCB-config-during-forward-config.patch new file mode 100644 index 0000000..fe08a1a --- /dev/null +++ b/0186-app-testpmd-verify-DCB-config-during-forward-config.patch @@ -0,0 +1,107 @@ +From 118f18c9ab370a30a25ef548d1dee2b125bcfc16 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:44 +0800 +Subject: [PATCH 186/189] app/testpmd: verify DCB config during forward config + +Currently, the check for doing DCB test is assigned to +start_packet_forwarding(), which will be called when +run "start" cmd. But fwd_config_setup() is used in many +scenarios, such as, "port config all rxq". + +This patch moves the check from start_packet_forwarding() +to fwd_config_setup(). + +Fixes: 7741e4cf16c0 ("app/testpmd: VMDq and DCB updates") +Cc: stable@dpdk.org + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/config.c | 23 +++++++++++++++++++++-- + app/test-pmd/testpmd.c | 19 ------------------- + 2 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c +index c3f9431..7af13f6 100644 +--- a/app/test-pmd/config.c ++++ b/app/test-pmd/config.c +@@ -3345,6 +3345,10 @@ icmp_echo_config_setup(void) + void + fwd_config_setup(void) + { ++ struct rte_port *port; ++ portid_t pt_id; ++ unsigned int i; ++ + cur_fwd_config.fwd_eng = cur_fwd_eng; + if (strcmp(cur_fwd_eng->fwd_mode_name, "icmpecho") == 0) { + icmp_echo_config_setup(); +@@ -3352,9 +3356,24 @@ fwd_config_setup(void) + } + + if ((nb_rxq > 1) && (nb_txq > 1)){ +- if (dcb_config) ++ if (dcb_config) { ++ for (i = 0; i < nb_fwd_ports; i++) { ++ pt_id = fwd_ports_ids[i]; ++ port = &ports[pt_id]; ++ if (!port->dcb_flag) { ++ printf("In DCB mode, all forwarding ports must " ++ "be configured in this mode.\n"); ++ return; ++ } ++ } ++ if (nb_fwd_lcores == 1) { ++ printf("In DCB mode,the nb forwarding cores " ++ "should be larger than 1.\n"); ++ return; ++ } ++ + dcb_fwd_config_setup(); +- else ++ } else + rss_fwd_config_setup(); + } + else +diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c +index e55d986..f9155ae 100644 +--- a/app/test-pmd/testpmd.c ++++ b/app/test-pmd/testpmd.c +@@ -2112,9 +2112,7 @@ start_packet_forwarding(int with_tx_first) + { + port_fwd_begin_t port_fwd_begin; + port_fwd_end_t port_fwd_end; +- struct rte_port *port; + unsigned int i; +- portid_t pt_id; + + if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq) + rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n"); +@@ -2137,23 +2135,6 @@ start_packet_forwarding(int with_tx_first) + printf("Packet forwarding already started\n"); + return; + } +- +- if (dcb_config) { +- for (i = 0; i < nb_fwd_ports; i++) { +- pt_id = fwd_ports_ids[i]; +- port = &ports[pt_id]; +- if (!port->dcb_flag) { +- printf("In DCB mode, all forwarding ports must " +- "be configured in this mode.\n"); +- return; +- } +- } +- if (nb_fwd_lcores == 1) { +- printf("In DCB mode,the nb forwarding cores " +- "should be larger than 1.\n"); +- return; +- } +- } + test_done = 0; + + fwd_config_setup(); +-- +2.7.4 + diff --git a/0187-app-testpmd-add-forwarding-configuration-to-DCB-conf.patch b/0187-app-testpmd-add-forwarding-configuration-to-DCB-conf.patch new file mode 100644 index 0000000..9c3b3fd --- /dev/null +++ b/0187-app-testpmd-add-forwarding-configuration-to-DCB-conf.patch @@ -0,0 +1,40 @@ +From b7e79c9c712372946ccd9ce66bd3d1b91cd0a9d1 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:45 +0800 +Subject: [PATCH 187/189] app/testpmd: add forwarding configuration to DCB + config + +This patch adds fwd_config_setup() at the end of cmd_config_dcb_parsed() +to update "cur_fwd_config", so that the actual forwarding streams can be +queried by the "show config fwd" cmd. + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/cmdline.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c +index 40a6871..78db462 100644 +--- a/app/test-pmd/cmdline.c ++++ b/app/test-pmd/cmdline.c +@@ -3292,13 +3292,13 @@ cmd_config_dcb_parsed(void *parsed_result, + ret = init_port_dcb_config(port_id, DCB_ENABLED, + (enum rte_eth_nb_tcs)res->num_tcs, + pfc_en); +- +- + if (ret != 0) { + printf("Cannot initialize network ports.\n"); + return; + } + ++ fwd_config_setup(); ++ + cmd_reconfig_device_queue(port_id, 1, 1); + } + +-- +2.7.4 + diff --git a/0188-app-testpmd-remove-redundant-forwarding-initializati.patch b/0188-app-testpmd-remove-redundant-forwarding-initializati.patch new file mode 100644 index 0000000..640ad6b --- /dev/null +++ b/0188-app-testpmd-remove-redundant-forwarding-initializati.patch @@ -0,0 +1,35 @@ +From 998201309e193b7203ad6418c184993e0f61fc28 Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Wed, 28 Apr 2021 14:40:46 +0800 +Subject: [PATCH 188/189] app/testpmd: remove redundant forwarding + initialization + +The fwd_config_setup() is called after init_fwd_streams(). +The fwd_config_setup() will reinitialize forwarding streams. +This patch removes init_fwd_streams() from init_config(). + +Signed-off-by: Huisong Li +Signed-off-by: Lijun Ou +Acked-by: Xiaoyun Li +--- + app/test-pmd/testpmd.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c +index f9155ae..3098df6 100644 +--- a/app/test-pmd/testpmd.c ++++ b/app/test-pmd/testpmd.c +@@ -1559,10 +1559,6 @@ init_config(void) + fwd_lcores[lc_id]->gso_ctx.flag = 0; + } + +- /* Configuration of packet forwarding streams. */ +- if (init_fwd_streams() < 0) +- rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); +- + fwd_config_setup(); + + /* create a gro context for each lcore */ +-- +2.7.4 + diff --git a/0189-net-fix-compiling-bug-for-20.11-merge.patch b/0189-net-fix-compiling-bug-for-20.11-merge.patch new file mode 100644 index 0000000..d857b83 --- /dev/null +++ b/0189-net-fix-compiling-bug-for-20.11-merge.patch @@ -0,0 +1,28 @@ +From 2fa098fa0c4986f77f00521bc7ef50948397a6ef Mon Sep 17 00:00:00 2001 +From: "Min Hu (Connor)" +Date: Thu, 10 Jun 2021 15:21:07 +0800 +Subject: [PATCH 189/189] net: fix compiling bug for 20.11 merge + +This patch add byte order support for definition. + +Signed-off-by: Min Hu (Connor) +--- + lib/librte_net/rte_geneve.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/librte_net/rte_geneve.h b/lib/librte_net/rte_geneve.h +index bb67724..3bbc561 100644 +--- a/lib/librte_net/rte_geneve.h ++++ b/lib/librte_net/rte_geneve.h +@@ -12,6 +12,8 @@ + */ + #include + ++#include ++ + #ifdef __cplusplus + extern "C" { + #endif +-- +2.7.4 + diff --git a/CVE-2020-10722.patch b/CVE-2020-10722.patch deleted file mode 100644 index 15c19d9..0000000 --- a/CVE-2020-10722.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 2cf9c470ebff0091e41af85f16ab906fd98cf9af Mon Sep 17 00:00:00 2001 -From: Maxime Coquelin -Date: Tue, 21 Apr 2020 11:16:56 +0200 -Subject: vhost: check log mmap offset and size overflow - -vhost_user_set_log_base() is a message handler that is -called to handle the VHOST_USER_SET_LOG_BASE message. -Its payload contains a 64 bit size and offset. Both are -added up and used as a size when calling mmap(). - -There is no integer overflow check. If an integer overflow -occurs a smaller memory map would be created than -requested. Since the returned mapping is mapped as writable -and used for logging, a memory corruption could occur. - -Fixes: fbc4d248b198 ("vhost: fix offset while mmaping log base address") - -This issue has been assigned CVE-2020-10722 - -Reported-by: Ilja Van Sprundel -Signed-off-by: Maxime Coquelin -Reviewed-by: Xiaolong Ye -Reviewed-by: Ilja Van Sprundel ---- - lib/librte_vhost/vhost_user.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c -index 40c4520..02962fc 100644 ---- a/lib/librte_vhost/vhost_user.c -+++ b/lib/librte_vhost/vhost_user.c -@@ -2060,10 +2060,10 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg, - size = msg->payload.log.mmap_size; - off = msg->payload.log.mmap_offset; - -- /* Don't allow mmap_offset to point outside the mmap region */ -- if (off > size) { -+ /* Check for mmap size and offset overflow. */ -+ if (off >= -size) { - RTE_LOG(ERR, VHOST_CONFIG, -- "log offset %#"PRIx64" exceeds log size %#"PRIx64"\n", -+ "log offset %#"PRIx64" and log size %#"PRIx64" overflow\n", - off, size); - return RTE_VHOST_MSG_RESULT_ERR; - } --- -cgit v1.0 - diff --git a/CVE-2020-10723.patch b/CVE-2020-10723.patch deleted file mode 100644 index 045a330..0000000 --- a/CVE-2020-10723.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 8e9652b0b616a3704b5cb5a3dccb2c239e16ab9c Mon Sep 17 00:00:00 2001 -From: Maxime Coquelin -Date: Tue, 21 Apr 2020 18:17:43 +0200 -Subject: vhost: fix vring index check - -vhost_user_check_and_alloc_queue_pair() is used to extract -a vring index from a payload. This function validates the -index and is called early on in when performing message -handling. Most message handlers depend on it correctly -validating the vring index. - -Depending on the message type the vring index is in -different parts of the payload. The function contains a -switch/case for each type and copies the index. This is -stored in a uint16. This index is then validated. Depending -on the message, the source index is an unsigned int. If -integer truncation occurs (uint->uint16) the top 16 bits -of the index are never validated. - -When they are used later on (e.g. in -vhost_user_set_vring_num() or vhost_user_set_vring_addr()) -it can lead to out of bound indexing. The out of bound -indexed data gets written to, and hence this can cause -memory corruption. - -This patch fixes this vulnerability by declaring vring -index as an unsigned int in -vhost_user_check_and_alloc_queue_pair(). - -Fixes: 160cbc815b41 ("vhost: remove a hack on queue allocation") - -This issue has been assigned CVE-2020-10723 - -Reported-by: Ilja Van Sprundel -Signed-off-by: Maxime Coquelin -Reviewed-by: Xiaolong Ye -Reviewed-by: Ilja Van Sprundel ---- - lib/librte_vhost/vhost_user.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c -index 02962fc..d196142 100644 ---- a/lib/librte_vhost/vhost_user.c -+++ b/lib/librte_vhost/vhost_user.c -@@ -2508,7 +2508,7 @@ static int - vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, - struct VhostUserMsg *msg) - { -- uint16_t vring_idx; -+ uint32_t vring_idx; - - switch (msg->request.master) { - case VHOST_USER_SET_VRING_KICK: --- -cgit v1.0 - diff --git a/CVE-2020-10724.patch b/CVE-2020-10724.patch deleted file mode 100644 index 729d4db..0000000 --- a/CVE-2020-10724.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 963b6eea05f3ee720fcfecd110e20f61b92205d6 Mon Sep 17 00:00:00 2001 -From: Maxime Coquelin -Date: Tue, 21 Apr 2020 19:10:09 +0200 -Subject: vhost/crypto: validate keys lengths - -transform_cipher_param() and transform_chain_param() handle -the payload data for the VHOST_USER_CRYPTO_CREATE_SESS -message. These payloads have to be validated, since it -could come from untrusted sources. - -Two buffers and their lenghts are defined in this payload, -one the the auth key and one for the cipher key. But above -functions do not validate the key length inputs, which could -lead to read out of bounds, as buffers have static sizes of -64 bytes for the cipher key and 512 bytes for the auth key. - -This patch adds necessary checks on the key length field -before being used. - -Fixes: e80a98708166 ("vhost/crypto: add session message handler") - -This issue has been assigned CVE-2020-10724 - -Reported-by: Ilja Van Sprundel -Signed-off-by: Maxime Coquelin -Reviewed-by: Xiaolong Ye -Reviewed-by: Ilja Van Sprundel ---- - lib/librte_vhost/vhost_crypto.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c -index 6891197..07a4115 100644 ---- a/lib/librte_vhost/vhost_crypto.c -+++ b/lib/librte_vhost/vhost_crypto.c -@@ -237,6 +237,11 @@ transform_cipher_param(struct rte_crypto_sym_xform *xform, - if (unlikely(ret < 0)) - return ret; - -+ if (param->cipher_key_len > VHOST_USER_CRYPTO_MAX_CIPHER_KEY_LENGTH) { -+ VC_LOG_DBG("Invalid cipher key length\n"); -+ return -VIRTIO_CRYPTO_BADMSG; -+ } -+ - xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - xform->cipher.key.length = param->cipher_key_len; - if (xform->cipher.key.length > 0) -@@ -287,6 +292,12 @@ transform_chain_param(struct rte_crypto_sym_xform *xforms, - &xform_cipher->cipher.algo); - if (unlikely(ret < 0)) - return ret; -+ -+ if (param->cipher_key_len > VHOST_USER_CRYPTO_MAX_CIPHER_KEY_LENGTH) { -+ VC_LOG_DBG("Invalid cipher key length\n"); -+ return -VIRTIO_CRYPTO_BADMSG; -+ } -+ - xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - xform_cipher->cipher.key.length = param->cipher_key_len; - xform_cipher->cipher.key.data = param->cipher_key_buf; -@@ -301,6 +312,12 @@ transform_chain_param(struct rte_crypto_sym_xform *xforms, - ret = auth_algo_transform(param->hash_algo, &xform_auth->auth.algo); - if (unlikely(ret < 0)) - return ret; -+ -+ if (param->auth_key_len > VHOST_USER_CRYPTO_MAX_HMAC_KEY_LENGTH) { -+ VC_LOG_DBG("Invalid auth key length\n"); -+ return -VIRTIO_CRYPTO_BADMSG; -+ } -+ - xform_auth->auth.digest_length = param->digest_len; - xform_auth->auth.key.length = param->auth_key_len; - xform_auth->auth.key.data = param->auth_key_buf; --- -cgit v1.0 - diff --git a/CVE-2020-10725.patch b/CVE-2020-10725.patch deleted file mode 100644 index a6eba33..0000000 --- a/CVE-2020-10725.patch +++ /dev/null @@ -1,44 +0,0 @@ -From cd0ea71bb6a7d1c503bf2f6f1e3c455cf246d9a1 Mon Sep 17 00:00:00 2001 -From: Marvin Liu -Date: Wed, 8 Apr 2020 17:13:55 +0800 -Subject: vhost: fix translated address not checked - -Malicious guest can construct desc with invalid address and zero buffer -length. That will request vhost to check both translated address and -translated data length. This patch will add missed address check. - -Fixes: 75ed51697820 ("vhost: add packed ring batch dequeue") -Fixes: ef861692c398 ("vhost: add packed ring batch enqueue") - -This issue has been assigned CVE-2020-10725 - -Signed-off-by: Marvin Liu -Reviewed-by: Maxime Coquelin ---- - lib/librte_vhost/virtio_net.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c -index ac2842b..33f1025 100644 ---- a/lib/librte_vhost/virtio_net.c -+++ b/lib/librte_vhost/virtio_net.c -@@ -1086,6 +1086,8 @@ virtio_dev_rx_batch_packed(struct virtio_net *dev, - VHOST_ACCESS_RW); - - vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { -+ if (unlikely(!desc_addrs[i])) -+ return -1; - if (unlikely(lens[i] != descs[avail_idx + i].len)) - return -1; - } -@@ -1841,6 +1843,8 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, - } - - vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { -+ if (unlikely(!desc_addrs[i])) -+ return -1; - if (unlikely((lens[i] != descs[avail_idx + i].len))) - return -1; - } --- -cgit v1.0 \ No newline at end of file diff --git a/CVE-2020-10726.patch b/CVE-2020-10726.patch deleted file mode 100644 index 853ef90..0000000 --- a/CVE-2020-10726.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 95e1f29c26777ee36456e340ed9c2b07472add28 Mon Sep 17 00:00:00 2001 -From: Xiaolong Ye -Date: Wed, 8 Apr 2020 15:31:35 +0800 -Subject: vhost: fix potential memory space leak - -A malicious container which has direct access to the vhost-user socket -can keep sending VHOST_USER_GET_INFLIGHT_FD messages which may cause -leaking resources until resulting a DOS. Fix it by unmapping the -dev->inflight_info->addr before assigning new mapped addr to it. - -Fixes: d87f1a1cb7b6 ("vhost: support inflight info sharing") - -This issue has been assigned CVE-2020-10726 - -Signed-off-by: Xiaolong Ye -Reviewed-by: Maxime Coquelin ---- - lib/librte_vhost/vhost_user.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c -index d196142..2a4ba20 100644 ---- a/lib/librte_vhost/vhost_user.c -+++ b/lib/librte_vhost/vhost_user.c -@@ -1440,6 +1440,11 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, - } - memset(addr, 0, mmap_size); - -+ if (dev->inflight_info->addr) { -+ munmap(dev->inflight_info->addr, dev->inflight_info->size); -+ dev->inflight_info->addr = NULL; -+ } -+ - dev->inflight_info->addr = addr; - dev->inflight_info->size = msg->payload.inflight.mmap_size = mmap_size; - dev->inflight_info->fd = msg->fds[0] = fd; -@@ -1524,8 +1529,10 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, - } - } - -- if (dev->inflight_info->addr) -+ if (dev->inflight_info->addr) { - munmap(dev->inflight_info->addr, dev->inflight_info->size); -+ dev->inflight_info->addr = NULL; -+ } - - addr = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, mmap_offset); --- -cgit v1.0 - diff --git a/CVE-2020-14374.patch b/CVE-2020-14374.patch deleted file mode 100644 index 14bc0d9..0000000 --- a/CVE-2020-14374.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 6a3a414698e45cf01bb1489ef81f4d663a88047b Mon Sep 17 00:00:00 2001 -From: Fan Zhang -Date: Thu, 16 Apr 2020 11:29:06 +0100 -Subject: vhost/crypto: fix data length check - -This patch fixes the incorrect data length check to vhost crypto. -Instead of blindly accepting the descriptor length as data length, the -change compare the request provided data length and descriptor length -first. The security issue CVE-2020-14374 is not fixed alone by this -patch, part of the fix is done through: -"vhost/crypto: fix missed request check for copy mode". - -CVE-2020-14374 -Fixes: 3c79609fda7c ("vhost/crypto: handle virtually non-contiguous buffers") -Cc: stable@dpdk.org - -Signed-off-by: Fan Zhang -Acked-by: Chenbo Xia - -reference:https://git.dpdk.org/dpdk-stable/commit/?h=19.11&id=6a3a414698e4 -Signed-off-by: gaoxingwang ---- - lib/librte_vhost/vhost_crypto.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c -index f1cc32a..cf9aa25 100644 ---- a/lib/librte_vhost/vhost_crypto.c -+++ b/lib/librte_vhost/vhost_crypto.c -@@ -624,7 +624,7 @@ copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, - desc = &vc_req->head[desc->next]; - rte_prefetch0(&vc_req->head[desc->next]); - to_copy = RTE_MIN(desc->len, (uint32_t)left); -- dlen = desc->len; -+ dlen = to_copy; - src = IOVA_TO_VVA(uint8_t *, vc_req, desc->addr, &dlen, - VHOST_ACCESS_RO); - if (unlikely(!src || !dlen)) { --- -cgit v1.0 diff --git a/CVE-2020-14375.patch b/CVE-2020-14375.patch deleted file mode 100644 index 02afbfa..0000000 --- a/CVE-2020-14375.patch +++ /dev/null @@ -1,803 +0,0 @@ -From e2666ec24535c7ba0fb325d61a753bcabc8bf1ae Mon Sep 17 00:00:00 2001 -From: Fan Zhang -Date: Wed, 9 Sep 2020 09:35:53 +0100 -Subject: vhost/crypto: fix possible TOCTOU attack - -This patch fixes the possible time-of-check to time-of-use (TOCTOU) -attack problem by copying request data and descriptor index to local -variable prior to process. - -Also the original sequential read of descriptors may lead to TOCTOU -attack. This patch fixes the problem by loading all descriptors of a -request to local buffer before processing. - -CVE-2020-14375 -Fixes: 3bb595ecd682 ("vhost/crypto: add request handler") -Cc: stable@dpdk.org - -Signed-off-by: Fan Zhang -Acked-by: Chenbo Xia - -reference:https://git.dpdk.org/dpdk-stable/commit/?h=19.11&id=e2666ec24535 -Signed-off-by: gaoxingwang ---- - lib/librte_vhost/rte_vhost_crypto.h | 2 + - lib/librte_vhost/vhost_crypto.c | 391 ++++++++++++++++++------------------ - 2 files changed, 202 insertions(+), 191 deletions(-) - -diff --git a/lib/librte_vhost/rte_vhost_crypto.h b/lib/librte_vhost/rte_vhost_crypto.h -index 866a592..b54d61d 100644 ---- a/lib/librte_vhost/rte_vhost_crypto.h -+++ b/lib/librte_vhost/rte_vhost_crypto.h -@@ -7,10 +7,12 @@ - - #define VHOST_CRYPTO_MBUF_POOL_SIZE (8192) - #define VHOST_CRYPTO_MAX_BURST_SIZE (64) -+#define VHOST_CRYPTO_MAX_DATA_SIZE (4096) - #define VHOST_CRYPTO_SESSION_MAP_ENTRIES (1024) /**< Max nb sessions */ - /** max nb virtual queues in a burst for finalizing*/ - #define VIRTIO_CRYPTO_MAX_NUM_BURST_VQS (64) - #define VHOST_CRYPTO_MAX_IV_LEN (32) -+#define VHOST_CRYPTO_MAX_N_DESC (32) - - enum rte_vhost_crypto_zero_copy { - RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE = 0, -diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c -index cf9aa25..e08f9c6 100644 ---- a/lib/librte_vhost/vhost_crypto.c -+++ b/lib/librte_vhost/vhost_crypto.c -@@ -46,6 +46,14 @@ - #define IOVA_TO_VVA(t, r, a, l, p) \ - ((t)(uintptr_t)vhost_iova_to_vva(r->dev, r->vq, a, l, p)) - -+/* -+ * vhost_crypto_desc is used to copy original vring_desc to the local buffer -+ * before processing (except the next index). The copy result will be an -+ * array of vhost_crypto_desc elements that follows the sequence of original -+ * vring_desc.next is arranged. -+ */ -+#define vhost_crypto_desc vring_desc -+ - static int - cipher_algo_transform(uint32_t virtio_cipher_algo, - enum rte_crypto_cipher_algorithm *algo) -@@ -479,83 +487,71 @@ vhost_crypto_msg_post_handler(int vid, void *msg) - return ret; - } - --static __rte_always_inline struct vring_desc * --find_write_desc(struct vring_desc *head, struct vring_desc *desc, -- uint32_t *nb_descs, uint32_t vq_size) -+static __rte_always_inline struct vhost_crypto_desc * -+find_write_desc(struct vhost_crypto_desc *head, struct vhost_crypto_desc *desc, -+ uint32_t max_n_descs) - { -- if (desc->flags & VRING_DESC_F_WRITE) -- return desc; -- -- while (desc->flags & VRING_DESC_F_NEXT) { -- if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) -- return NULL; -- (*nb_descs)--; -+ if (desc < head) -+ return NULL; - -- desc = &head[desc->next]; -+ while (desc - head < (int)max_n_descs) { - if (desc->flags & VRING_DESC_F_WRITE) - return desc; -+ desc++; - } - - return NULL; - } - --static struct virtio_crypto_inhdr * --reach_inhdr(struct vhost_crypto_data_req *vc_req, struct vring_desc *desc, -- uint32_t *nb_descs, uint32_t vq_size) -+static __rte_always_inline struct virtio_crypto_inhdr * -+reach_inhdr(struct vhost_crypto_data_req *vc_req, -+ struct vhost_crypto_desc *head, -+ uint32_t max_n_descs) - { -- uint64_t dlen; - struct virtio_crypto_inhdr *inhdr; -+ struct vhost_crypto_desc *last = head + (max_n_descs - 1); -+ uint64_t dlen = last->len; - -- while (desc->flags & VRING_DESC_F_NEXT) { -- if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) -- return NULL; -- (*nb_descs)--; -- desc = &vc_req->head[desc->next]; -- } -+ if (unlikely(dlen != sizeof(*inhdr))) -+ return NULL; - -- dlen = desc->len; -- inhdr = IOVA_TO_VVA(struct virtio_crypto_inhdr *, vc_req, desc->addr, -+ inhdr = IOVA_TO_VVA(struct virtio_crypto_inhdr *, vc_req, last->addr, - &dlen, VHOST_ACCESS_WO); -- if (unlikely(!inhdr || dlen != desc->len)) -+ if (unlikely(!inhdr || dlen != last->len)) - return NULL; - - return inhdr; - } - - static __rte_always_inline int --move_desc(struct vring_desc *head, struct vring_desc **cur_desc, -- uint32_t size, uint32_t *nb_descs, uint32_t vq_size) -+move_desc(struct vhost_crypto_desc *head, -+ struct vhost_crypto_desc **cur_desc, -+ uint32_t size, uint32_t max_n_descs) - { -- struct vring_desc *desc = *cur_desc; -+ struct vhost_crypto_desc *desc = *cur_desc; - int left = size - desc->len; - -- while ((desc->flags & VRING_DESC_F_NEXT) && left > 0) { -- if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) -- return -1; -- -- desc = &head[desc->next]; -- rte_prefetch0(&head[desc->next]); -+ while (desc->flags & VRING_DESC_F_NEXT && left > 0 && -+ desc >= head && -+ desc - head < (int)max_n_descs) { -+ desc++; - left -= desc->len; -- if (left > 0) -- (*nb_descs)--; - } - - if (unlikely(left > 0)) - return -1; - -- if (unlikely(*nb_descs == 0)) -+ if (unlikely(head - desc == (int)max_n_descs)) - *cur_desc = NULL; -- else { -- if (unlikely(desc->next >= vq_size)) -- return -1; -- *cur_desc = &head[desc->next]; -- } -+ else -+ *cur_desc = desc + 1; - - return 0; - } - - static __rte_always_inline void * --get_data_ptr(struct vhost_crypto_data_req *vc_req, struct vring_desc *cur_desc, -+get_data_ptr(struct vhost_crypto_data_req *vc_req, -+ struct vhost_crypto_desc *cur_desc, - uint8_t perm) - { - void *data; -@@ -570,12 +566,13 @@ get_data_ptr(struct vhost_crypto_data_req *vc_req, struct vring_desc *cur_desc, - return data; - } - --static int -+static __rte_always_inline int - copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, -- struct vring_desc **cur_desc, uint32_t size, -- uint32_t *nb_descs, uint32_t vq_size) -+ struct vhost_crypto_desc *head, -+ struct vhost_crypto_desc **cur_desc, -+ uint32_t size, uint32_t max_n_descs) - { -- struct vring_desc *desc = *cur_desc; -+ struct vhost_crypto_desc *desc = *cur_desc; - uint64_t remain, addr, dlen, len; - uint32_t to_copy; - uint8_t *data = dst_data; -@@ -614,15 +611,8 @@ copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, - - left -= to_copy; - -- while ((desc->flags & VRING_DESC_F_NEXT) && left > 0) { -- if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) { -- VC_LOG_ERR("Invalid descriptors"); -- return -1; -- } -- (*nb_descs)--; -- -- desc = &vc_req->head[desc->next]; -- rte_prefetch0(&vc_req->head[desc->next]); -+ while (desc >= head && desc - head < (int)max_n_descs && left) { -+ desc++; - to_copy = RTE_MIN(desc->len, (uint32_t)left); - dlen = to_copy; - src = IOVA_TO_VVA(uint8_t *, vc_req, desc->addr, &dlen, -@@ -663,13 +653,10 @@ copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, - return -1; - } - -- if (unlikely(*nb_descs == 0)) -+ if (unlikely(desc - head == (int)max_n_descs)) - *cur_desc = NULL; -- else { -- if (unlikely(desc->next >= vq_size)) -- return -1; -- *cur_desc = &vc_req->head[desc->next]; -- } -+ else -+ *cur_desc = desc + 1; - - return 0; - } -@@ -681,6 +668,7 @@ write_back_data(struct vhost_crypto_data_req *vc_req) - - while (wb_data) { - rte_memcpy(wb_data->dst, wb_data->src, wb_data->len); -+ memset(wb_data->src, 0, wb_data->len); - wb_last = wb_data; - wb_data = wb_data->next; - rte_mempool_put(vc_req->wb_pool, wb_last); -@@ -722,17 +710,18 @@ free_wb_data(struct vhost_crypto_writeback_data *wb_data, - * @return - * The pointer to the start of the write back data linked list. - */ --static struct vhost_crypto_writeback_data * -+static __rte_always_inline struct vhost_crypto_writeback_data * - prepare_write_back_data(struct vhost_crypto_data_req *vc_req, -- struct vring_desc **cur_desc, -+ struct vhost_crypto_desc *head_desc, -+ struct vhost_crypto_desc **cur_desc, - struct vhost_crypto_writeback_data **end_wb_data, - uint8_t *src, - uint32_t offset, - uint64_t write_back_len, -- uint32_t *nb_descs, uint32_t vq_size) -+ uint32_t max_n_descs) - { - struct vhost_crypto_writeback_data *wb_data, *head; -- struct vring_desc *desc = *cur_desc; -+ struct vhost_crypto_desc *desc = *cur_desc; - uint64_t dlen; - uint8_t *dst; - int ret; -@@ -775,14 +764,10 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, - } else - offset -= desc->len; - -- while (write_back_len) { -- if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) { -- VC_LOG_ERR("Invalid descriptors"); -- goto error_exit; -- } -- (*nb_descs)--; -- -- desc = &vc_req->head[desc->next]; -+ while (write_back_len && -+ desc >= head_desc && -+ desc - head_desc < (int)max_n_descs) { -+ desc++; - if (unlikely(!(desc->flags & VRING_DESC_F_WRITE))) { - VC_LOG_ERR("incorrect descriptor"); - goto error_exit; -@@ -821,13 +806,10 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, - wb_data->next = NULL; - } - -- if (unlikely(*nb_descs == 0)) -+ if (unlikely(desc - head_desc == (int)max_n_descs)) - *cur_desc = NULL; -- else { -- if (unlikely(desc->next >= vq_size)) -- goto error_exit; -- *cur_desc = &vc_req->head[desc->next]; -- } -+ else -+ *cur_desc = desc + 1; - - *end_wb_data = wb_data; - -@@ -851,14 +833,14 @@ vhost_crypto_check_cipher_request(struct virtio_crypto_cipher_data_req *req) - return VIRTIO_CRYPTO_BADMSG; - } - --static uint8_t -+static __rte_always_inline uint8_t - prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - struct vhost_crypto_data_req *vc_req, - struct virtio_crypto_cipher_data_req *cipher, -- struct vring_desc *cur_desc, -- uint32_t *nb_descs, uint32_t vq_size) -+ struct vhost_crypto_desc *head, -+ uint32_t max_n_descs) - { -- struct vring_desc *desc = cur_desc; -+ struct vhost_crypto_desc *desc = head; - struct vhost_crypto_writeback_data *ewb = NULL; - struct rte_mbuf *m_src = op->sym->m_src, *m_dst = op->sym->m_dst; - uint8_t *iv_data = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET); -@@ -869,8 +851,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - - /* prepare */ - /* iv */ -- if (unlikely(copy_data(iv_data, vc_req, &desc, cipher->para.iv_len, -- nb_descs, vq_size) < 0)) { -+ if (unlikely(copy_data(iv_data, vc_req, head, &desc, -+ cipher->para.iv_len, max_n_descs))) { - ret = VIRTIO_CRYPTO_BADMSG; - goto error_exit; - } -@@ -888,9 +870,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - goto error_exit; - } - -- if (unlikely(move_desc(vc_req->head, &desc, -- cipher->para.src_data_len, nb_descs, -- vq_size) < 0)) { -+ if (unlikely(move_desc(head, &desc, cipher->para.src_data_len, -+ max_n_descs) < 0)) { - VC_LOG_ERR("Incorrect descriptor"); - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; -@@ -901,8 +882,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - vc_req->wb_pool = vcrypto->wb_pool; - m_src->data_len = cipher->para.src_data_len; - if (unlikely(copy_data(rte_pktmbuf_mtod(m_src, uint8_t *), -- vc_req, &desc, cipher->para.src_data_len, -- nb_descs, vq_size) < 0)) { -+ vc_req, head, &desc, cipher->para.src_data_len, -+ max_n_descs) < 0)) { - ret = VIRTIO_CRYPTO_BADMSG; - goto error_exit; - } -@@ -913,7 +894,7 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - } - - /* dst */ -- desc = find_write_desc(vc_req->head, desc, nb_descs, vq_size); -+ desc = find_write_desc(head, desc, max_n_descs); - if (unlikely(!desc)) { - VC_LOG_ERR("Cannot find write location"); - ret = VIRTIO_CRYPTO_BADMSG; -@@ -931,9 +912,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - goto error_exit; - } - -- if (unlikely(move_desc(vc_req->head, &desc, -- cipher->para.dst_data_len, -- nb_descs, vq_size) < 0)) { -+ if (unlikely(move_desc(head, &desc, cipher->para.dst_data_len, -+ max_n_descs) < 0)) { - VC_LOG_ERR("Incorrect descriptor"); - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; -@@ -942,9 +922,9 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - m_dst->data_len = cipher->para.dst_data_len; - break; - case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: -- vc_req->wb = prepare_write_back_data(vc_req, &desc, &ewb, -+ vc_req->wb = prepare_write_back_data(vc_req, head, &desc, &ewb, - rte_pktmbuf_mtod(m_src, uint8_t *), 0, -- cipher->para.dst_data_len, nb_descs, vq_size); -+ cipher->para.dst_data_len, max_n_descs); - if (unlikely(vc_req->wb == NULL)) { - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; -@@ -986,33 +966,33 @@ static __rte_always_inline uint8_t - vhost_crypto_check_chain_request(struct virtio_crypto_alg_chain_data_req *req) - { - if (likely((req->para.iv_len <= VHOST_CRYPTO_MAX_IV_LEN) && -- (req->para.src_data_len <= RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.src_data_len <= VHOST_CRYPTO_MAX_DATA_SIZE) && - (req->para.dst_data_len >= req->para.src_data_len) && -- (req->para.dst_data_len <= RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.dst_data_len <= VHOST_CRYPTO_MAX_DATA_SIZE) && - (req->para.cipher_start_src_offset < -- RTE_MBUF_DEFAULT_DATAROOM) && -- (req->para.len_to_cipher < RTE_MBUF_DEFAULT_DATAROOM) && -+ VHOST_CRYPTO_MAX_DATA_SIZE) && -+ (req->para.len_to_cipher <= VHOST_CRYPTO_MAX_DATA_SIZE) && - (req->para.hash_start_src_offset < -- RTE_MBUF_DEFAULT_DATAROOM) && -- (req->para.len_to_hash < RTE_MBUF_DEFAULT_DATAROOM) && -+ VHOST_CRYPTO_MAX_DATA_SIZE) && -+ (req->para.len_to_hash <= VHOST_CRYPTO_MAX_DATA_SIZE) && - (req->para.cipher_start_src_offset + req->para.len_to_cipher <= - req->para.src_data_len) && - (req->para.hash_start_src_offset + req->para.len_to_hash <= - req->para.src_data_len) && - (req->para.dst_data_len + req->para.hash_result_len <= -- RTE_MBUF_DEFAULT_DATAROOM))) -+ VHOST_CRYPTO_MAX_DATA_SIZE))) - return VIRTIO_CRYPTO_OK; - return VIRTIO_CRYPTO_BADMSG; - } - --static uint8_t -+static __rte_always_inline uint8_t - prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - struct vhost_crypto_data_req *vc_req, - struct virtio_crypto_alg_chain_data_req *chain, -- struct vring_desc *cur_desc, -- uint32_t *nb_descs, uint32_t vq_size) -+ struct vhost_crypto_desc *head, -+ uint32_t max_n_descs) - { -- struct vring_desc *desc = cur_desc, *digest_desc; -+ struct vhost_crypto_desc *desc = head, *digest_desc; - struct vhost_crypto_writeback_data *ewb = NULL, *ewb2 = NULL; - struct rte_mbuf *m_src = op->sym->m_src, *m_dst = op->sym->m_dst; - uint8_t *iv_data = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET); -@@ -1025,8 +1005,8 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - - /* prepare */ - /* iv */ -- if (unlikely(copy_data(iv_data, vc_req, &desc, -- chain->para.iv_len, nb_descs, vq_size) < 0)) { -+ if (unlikely(copy_data(iv_data, vc_req, head, &desc, -+ chain->para.iv_len, max_n_descs) < 0)) { - ret = VIRTIO_CRYPTO_BADMSG; - goto error_exit; - } -@@ -1045,9 +1025,8 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - goto error_exit; - } - -- if (unlikely(move_desc(vc_req->head, &desc, -- chain->para.src_data_len, -- nb_descs, vq_size) < 0)) { -+ if (unlikely(move_desc(head, &desc, chain->para.src_data_len, -+ max_n_descs) < 0)) { - VC_LOG_ERR("Incorrect descriptor"); - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; -@@ -1057,8 +1036,8 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - vc_req->wb_pool = vcrypto->wb_pool; - m_src->data_len = chain->para.src_data_len; - if (unlikely(copy_data(rte_pktmbuf_mtod(m_src, uint8_t *), -- vc_req, &desc, chain->para.src_data_len, -- nb_descs, vq_size) < 0)) { -+ vc_req, head, &desc, chain->para.src_data_len, -+ max_n_descs) < 0)) { - ret = VIRTIO_CRYPTO_BADMSG; - goto error_exit; - } -@@ -1070,7 +1049,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - } - - /* dst */ -- desc = find_write_desc(vc_req->head, desc, nb_descs, vq_size); -+ desc = find_write_desc(head, desc, max_n_descs); - if (unlikely(!desc)) { - VC_LOG_ERR("Cannot find write location"); - ret = VIRTIO_CRYPTO_BADMSG; -@@ -1089,8 +1068,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - } - - if (unlikely(move_desc(vc_req->head, &desc, -- chain->para.dst_data_len, -- nb_descs, vq_size) < 0)) { -+ chain->para.dst_data_len, max_n_descs) < 0)) { - VC_LOG_ERR("Incorrect descriptor"); - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; -@@ -1106,9 +1084,9 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - goto error_exit; - } - -- if (unlikely(move_desc(vc_req->head, &desc, -+ if (unlikely(move_desc(head, &desc, - chain->para.hash_result_len, -- nb_descs, vq_size) < 0)) { -+ max_n_descs) < 0)) { - VC_LOG_ERR("Incorrect descriptor"); - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; -@@ -1116,34 +1094,34 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - - break; - case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: -- vc_req->wb = prepare_write_back_data(vc_req, &desc, &ewb, -+ vc_req->wb = prepare_write_back_data(vc_req, head, &desc, &ewb, - rte_pktmbuf_mtod(m_src, uint8_t *), - chain->para.cipher_start_src_offset, - chain->para.dst_data_len - -- chain->para.cipher_start_src_offset, -- nb_descs, vq_size); -+ chain->para.cipher_start_src_offset, -+ max_n_descs); - if (unlikely(vc_req->wb == NULL)) { - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; - } - -+ digest_desc = desc; - digest_offset = m_src->data_len; - digest_addr = rte_pktmbuf_mtod_offset(m_src, void *, - digest_offset); -- digest_desc = desc; - - /** create a wb_data for digest */ -- ewb->next = prepare_write_back_data(vc_req, &desc, &ewb2, -- digest_addr, 0, chain->para.hash_result_len, -- nb_descs, vq_size); -+ ewb->next = prepare_write_back_data(vc_req, head, &desc, -+ &ewb2, digest_addr, 0, -+ chain->para.hash_result_len, max_n_descs); - if (unlikely(ewb->next == NULL)) { - ret = VIRTIO_CRYPTO_ERR; - goto error_exit; - } - -- if (unlikely(copy_data(digest_addr, vc_req, &digest_desc, -+ if (unlikely(copy_data(digest_addr, vc_req, head, &digest_desc, - chain->para.hash_result_len, -- nb_descs, vq_size) < 0)) { -+ max_n_descs) < 0)) { - ret = VIRTIO_CRYPTO_BADMSG; - goto error_exit; - } -@@ -1193,74 +1171,103 @@ error_exit: - static __rte_always_inline int - vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, - struct vhost_virtqueue *vq, struct rte_crypto_op *op, -- struct vring_desc *head, uint16_t desc_idx) -+ struct vring_desc *head, struct vhost_crypto_desc *descs, -+ uint16_t desc_idx) - { - struct vhost_crypto_data_req *vc_req = rte_mbuf_to_priv(op->sym->m_src); - struct rte_cryptodev_sym_session *session; -- struct virtio_crypto_op_data_req *req, tmp_req; -+ struct virtio_crypto_op_data_req req; - struct virtio_crypto_inhdr *inhdr; -- struct vring_desc *desc = NULL; -+ struct vhost_crypto_desc *desc = descs; -+ struct vring_desc *src_desc; - uint64_t session_id; - uint64_t dlen; -- uint32_t nb_descs = vq->size; -- int err = 0; -+ uint32_t nb_descs = 0, max_n_descs, i; -+ int err; - - vc_req->desc_idx = desc_idx; - vc_req->dev = vcrypto->dev; - vc_req->vq = vq; - -- if (likely(head->flags & VRING_DESC_F_INDIRECT)) { -- dlen = head->len; -- nb_descs = dlen / sizeof(struct vring_desc); -- /* drop invalid descriptors */ -- if (unlikely(nb_descs > vq->size)) -- return -1; -- desc = IOVA_TO_VVA(struct vring_desc *, vc_req, head->addr, -- &dlen, VHOST_ACCESS_RO); -- if (unlikely(!desc || dlen != head->len)) -- return -1; -- desc_idx = 0; -- head = desc; -- } else { -- desc = head; -+ if (unlikely((head->flags & VRING_DESC_F_INDIRECT) == 0)) { -+ VC_LOG_ERR("Invalid descriptor"); -+ return -1; - } - -- vc_req->head = head; -- vc_req->zero_copy = vcrypto->option; -+ dlen = head->len; -+ src_desc = IOVA_TO_VVA(struct vring_desc *, vc_req, head->addr, -+ &dlen, VHOST_ACCESS_RO); -+ if (unlikely(!src_desc || dlen != head->len)) { -+ VC_LOG_ERR("Invalid descriptor"); -+ return -1; -+ } -+ head = src_desc; - -- req = get_data_ptr(vc_req, desc, VHOST_ACCESS_RO); -- if (unlikely(req == NULL)) { -- switch (vcrypto->option) { -- case RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE: -- err = VIRTIO_CRYPTO_BADMSG; -- VC_LOG_ERR("Invalid descriptor"); -- goto error_exit; -- case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: -- req = &tmp_req; -- if (unlikely(copy_data(req, vc_req, &desc, sizeof(*req), -- &nb_descs, vq->size) < 0)) { -- err = VIRTIO_CRYPTO_BADMSG; -- VC_LOG_ERR("Invalid descriptor"); -- goto error_exit; -+ nb_descs = max_n_descs = dlen / sizeof(struct vring_desc); -+ if (unlikely(nb_descs > VHOST_CRYPTO_MAX_N_DESC || nb_descs == 0)) { -+ err = VIRTIO_CRYPTO_ERR; -+ VC_LOG_ERR("Cannot process num of descriptors %u", nb_descs); -+ if (nb_descs > 0) { -+ struct vring_desc *inhdr_desc = head; -+ while (inhdr_desc->flags & VRING_DESC_F_NEXT) { -+ if (inhdr_desc->next >= max_n_descs) -+ return -1; -+ inhdr_desc = &head[inhdr_desc->next]; - } -- break; -- default: -- err = VIRTIO_CRYPTO_ERR; -- VC_LOG_ERR("Invalid option"); -- goto error_exit; -+ if (inhdr_desc->len != sizeof(*inhdr)) -+ return -1; -+ inhdr = IOVA_TO_VVA(struct virtio_crypto_inhdr *, -+ vc_req, inhdr_desc->addr, &dlen, -+ VHOST_ACCESS_WO); -+ if (unlikely(!inhdr || dlen != inhdr_desc->len)) -+ return -1; -+ inhdr->status = VIRTIO_CRYPTO_ERR; -+ return -1; - } -- } else { -- if (unlikely(move_desc(vc_req->head, &desc, -- sizeof(*req), &nb_descs, vq->size) < 0)) { -- VC_LOG_ERR("Incorrect descriptor"); -+ } -+ -+ /* copy descriptors to local variable */ -+ for (i = 0; i < max_n_descs; i++) { -+ desc->addr = src_desc->addr; -+ desc->len = src_desc->len; -+ desc->flags = src_desc->flags; -+ desc++; -+ if (unlikely((src_desc->flags & VRING_DESC_F_NEXT) == 0)) -+ break; -+ if (unlikely(src_desc->next >= max_n_descs)) { -+ err = VIRTIO_CRYPTO_BADMSG; -+ VC_LOG_ERR("Invalid descriptor"); - goto error_exit; - } -+ src_desc = &head[src_desc->next]; -+ } -+ -+ vc_req->head = head; -+ vc_req->zero_copy = vcrypto->option; -+ -+ nb_descs = desc - descs; -+ desc = descs; -+ -+ if (unlikely(desc->len < sizeof(req))) { -+ err = VIRTIO_CRYPTO_BADMSG; -+ VC_LOG_ERR("Invalid descriptor"); -+ goto error_exit; - } - -- switch (req->header.opcode) { -+ if (unlikely(copy_data(&req, vc_req, descs, &desc, sizeof(req), -+ max_n_descs) < 0)) { -+ err = VIRTIO_CRYPTO_BADMSG; -+ VC_LOG_ERR("Invalid descriptor"); -+ goto error_exit; -+ } -+ -+ /* desc is advanced by 1 now */ -+ max_n_descs -= 1; -+ -+ switch (req.header.opcode) { - case VIRTIO_CRYPTO_CIPHER_ENCRYPT: - case VIRTIO_CRYPTO_CIPHER_DECRYPT: -- session_id = req->header.session_id; -+ session_id = req.header.session_id; - - /* one branch to avoid unnecessary table lookup */ - if (vcrypto->cache_session_id != session_id) { -@@ -1286,19 +1293,19 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, - goto error_exit; - } - -- switch (req->u.sym_req.op_type) { -+ switch (req.u.sym_req.op_type) { - case VIRTIO_CRYPTO_SYM_OP_NONE: - err = VIRTIO_CRYPTO_NOTSUPP; - break; - case VIRTIO_CRYPTO_SYM_OP_CIPHER: - err = prepare_sym_cipher_op(vcrypto, op, vc_req, -- &req->u.sym_req.u.cipher, desc, -- &nb_descs, vq->size); -+ &req.u.sym_req.u.cipher, desc, -+ max_n_descs); - break; - case VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING: - err = prepare_sym_chain_op(vcrypto, op, vc_req, -- &req->u.sym_req.u.chain, desc, -- &nb_descs, vq->size); -+ &req.u.sym_req.u.chain, desc, -+ max_n_descs); - break; - } - if (unlikely(err != 0)) { -@@ -1307,8 +1314,9 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, - } - break; - default: -+ err = VIRTIO_CRYPTO_ERR; - VC_LOG_ERR("Unsupported symmetric crypto request type %u", -- req->header.opcode); -+ req.header.opcode); - goto error_exit; - } - -@@ -1316,7 +1324,7 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, - - error_exit: - -- inhdr = reach_inhdr(vc_req, desc, &nb_descs, vq->size); -+ inhdr = reach_inhdr(vc_req, descs, max_n_descs); - if (likely(inhdr != NULL)) - inhdr->status = (uint8_t)err; - -@@ -1330,17 +1338,16 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op, - struct rte_mbuf *m_src = op->sym->m_src; - struct rte_mbuf *m_dst = op->sym->m_dst; - struct vhost_crypto_data_req *vc_req = rte_mbuf_to_priv(m_src); -- uint16_t desc_idx; -+ struct vhost_virtqueue *vq = vc_req->vq; -+ uint16_t used_idx = vc_req->desc_idx, desc_idx; - - if (unlikely(!vc_req)) { - VC_LOG_ERR("Failed to retrieve vc_req"); - return NULL; - } - -- if (old_vq && (vc_req->vq != old_vq)) -- return vc_req->vq; -- -- desc_idx = vc_req->desc_idx; -+ if (old_vq && (vq != old_vq)) -+ return vq; - - if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) - vc_req->inhdr->status = VIRTIO_CRYPTO_ERR; -@@ -1349,8 +1356,9 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op, - write_back_data(vc_req); - } - -- vc_req->vq->used->ring[desc_idx].id = desc_idx; -- vc_req->vq->used->ring[desc_idx].len = vc_req->len; -+ desc_idx = vq->avail->ring[used_idx]; -+ vq->used->ring[desc_idx].id = vq->avail->ring[desc_idx]; -+ vq->used->ring[desc_idx].len = vc_req->len; - - rte_mempool_put(m_src->pool, (void *)m_src); - -@@ -1448,7 +1456,7 @@ rte_vhost_crypto_create(int vid, uint8_t cryptodev_id, - vcrypto->mbuf_pool = rte_pktmbuf_pool_create(name, - VHOST_CRYPTO_MBUF_POOL_SIZE, 512, - sizeof(struct vhost_crypto_data_req), -- RTE_MBUF_DEFAULT_DATAROOM * 2 + RTE_PKTMBUF_HEADROOM, -+ VHOST_CRYPTO_MAX_DATA_SIZE + RTE_PKTMBUF_HEADROOM, - rte_socket_id()); - if (!vcrypto->mbuf_pool) { - VC_LOG_ERR("Failed to creath mbuf pool"); -@@ -1574,6 +1582,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, - struct rte_crypto_op **ops, uint16_t nb_ops) - { - struct rte_mbuf *mbufs[VHOST_CRYPTO_MAX_BURST_SIZE * 2]; -+ struct vhost_crypto_desc descs[VHOST_CRYPTO_MAX_N_DESC]; - struct virtio_net *dev = get_device(vid); - struct vhost_crypto *vcrypto; - struct vhost_virtqueue *vq; -@@ -1632,7 +1641,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, - op->sym->m_dst->data_off = 0; - - if (unlikely(vhost_crypto_process_one_req(vcrypto, vq, -- op, head, desc_idx) < 0)) -+ op, head, descs, used_idx) < 0)) - break; - } - -@@ -1661,7 +1670,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, - op->sym->m_src->data_off = 0; - - if (unlikely(vhost_crypto_process_one_req(vcrypto, vq, -- op, head, desc_idx) < 0)) -+ op, head, descs, desc_idx) < 0)) - break; - } - --- -cgit v1.0 diff --git a/CVE-2020-14376-CVE-2020-14377.patch b/CVE-2020-14376-CVE-2020-14377.patch deleted file mode 100644 index c28e251..0000000 --- a/CVE-2020-14376-CVE-2020-14377.patch +++ /dev/null @@ -1,163 +0,0 @@ -From e4a7c14f02480a41992414afb5e011f8ff8f02f3 Mon Sep 17 00:00:00 2001 -From: Fan Zhang -Date: Tue, 14 Apr 2020 17:26:48 +0100 -Subject: vhost/crypto: fix missed request check for copy mode - -This patch fixes the missed request check to vhost crypto -copy mode. - -CVE-2020-14376 -CVE-2020-14377 -Fixes: 3bb595ecd682 ("vhost/crypto: add request handler") -Cc: stable@dpdk.org - -Signed-off-by: Fan Zhang -Acked-by: Chenbo Xia - -reference:https://git.dpdk.org/dpdk-stable/commit/?h=19.11&id=e4a7c14f0248 -Signed-off-by: gaoxingwang ---- - lib/librte_vhost/vhost_crypto.c | 68 ++++++++++++++++++++++++++++------------- - 1 file changed, 47 insertions(+), 21 deletions(-) - -diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c -index 86747dd..494f490 100644 ---- a/lib/librte_vhost/vhost_crypto.c -+++ b/lib/librte_vhost/vhost_crypto.c -@@ -756,7 +756,7 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, - } - - wb_data->dst = dst; -- wb_data->len = desc->len - offset; -+ wb_data->len = RTE_MIN(desc->len - offset, write_back_len); - write_back_len -= wb_data->len; - src += offset + wb_data->len; - offset = 0; -@@ -840,6 +840,17 @@ error_exit: - return NULL; - } - -+static __rte_always_inline uint8_t -+vhost_crypto_check_cipher_request(struct virtio_crypto_cipher_data_req *req) -+{ -+ if (likely((req->para.iv_len <= VHOST_CRYPTO_MAX_IV_LEN) && -+ (req->para.src_data_len <= RTE_MBUF_DEFAULT_BUF_SIZE) && -+ (req->para.dst_data_len >= req->para.src_data_len) && -+ (req->para.dst_data_len <= RTE_MBUF_DEFAULT_BUF_SIZE))) -+ return VIRTIO_CRYPTO_OK; -+ return VIRTIO_CRYPTO_BADMSG; -+} -+ - static uint8_t - prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - struct vhost_crypto_data_req *vc_req, -@@ -851,7 +862,10 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - struct vhost_crypto_writeback_data *ewb = NULL; - struct rte_mbuf *m_src = op->sym->m_src, *m_dst = op->sym->m_dst; - uint8_t *iv_data = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET); -- uint8_t ret = 0; -+ uint8_t ret = vhost_crypto_check_cipher_request(cipher); -+ -+ if (unlikely(ret != VIRTIO_CRYPTO_OK)) -+ goto error_exit; - - /* prepare */ - /* iv */ -@@ -861,10 +875,9 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - goto error_exit; - } - -- m_src->data_len = cipher->para.src_data_len; -- - switch (vcrypto->option) { - case RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE: -+ m_src->data_len = cipher->para.src_data_len; - m_src->buf_iova = gpa_to_hpa(vcrypto->dev, desc->addr, - cipher->para.src_data_len); - m_src->buf_addr = get_data_ptr(vc_req, desc, VHOST_ACCESS_RO); -@@ -886,13 +899,7 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - break; - case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: - vc_req->wb_pool = vcrypto->wb_pool; -- -- if (unlikely(cipher->para.src_data_len > -- RTE_MBUF_DEFAULT_BUF_SIZE)) { -- VC_LOG_ERR("Not enough space to do data copy"); -- ret = VIRTIO_CRYPTO_ERR; -- goto error_exit; -- } -+ m_src->data_len = cipher->para.src_data_len; - if (unlikely(copy_data(rte_pktmbuf_mtod(m_src, uint8_t *), - vc_req, &desc, cipher->para.src_data_len, - nb_descs, vq_size) < 0)) { -@@ -975,6 +982,29 @@ error_exit: - return ret; - } - -+static __rte_always_inline uint8_t -+vhost_crypto_check_chain_request(struct virtio_crypto_alg_chain_data_req *req) -+{ -+ if (likely((req->para.iv_len <= VHOST_CRYPTO_MAX_IV_LEN) && -+ (req->para.src_data_len <= RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.dst_data_len >= req->para.src_data_len) && -+ (req->para.dst_data_len <= RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.cipher_start_src_offset < -+ RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.len_to_cipher < RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.hash_start_src_offset < -+ RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.len_to_hash < RTE_MBUF_DEFAULT_DATAROOM) && -+ (req->para.cipher_start_src_offset + req->para.len_to_cipher <= -+ req->para.src_data_len) && -+ (req->para.hash_start_src_offset + req->para.len_to_hash <= -+ req->para.src_data_len) && -+ (req->para.dst_data_len + req->para.hash_result_len <= -+ RTE_MBUF_DEFAULT_DATAROOM))) -+ return VIRTIO_CRYPTO_OK; -+ return VIRTIO_CRYPTO_BADMSG; -+} -+ - static uint8_t - prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - struct vhost_crypto_data_req *vc_req, -@@ -988,7 +1018,10 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - uint8_t *iv_data = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET); - uint32_t digest_offset; - void *digest_addr; -- uint8_t ret = 0; -+ uint8_t ret = vhost_crypto_check_chain_request(chain); -+ -+ if (unlikely(ret != VIRTIO_CRYPTO_OK)) -+ goto error_exit; - - /* prepare */ - /* iv */ -@@ -998,10 +1031,9 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - goto error_exit; - } - -- m_src->data_len = chain->para.src_data_len; -- - switch (vcrypto->option) { - case RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE: -+ m_src->data_len = chain->para.src_data_len; - m_dst->data_len = chain->para.dst_data_len; - - m_src->buf_iova = gpa_to_hpa(vcrypto->dev, desc->addr, -@@ -1023,13 +1055,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, - break; - case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: - vc_req->wb_pool = vcrypto->wb_pool; -- -- if (unlikely(chain->para.src_data_len > -- RTE_MBUF_DEFAULT_BUF_SIZE)) { -- VC_LOG_ERR("Not enough space to do data copy"); -- ret = VIRTIO_CRYPTO_ERR; -- goto error_exit; -- } -+ m_src->data_len = chain->para.src_data_len; - if (unlikely(copy_data(rte_pktmbuf_mtod(m_src, uint8_t *), - vc_req, &desc, chain->para.src_data_len, - nb_descs, vq_size) < 0)) { --- -cgit v1.0 diff --git a/CVE-2020-14378.patch b/CVE-2020-14378.patch deleted file mode 100644 index 902dc04..0000000 --- a/CVE-2020-14378.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 81e9694830209207cbba599b62858c97c3ed5cfe Mon Sep 17 00:00:00 2001 -From: Fan Zhang -Date: Tue, 14 Apr 2020 16:52:47 +0100 -Subject: vhost/crypto: fix incorrect descriptor deduction - -This patch fixes the incorrect descriptor deduction for vhost crypto. - -CVE-2020-14378 -Fixes: 16d2e718b8ce ("vhost/crypto: fix possible out of bound access") -Cc: stable@dpdk.org - -Signed-off-by: Fan Zhang -Acked-by: Chenbo Xia - -reference:https://git.dpdk.org/dpdk-stable/commit/?h=19.11&id=81e969483020 -Signed-off-by: gaoxingwang ---- - lib/librte_vhost/vhost_crypto.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c -index 0f9df40..86747dd 100644 ---- a/lib/librte_vhost/vhost_crypto.c -+++ b/lib/librte_vhost/vhost_crypto.c -@@ -530,13 +530,14 @@ move_desc(struct vring_desc *head, struct vring_desc **cur_desc, - int left = size - desc->len; - - while ((desc->flags & VRING_DESC_F_NEXT) && left > 0) { -- (*nb_descs)--; - if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) - return -1; - - desc = &head[desc->next]; - rte_prefetch0(&head[desc->next]); - left -= desc->len; -+ if (left > 0) -+ (*nb_descs)--; - } - - if (unlikely(left > 0)) --- -cgit v1.0 diff --git a/dpdk-19.11.tar.xz b/dpdk-19.11.tar.xz deleted file mode 100644 index 6969939..0000000 Binary files a/dpdk-19.11.tar.xz and /dev/null differ diff --git a/dpdk-20.11.tar.xz b/dpdk-20.11.tar.xz new file mode 100644 index 0000000..b022fc5 Binary files /dev/null and b/dpdk-20.11.tar.xz differ diff --git a/dpdk.spec b/dpdk.spec index 749efbe..ceac599 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,73 +1,217 @@ Name: dpdk -Version: 19.11 -Release: 14 +Version: 20.11 +Release: 1 Packager: packaging@6wind.com URL: http://dpdk.org -%global source_version 19.11 +%global source_version 20.11 Source: https://git.dpdk.org/dpdk/snapshot/%{name}-%{version}.tar.xz -Patch0: CVE-2020-10725.patch -Patch1: CVE-2020-10722.patch -Patch2: CVE-2020-10723.patch -Patch3: CVE-2020-10724.patch -Patch4: CVE-2020-10726.patch -Patch5: kni-fix-build-with-Linux-5.6.patch -Patch6: v2-kni-fix-build-with-Linux-5.9.patch -Patch7: CVE-2020-14378.patch -Patch8: CVE-2020-14376-CVE-2020-14377.patch -Patch9: fix-pool-allocation.patch -Patch10: CVE-2020-14374.patch -Patch11: CVE-2020-14375.patch -Patch12: fix-compilation-error-of-max-inline-insns-single-o2-.patch -Patch13: fix-populate-with-small-virtual-chunks.patch -Patch14: 0001-dpdk-add-secure-compile-option-and-fPIC-option.patch -Patch15: 0002-dpdk-add-secure-option-in-makefile.patch -Patch16: 0003-dpdk-bugfix-the-deadlock-in-rte_eal_init.patch -Patch17: 0004-dpdk-master-core-donot-set-affinity-in-libstorage.patch -Patch18: 0005-dpdk-change-the-log-level-in-prepare_numa.patch -Patch19: 0006-dpdk-fix-dpdk-coredump-problem.patch -Patch20: 0007-dpdk-add-secure-compile-option-in-pmdinfogen-Makefil.patch -Patch21: 0008-dpdk-fix-cpu-flag-error-in-Intel-R-Xeon-R-CPU-E5-262.patch -Patch22: 0009-dpdk-support-gazelle-01-include.patch -Patch23: 0009-dpdk-support-gazelle-02-include-base.patch -Patch24: 0009-dpdk-support-gazelle-03-memory.patch -Patch25: 0009-dpdk-support-gazelle-04-cfg-options.patch -Patch26: 0009-dpdk-support-gazelle-05-fbarray-hugepageinfo.patch -Patch27: 0009-dpdk-support-gazelle-06-memalloc.patch -Patch28: 0009-dpdk-support-gazelle-07-eal-add-sec-attach.patch -Patch29: 0009-dpdk-support-gazelle-08-eal-add-config.patch -Patch30: 0009-dpdk-support-gazelle-09-eal-add-libnetapi.patch -Patch31: 0009-dpdk-support-gazelle-10-eal-memory-inter-config.patch -Patch32: 0009-dpdk-support-gazelle-11-eal-memory-add-sec.patch -Patch33: 0010-dpdk-fix-error-in-clearing-secondary-process-memseg-lists.patch -Patch34: 0011-dpdk-fix-coredump-when-primary-process-attach-without-shared-file.patch -Patch35: 0012-dpdk-fix-fbarray-memseg-destory-error-during-detach.patch -Patch36: 0013-dpdk-optimize-the-efficiency-of-compiling-dpdk.patch +Patch0: 0001-net-hns3-adjust-MAC-address-logging.patch +Patch1: 0002-net-hns3-fix-FEC-state-query.patch +Patch2: 0003-net-hns3-fix-build-with-SVE.patch +Patch3: 0004-net-hns3-fix-interception-with-flow-director.patch +Patch4: 0005-net-hns3-fix-xstats-with-id-and-names.patch +Patch5: 0006-net-hns3-fix-error-code-in-xstats.patch +Patch6: 0007-net-hns3-fix-Rx-Tx-errors-stats.patch +Patch7: 0008-net-hns3-fix-crash-with-multi-process.patch +Patch8: 0009-net-hns3-remove-unnecessary-memset.patch +Patch9: 0010-net-hns3-fix-jumbo-frame-flag-condition-for-MTU-set.patch +Patch10: 0011-net-hns3-use-C11-atomics-builtins-for-resetting.patch +Patch11: 0012-net-hns3-support-traffic-management.patch +Patch12: 0013-net-hns3-fix-VF-query-link-status-in-dev-init.patch +Patch13: 0014-net-hns3-use-new-opcode-for-clearing-hardware-resour.patch +Patch14: 0015-net-hns3-fix-register-length-when-dumping-registers.patch +Patch15: 0016-net-hns3-fix-data-overwriting-during-register-dump.patch +Patch16: 0017-net-hns3-fix-dump-register-out-of-range.patch +Patch17: 0018-net-hns3-remove-unused-assignment-for-RSS-key.patch +Patch18: 0019-net-hns3-encapsulate-DFX-stats-in-datapath.patch +Patch19: 0020-net-hns3-move-queue-stats-to-xstats.patch +Patch20: 0021-net-hns3-refactor-converting-descriptor-error.patch +Patch21: 0022-net-hns3-refactor-flow-checks-into-own-functions.patch +Patch22: 0023-net-hns3-reconstruct-Rx-interrupt-map.patch +Patch23: 0024-net-hns3-extract-common-checks-for-flow-director.patch +Patch24: 0025-net-hns3-refactor-reset-event-report-function.patch +Patch25: 0026-net-hns3-fix-memory-leak-on-secondary-process-exit.patch +Patch26: 0027-net-hns3-fix-interrupt-resources-in-Rx-interrupt-mod.patch +Patch27: 0028-net-hns3-rename-RSS-functions.patch +Patch28: 0029-net-hns3-adjust-some-comments.patch +Patch29: 0030-net-hns3-remove-unnecessary-parentheses.patch +Patch30: 0031-net-hns3-adjust-format-specifier-for-enum.patch +Patch31: 0032-net-hns3-support-LSC-event-report.patch +Patch32: 0033-net-hns3-fix-query-order-of-link-status-and-link-inf.patch +Patch33: 0034-net-hns3-fix-link-status-change-from-firmware.patch +Patch34: 0035-net-hns3-fix-RSS-indirection-table-size.patch +Patch35: 0036-net-hns3-constrain-TM-peak-rate.patch +Patch36: 0037-net-hns3-remove-MPLS-from-supported-flow-items.patch +Patch37: 0038-net-hns3-fix-stats-flip-overflow.patch +Patch38: 0039-net-hns3-use-C11-atomics.patch +Patch39: 0040-net-hns3-fix-flow-director-rule-residue-on-malloc-fa.patch +Patch40: 0041-net-hns3-fix-firmware-exceptions-by-concurrent-comma.patch +Patch41: 0042-net-hns3-fix-VF-reset-on-mailbox-failure.patch +Patch42: 0043-net-hns3-validate-requested-maximum-Rx-frame-length.patch +Patch43: 0044-drivers-net-redefine-array-size-macros.patch +Patch44: 0045-net-hns3-support-module-EEPROM-dump.patch +Patch45: 0046-net-hns3-add-more-registers-to-dump.patch +Patch46: 0047-net-hns3-implement-Tx-mbuf-free-on-demand.patch +Patch47: 0048-net-hns3-add-bytes-stats.patch +Patch48: 0049-net-hns3-add-imissed-packet-stats.patch +Patch49: 0050-net-hns3-encapsulate-port-shaping-interface.patch +Patch50: 0051-net-hns3-fix-device-capabilities-for-copper-media-ty.patch +Patch51: 0052-net-hns3-support-PF-device-with-copper-PHYs.patch +Patch52: 0053-net-hns3-support-Rx-descriptor-advanced-layout.patch +Patch53: 0054-net-hns3-fix-HW-buffer-size-on-MTU-update.patch +Patch54: 0055-net-hns3-remove-unused-parameter-markers.patch +Patch55: 0056-net-hns3-fix-mbuf-leakage.patch +Patch56: 0057-net-hns3-process-MAC-interrupt.patch +Patch57: 0058-net-hns3-fix-imprecise-statistics.patch +Patch58: 0059-net-hns3-add-runtime-config-to-select-IO-burst-funct.patch +Patch59: 0060-net-hns3-support-outer-UDP-checksum.patch +Patch60: 0061-net-hns3-adjust-format-of-RAS-related-structures.patch +Patch61: 0062-net-hns3-delete-redundant-xstats-RAS-statistics.patch +Patch62: 0063-net-hns3-support-imissed-stats-for-PF-VF.patch +Patch63: 0064-net-hns3-support-oerrors-stats-in-PF.patch +Patch64: 0065-net-hns3-support-Tx-descriptor-status-query.patch +Patch65: 0066-net-hns3-support-Rx-descriptor-status-query.patch +Patch66: 0067-net-hns3-fix-reporting-undefined-speed.patch +Patch67: 0068-net-hns3-fix-build-for-SVE-path.patch +Patch68: 0069-net-hns3-fix-processing-Tx-offload-flags.patch +Patch69: 0070-net-hns3-fix-Tx-checksum-for-UDP-packets-with-specia.patch +Patch70: 0071-net-hns3-fix-link-update-when-failed-to-get-link-inf.patch +Patch71: 0072-net-hns3-fix-long-task-queue-pairs-reset-time.patch +Patch72: 0073-net-hns3-fix-MTU-config-complexity.patch +Patch73: 0074-net-hns3-support-IEEE-1588-PTP.patch +Patch74: 0075-ethdev-validate-input-in-register-info.patch +Patch75: 0076-net-hns3-support-wait-in-link-update.patch +Patch76: 0077-net-hns3-fix-some-function-names-for-copper-media-ty.patch +Patch77: 0078-net-hns3-fix-setting-default-MAC-address-in-bonding-.patch +Patch78: 0079-net-hns3-fix-FLR-miss-detection.patch +Patch79: 0080-net-hns3-fix-rollback-after-setting-PVID-failure.patch +Patch80: 0081-net-hns3-fix-flow-control-exception.patch +Patch81: 0082-net-hns3-fix-flow-counter-value.patch +Patch82: 0083-net-hns3-fix-VF-mailbox-head-field.patch +Patch83: 0084-net-hns3-support-get-device-version-when-dump-regist.patch +Patch84: 0085-net-hns3-delete-redundant-blank-line.patch +Patch85: 0086-net-hns3-fix-code-style.patch +Patch86: 0087-net-hns3-refactor-VF-LSC-event-report.patch +Patch87: 0088-net-hns3-refactor-PF-LSC-event-report.patch +Patch88: 0089-net-hns3-log-selected-datapath.patch +Patch89: 0090-net-hns3-simplify-selecting-Rx-Tx-function.patch +Patch90: 0091-net-hns3-fix-rollback-in-PF-init.patch +Patch91: 0092-net-hns3-fix-concurrent-interrupt-handling.patch +Patch92: 0093-net-hns3-fix-some-packet-types.patch +Patch93: 0094-net-hns3-fix-timing-in-resetting-queues.patch +Patch94: 0095-net-hns3-fix-queue-state-when-concurrent-with-reset.patch +Patch95: 0096-net-hns3-fix-configure-FEC-when-concurrent-with-rese.patch +Patch96: 0097-net-hns3-delete-mailbox-arq-ring.patch +Patch97: 0098-net-hns3-fix-possible-mismatched-response-of-mailbox.patch +Patch98: 0099-net-hns3-fix-VF-handling-LSC-event-in-secondary-proc.patch +Patch99: 0100-net-hns3-fix-timing-in-mailbox.patch +Patch100: 0101-net-hns3-fix-use-of-command-status-enumeration.patch +Patch101: 0102-net-hns3-fix-verification-of-NEON-support.patch +Patch102: 0103-net-hns3-fix-missing-outer-L4-UDP-flag-for-VXLAN.patch +Patch103: 0104-net-hns3-add-reporting-tunnel-GRE-packet-type.patch +Patch104: 0105-net-hns3-fix-PTP-capability-report.patch +Patch105: 0106-net-hns3-list-supported-ptypes-for-advanced-Rx-descr.patch +Patch106: 0107-net-hns3-remove-VLAN-QinQ-ptypes-from-support-list.patch +Patch107: 0108-net-hns3-fix-supported-speed-of-copper-ports.patch +Patch108: 0109-net-hns3-add-1000M-speed-bit-for-copper-PHYs.patch +Patch109: 0110-net-hns3-fix-flow-control-mode.patch +Patch110: 0111-net-hns3-fix-firmware-compatibility-configuration.patch +Patch111: 0112-net-hns3-obtain-supported-speed-for-fiber-port.patch +Patch112: 0113-net-hns3-report-speed-capability-for-PF.patch +Patch113: 0114-net-hns3-support-link-speed-autoneg-for-PF.patch +Patch114: 0115-net-hns3-support-flow-control-autoneg-for-copper-por.patch +Patch115: 0116-net-hns3-support-fixed-link-speed.patch +Patch116: 0117-net-hns3-rename-Rx-burst-function.patch +Patch117: 0118-net-hns3-remove-unused-macros.patch +Patch118: 0119-net-hns3-support-RAS-process-in-Kunpeng-930.patch +Patch119: 0120-net-hns3-support-masking-device-capability.patch +Patch120: 0121-net-hns3-simplify-Rx-checksum.patch +Patch121: 0122-net-hns3-check-max-SIMD-bitwidth.patch +Patch122: 0123-net-hns3-add-compile-time-verification-on-Rx-vector.patch +Patch123: 0124-net-hns3-remove-redundant-mailbox-response.patch +Patch124: 0125-net-hns3-fix-DCB-mode-check.patch +Patch125: 0126-net-hns3-fix-VMDq-mode-check.patch +Patch126: 0127-net-hns3-fix-flow-director-lock.patch +Patch127: 0128-net-hns3-move-link-speeds-check-to-configure.patch +Patch128: 0129-net-hns3-remove-unused-macro.patch +Patch129: 0130-net-hns3-fix-traffic-management-support-check.patch +Patch130: 0131-net-hns3-ignore-devargs-parsing-return.patch +Patch131: 0132-net-hns3-fix-mailbox-error-message.patch +Patch132: 0133-net-hns3-fix-processing-link-status-message-on-PF.patch +Patch133: 0134-net-hns3-remove-unused-mailbox-macro-and-struct.patch +Patch134: 0135-net-hns3-fix-typos-on-comments.patch +Patch135: 0136-net-hns3-disable-MAC-status-report-interrupt.patch +Patch136: 0137-net-hns3-fix-handling-link-update.patch +Patch137: 0138-net-hns3-fix-link-status-when-port-is-stopped.patch +Patch138: 0139-net-hns3-fix-link-speed-when-port-is-down.patch +Patch139: 0140-net-hns3-support-preferred-burst-size-and-queues-in-.patch +Patch140: 0141-net-hns3-log-time-delta-in-decimal-format.patch +Patch141: 0142-net-hns3-fix-time-delta-calculation.patch +Patch142: 0143-net-hns3-select-Tx-prepare-based-on-Tx-offload.patch +Patch143: 0144-net-hns3-fix-MAC-enable-failure-rollback.patch +Patch144: 0145-net-hns3-fix-IEEE-1588-PTP-for-scalar-scattered-Rx.patch +Patch145: 0146-net-hns3-remove-some-unused-capabilities.patch +Patch146: 0147-net-hns3-refactor-optimised-register-write.patch +Patch147: 0148-net-hns3-use-existing-macro-to-get-array-size.patch +Patch148: 0149-net-hns3-improve-IO-path-data-cache-usage.patch +Patch149: 0150-net-hns3-log-flow-director-configuration.patch +Patch150: 0151-net-hns3-fix-vector-Rx-burst-limitation.patch +Patch151: 0152-net-hns3-remove-read-when-enabling-TM-QCN-error-even.patch +Patch152: 0153-net-hns3-remove-unused-VMDq-code.patch +Patch153: 0154-net-hns3-increase-readability-in-logs.patch +Patch154: 0155-net-hns3-fix-debug-build.patch +Patch155: 0156-net-hns3-return-error-on-PCI-config-write-failure.patch +Patch156: 0157-net-hns3-fix-log-on-flow-director-clear.patch +Patch157: 0158-net-hns3-clear-hash-map-on-flow-director-clear.patch +Patch158: 0159-net-hns3-fix-VF-alive-notification-after-config-rest.patch +Patch159: 0160-net-hns3-fix-querying-flow-director-counter-for-out-.patch +Patch160: 0161-net-hns3-fix-TM-QCN-error-event-report-by-MSI-X.patch +Patch161: 0162-net-hns3-fix-mailbox-message-ID-in-log.patch +Patch162: 0163-net-hns3-fix-secondary-process-request-start-stop-Rx.patch +Patch163: 0164-net-hns3-fix-ordering-in-secondary-process-initializ.patch +Patch164: 0165-net-hns3-fail-setting-FEC-if-one-bit-mode-is-not-sup.patch +Patch165: 0166-net-hns3-fix-Rx-Tx-queue-numbers-check.patch +Patch166: 0167-net-hns3-fix-requested-FC-mode-rollback.patch +Patch167: 0168-net-hns3-remove-meaningless-packet-buffer-rollback.patch +Patch168: 0169-net-hns3-fix-DCB-configuration.patch +Patch169: 0170-net-hns3-fix-DCB-reconfiguration.patch +Patch170: 0171-net-hns3-fix-link-speed-when-VF-device-is-down.patch +Patch171: 0172-net-bonding-fix-adding-itself-as-its-slave.patch +Patch172: 0173-ipc-use-monotonic-clock.patch +Patch173: 0174-ethdev-add-queue-state-in-queried-queue-information.patch +Patch174: 0175-app-testpmd-fix-queue-stats-mapping-configuration.patch +Patch175: 0176-app-testpmd-fix-bitmap-of-link-speeds-when-force-spe.patch +Patch176: 0177-app-testpmd-add-link-autoneg-status-display.patch +Patch177: 0178-app-testpmd-support-cleanup-Tx-queue-mbufs.patch +Patch178: 0179-app-testpmd-show-link-flow-control-info.patch +Patch179: 0180-app-testpmd-support-display-queue-state.patch +Patch180: 0181-app-testpmd-fix-max-queue-number-for-Tx-offloads.patch +Patch181: 0182-app-testpmd-fix-forward-lcores-number-for-DCB.patch +Patch182: 0183-app-testpmd-fix-DCB-forwarding-configuration.patch +Patch183: 0184-app-testpmd-fix-DCB-re-configuration.patch +Patch184: 0185-app-testpmd-check-DCB-info-support-for-configuration.patch +Patch185: 0186-app-testpmd-verify-DCB-config-during-forward-config.patch +Patch186: 0187-app-testpmd-add-forwarding-configuration-to-DCB-conf.patch +Patch187: 0188-app-testpmd-remove-redundant-forwarding-initializati.patch +Patch188: 0189-net-fix-compiling-bug-for-20.11-merge.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries License: BSD and LGPLv2 and GPLv2 ExclusiveArch: i686 x86_64 aarch64 -%ifarch aarch64 %global machine armv8a -%global target arm64-%{machine}-linux-gcc -%global config arm64-%{machine}-linux-gcc -%else -%global machine native -%global target x86_64-%{machine}-linux-gcc -%global config x86_64-%{machine}-linux-gcc -%endif +%global target build + +BuildRequires: meson +BuildRequires: ninja-build BuildRequires: gcc -BuildRequires: kernel-devel, libpcap-devel -BuildRequires: numactl-devel libconfig-devel -BuildRequires: module-init-tools uname-build-checks libnl3 libmnl -BuildRequires: glibc glibc-devel libibverbs libibverbs-devel libmnl-devel +BuildRequires: kernel-devel -Requires: python3-pyelftools +%define kern_devel_ver %(uname -r) -%define kern_devel_ver %(uname -r) %description DPDK core includes kernel modules, core libraries and tools. testpmd application allows to test fast packet processing environments @@ -79,8 +223,7 @@ More libraries are available as extensions in other packages. Summary: Data Plane Development Kit for development Requires: %{name}%{?_isa} = %{version}-%{release} %description devel -DPDK devel is a set of makefiles, headers and examples -for fast packet processing on arm64 platforms. +DPDK devel is a set of headers for fast packet processing on arm64 platforms. %package doc Summary: Data Plane Development Kit API documentation @@ -89,15 +232,22 @@ BuildArch: noarch DPDK doc is divided in two parts: API details in doxygen HTML format and guides in sphinx HTML/PDF formats. -%package tools -Summary: dpdk pdump tool -Group : Applications/System -Requires: dpdk = %{version} -%description tools -This package contains the pdump tool for capture the dpdk network packets. - %prep %setup -q -n %{name}-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 %patch14 -p1 %patch15 -p1 %patch16 -p1 @@ -106,11 +256,6 @@ This package contains the pdump tool for capture the dpdk network packets. %patch19 -p1 %patch20 -p1 %patch21 -p1 -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 %patch22 -p1 %patch23 -p1 %patch24 -p1 @@ -125,100 +270,183 @@ This package contains the pdump tool for capture the dpdk network packets. %patch33 -p1 %patch34 -p1 %patch35 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 %patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 +%patch82 -p1 +%patch83 -p1 +%patch84 -p1 +%patch85 -p1 +%patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 +%patch90 -p1 +%patch91 -p1 +%patch92 -p1 +%patch93 -p1 +%patch94 -p1 +%patch95 -p1 +%patch96 -p1 +%patch97 -p1 +%patch98 -p1 +%patch99 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 +%patch111 -p1 +%patch112 -p1 +%patch113 -p1 +%patch114 -p1 +%patch115 -p1 +%patch116 -p1 +%patch117 -p1 +%patch118 -p1 +%patch119 -p1 +%patch120 -p1 +%patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 +%patch125 -p1 +%patch126 -p1 +%patch127 -p1 +%patch128 -p1 +%patch129 -p1 +%patch130 -p1 +%patch131 -p1 +%patch132 -p1 +%patch133 -p1 +%patch134 -p1 +%patch135 -p1 +%patch136 -p1 +%patch137 -p1 +%patch138 -p1 +%patch139 -p1 +%patch140 -p1 +%patch141 -p1 +%patch142 -p1 +%patch143 -p1 +%patch144 -p1 +%patch145 -p1 +%patch146 -p1 +%patch147 -p1 +%patch148 -p1 +%patch149 -p1 +%patch150 -p1 +%patch151 -p1 +%patch152 -p1 +%patch153 -p1 +%patch154 -p1 +%patch155 -p1 +%patch156 -p1 +%patch157 -p1 +%patch158 -p1 +%patch159 -p1 +%patch160 -p1 +%patch161 -p1 +%patch162 -p1 +%patch163 -p1 +%patch164 -p1 +%patch165 -p1 +%patch166 -p1 +%patch167 -p1 +%patch168 -p1 +%patch169 -p1 +%patch170 -p1 +%patch171 -p1 +%patch172 -p1 +%patch173 -p1 +%patch174 -p1 +%patch175 -p1 +%patch176 -p1 +%patch177 -p1 +%patch178 -p1 +%patch179 -p1 +%patch180 -p1 +%patch181 -p1 +%patch182 -p1 +%patch183 -p1 +%patch184 -p1 +%patch185 -p1 +%patch186 -p1 +%patch187 -p1 +%patch188 -p1 %build -namer=%{kern_devel_ver} -export RTE_KERNELDIR=/lib/modules/${namer}/build -export EXTRA_CFLAGS="-fstack-protector-strong" -make O=%{target} T=%{config} config -#make .so and .a libraries for spdk -sed -ri 's,(RTE_BUILD_BOTH_STATIC_AND_SHARED_LIBS=).*,\1y,' %{target}/.config -sed -ri 's,(CONFIG_RTE_LIB_LIBOS=).*,\1n,' %{target}/.config -sed -ri 's,(RTE_MACHINE=).*,\1%{machine},' %{target}/.config -sed -ri 's,(RTE_APP_TEST=).*,\1n,' %{target}/.config -sed -ri 's,(RTE_NEXT_ABI=).*,\1n,' %{target}/.config -sed -ri 's,(LIBRTE_VHOST=).*,\1y,' %{target}/.config -#sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,' %{target}/.config -make O=%{target} -j16 +%define debug_package %{nil} +meson %{target} -Ddisable_drivers=*/octeontx2 -Ddisable_drivers=*/fpga* -Ddisable_drivers=*/ifpga* -Denable_kmods=true +ninja -C %{target} %install namer=%{kern_devel_ver} -rm -rf %{buildroot} -make install O=%{target} RTE_KERNELDIR=/lib/modules/${namer}/build \ - kerneldir=/lib/modules/${namer}/extra/dpdk DESTDIR=%{buildroot} \ - prefix=%{_prefix} bindir=%{_bindir} sbindir=%{_sbindir} \ - includedir=%{_includedir}/dpdk libdir=%{_libdir} \ - datadir=%{_datadir}/dpdk docdir=%{_docdir}/dpdk +DESTDIR=$RPM_BUILD_ROOT/ meson install -C %{target} -mkdir -p $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_eal.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_mempool.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_ring.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_mempool_ring.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_pci.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_bus_pci.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_kvargs.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_acl.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_ethdev.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_mbuf.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_cmdline.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_net.so* $RPM_BUILD_ROOT/lib64/ -cp -ar ./%{target}/lib/librte_meter.so* $RPM_BUILD_ROOT/lib64/ - -#make O=%{target} doc - -mkdir -p $RPM_BUILD_ROOT/usr/include/%{name}-%{version}/ -ln -s /usr/share/dpdk/mk $RPM_BUILD_ROOT/usr/include/%{name}-%{version}/ -ln -s /usr/share/dpdk/%{target} $RPM_BUILD_ROOT/usr/include/%{name}-%{version}/ - -mkdir -p $RPM_BUILD_ROOT/usr/include/dpdk/ -ln -s /usr/share/dpdk/%{target} $RPM_BUILD_ROOT/usr/include/dpdk/ - -mkdir -p $RPM_BUILD_ROOT/usr/bin -cp ./%{target}/app/dpdk-pdump $RPM_BUILD_ROOT/usr/bin - -strip -g $RPM_BUILD_ROOT/lib/modules/${namer}/extra/dpdk/igb_uio.ko strip -g $RPM_BUILD_ROOT/lib/modules/${namer}/extra/dpdk/rte_kni.ko %define _unpackaged_files_terminate_build 0 %files -%dir %{_datadir}/dpdk -%{_datadir}/dpdk/usertools/*.py -%{_datadir}/dpdk/usertools/*.sh -%{_sbindir}/dpdk-devbind /lib/modules/%{kern_devel_ver}/extra/dpdk/* -/lib64/librte*.so* +/usr/local/bin/* +/usr/local/lib64/* %files devel -%{_includedir}/dpdk -%{_datadir}/dpdk/mk -%{_datadir}/dpdk/buildtools -%{_datadir}/dpdk/%{target} -%{_datadir}/dpdk/examples -%{_bindir}/* -%{_libdir}/* -%dir /usr/include/%{name}-%{version}/ -/usr/include/%{name}-%{version}/* -%dir /usr/include/dpdk/ -/usr/include/dpdk/* -%exclude /usr/bin/dpdk-pdump +/usr/local/include/* %files doc -#%doc %{_docdir}/dpdk - -%files tools -/usr/bin/dpdk-pdump +/usr/local/share/* %post /sbin/ldconfig @@ -229,47 +457,8 @@ strip -g $RPM_BUILD_ROOT/lib/modules/${namer}/extra/dpdk/rte_kni.ko /usr/sbin/depmod %changelog -* Tue Jun 08 2021 huangliming - 19.11-14 -- add gcc BuildRequires +* Mon Jun 21 2021 Min Hu - 20.11-1 +- support hns3 PMD for Kunpeng 920 and Kunpeng 930 -* Mon May 24 2021 renmingshuai - 19.11-13 -- optimize the efficiency of compiling dpdk - -* Mon May 24 2021 wutao - 19.11-12 -- add fstack-protector-strong gcc flags - -* Mon Apr 5 2021 wu-changsheng<851744572@qq.com> - 19.11-11 -- add support for gazelle - -* Thu Jan 28 2021 huangliming - 19.11-10 -- fix populate with small virtual chunks - -* Thu Jan 28 2021 huangliming - 19.11-9 --fix yum update dpdk-tools conflict with dpdk-devel - -* Thu Jan 28 2021 huangliming - 19.11-8 -- fix compilation error of max-inline-insns-single-o2 limit reached - -* Mon Dec 28 2020 huangliming - 19.11-7 --fix CVE-2020-14374 CVE-2020-14375 - -* Wed Nov 25 2020 chxssg - 19.11-6 --fix CVE-2020-14376 CVE-2020-14377 CVE-2020-14378 - -* Fri Nov 20 2020 seuzw<930zhaowei@163.com> - 19.11-5 --kni: fix build with Linux 5.6 and 5.9 - -* Wed Sep 23 2020 hubble_zhu - 19.11-4 --update pyelftools to python3-pyelftools - -* Tue Sep 22 2020 hubble_zhu - 19.11-3 --add requires for dpdk-pmdinfo - -* Thu Sep 3 2020 zhaowei - 19.11-2 --update source URL - -* Wed May 27 2020 chenxiang - 19.11-1 --fix CVE-2020-10722 CVE-2020-10723 CVE-2020-10724 CVE-2020-10725 - -* Wed May 27 2020 openEuler dpdk version-release +* Wed Jun 16 2021 openEuler dpdk version-release -first package diff --git a/fix-compilation-error-of-max-inline-insns-single-o2-.patch b/fix-compilation-error-of-max-inline-insns-single-o2-.patch deleted file mode 100644 index 4904ef5..0000000 --- a/fix-compilation-error-of-max-inline-insns-single-o2-.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f3d569535f34bb5983c325757941b5565364017f Mon Sep 17 00:00:00 2001 -From: LemmyHuang -Date: Thu, 28 Jan 2021 08:34:33 +0000 -Subject: [PATCH] fix compilation error of max-inline-insns-single-o2 limit - reached - -Signed-off-by: LemmyHuang ---- - kernel/linux/igb_uio/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/linux/igb_uio/Makefile b/kernel/linux/igb_uio/Makefile -index f83bcc7..4c69f5d 100644 ---- a/kernel/linux/igb_uio/Makefile -+++ b/kernel/linux/igb_uio/Makefile -@@ -14,7 +14,7 @@ MODULE_PATH = drivers/net/igb_uio - # - MODULE_CFLAGS += -I$(SRCDIR) --param max-inline-insns-single=100 - MODULE_CFLAGS += -I$(RTE_OUTPUT)/include --MODULE_CFLAGS += -Winline -Wall -Werror -+MODULE_CFLAGS += -Winline -Wall - MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h - - # --- -2.23.0 - diff --git a/fix-pool-allocation.patch b/fix-pool-allocation.patch deleted file mode 100644 index 648bbee..0000000 --- a/fix-pool-allocation.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3f2635c5a9c3df4ba7cc0d6598a2023569ca3d39 Mon Sep 17 00:00:00 2001 -From: Fan Zhang -Date: Tue, 14 Apr 2020 16:19:51 +0100 -Subject: vhost/crypto: fix pool allocation - -This patch fixes the missing iv space allocation in crypto -operation mempool. - -Fixes: 709521f4c2cd ("examples/vhost_crypto: support multi-core") -Cc: stable@dpdk.org - -Signed-off-by: Fan Zhang -Acked-by: Chenbo Xia ---- - examples/vhost_crypto/main.c | 2 +- - lib/librte_vhost/rte_vhost_crypto.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c -index 1d7ba94..11b022e 100644 ---- a/examples/vhost_crypto/main.c -+++ b/examples/vhost_crypto/main.c -@@ -544,7 +544,7 @@ main(int argc, char *argv[]) - snprintf(name, 127, "COPPOOL_%u", lo->lcore_id); - info->cop_pool = rte_crypto_op_pool_create(name, - RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS, -- NB_CACHE_OBJS, 0, -+ NB_CACHE_OBJS, VHOST_CRYPTO_MAX_IV_LEN, - rte_lcore_to_socket_id(lo->lcore_id)); - - if (!info->cop_pool) { -diff --git a/lib/librte_vhost/rte_vhost_crypto.h b/lib/librte_vhost/rte_vhost_crypto.h -index d29871c..866a592 100644 ---- a/lib/librte_vhost/rte_vhost_crypto.h -+++ b/lib/librte_vhost/rte_vhost_crypto.h -@@ -10,6 +10,7 @@ - #define VHOST_CRYPTO_SESSION_MAP_ENTRIES (1024) /**< Max nb sessions */ - /** max nb virtual queues in a burst for finalizing*/ - #define VIRTIO_CRYPTO_MAX_NUM_BURST_VQS (64) -+#define VHOST_CRYPTO_MAX_IV_LEN (32) - - enum rte_vhost_crypto_zero_copy { - RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE = 0, --- -cgit v1.0 diff --git a/fix-populate-with-small-virtual-chunks.patch b/fix-populate-with-small-virtual-chunks.patch deleted file mode 100644 index 95933a3..0000000 --- a/fix-populate-with-small-virtual-chunks.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 43503c59adee6cae7069da23e105c24e044bf72c Mon Sep 17 00:00:00 2001 -From: Olivier Matz -Date: Fri, 17 Jan 2020 15:57:52 +0100 -Subject: mempool: fix populate with small virtual chunks - -To populate a mempool with a virtual area, the mempool code calls -rte_mempool_populate_iova() for each iova-contiguous area. It happens -(rarely) that this area is too small to store one object. In this case, -rte_mempool_populate_iova() returns an error, which is forwarded by -rte_mempool_populate_virt(). - -This case should not throw an error in rte_mempool_populate_virt(). -Instead, the area that is too small should just be ignored. - -To fix this issue, change the return value of -rte_mempool_populate_iova() to 0 when no object can be populated, -so it can be ignored by the caller. As this would be an API/ABI change, -only do this modification internally for now. - -Fixes: 354788b60cfd ("mempool: allow populating with unaligned virtual area") -Cc: stable@dpdk.org - -Signed-off-by: Olivier Matz -Tested-by: Anatoly Burakov -Tested-by: Alvin Zhang - -Conflict:NA -Reference:http://git.dpdk.org/dpdk/patch/?id=43503c59adee6cae7069da23e105c24e044bf72c -Signed-off-by:wuchangsheng ---- - lib/librte_mempool/rte_mempool.c | 30 +++++++++++++++++++++++++----- - 1 file changed, 25 insertions(+), 5 deletions(-) - -diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c -index aea5972..08906df 100644 ---- a/lib/librte_mempool/rte_mempool.c -+++ b/lib/librte_mempool/rte_mempool.c -@@ -297,8 +297,8 @@ mempool_ops_alloc_once(struct rte_mempool *mp) - * zone. Return the number of objects added, or a negative value - * on error. - */ --int --rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, -+static int -+__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, - rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb, - void *opaque) - { -@@ -332,7 +332,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, - off = RTE_PTR_ALIGN_CEIL(vaddr, RTE_MEMPOOL_ALIGN) - vaddr; - - if (off > len) { -- ret = -EINVAL; -+ ret = 0; - goto fail; - } - -@@ -343,7 +343,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, - - /* not enough room to store one object */ - if (i == 0) { -- ret = -EINVAL; -+ ret = 0; - goto fail; - } - -@@ -356,6 +356,21 @@ fail: - return ret; - } - -+int -+rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, -+ rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb, -+ void *opaque) -+{ -+ int ret; -+ -+ ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb, -+ opaque); -+ if (ret == 0) -+ ret = -EINVAL; -+ -+ return ret; -+} -+ - static rte_iova_t - get_iova(void *addr) - { -@@ -406,8 +421,10 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, - break; - } - -- ret = rte_mempool_populate_iova(mp, addr + off, iova, -+ ret = __rte_mempool_populate_iova(mp, addr + off, iova, - phys_len, free_cb, opaque); -+ if (ret == 0) -+ continue; - if (ret < 0) - goto fail; - /* no need to call the free callback for next chunks */ -@@ -415,6 +432,9 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, - cnt += ret; - } - -+ if (cnt == 0) -+ return -EINVAL; -+ - return cnt; - - fail: --- -cgit v1.0 diff --git a/kni-fix-build-with-Linux-5.6.patch b/kni-fix-build-with-Linux-5.6.patch deleted file mode 100644 index 1f4785a..0000000 --- a/kni-fix-build-with-Linux-5.6.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Ferruh Yigit -Date: Wed, 12 Feb 2020 17:14:24 +0000 -Message-Id: <20200212171424.695556-1-ferruh.yigit@intel.com> -Subject: [dpdk-dev] [PATCH] kni: fix build with Linux 5.6 - -With the following Linux commit a new parameter 'txqueue' has been added -to 'ndo_tx_timeout' ndo: -commit 0290bd291cc0 ("netdev: pass the stuck queue to the timeout handler") - -The change reflected to the KNI with version check. - -Signed-off-by: Ferruh Yigit -Acked-by: David Marchand ---- - kernel/linux/kni/compat.h | 4 ++++ - kernel/linux/kni/kni_net.c | 5 +++++ - 2 files changed, 9 insertions(+) - -diff --git a/kernel/linux/kni/compat.h b/kernel/linux/kni/compat.h -index 7109474ec..9ee45dbf6 100644 ---- a/kernel/linux/kni/compat.h -+++ b/kernel/linux/kni/compat.h -@@ -130,3 +130,7 @@ - #if KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE - #define HAVE_IOVA_TO_KVA_MAPPING_SUPPORT - #endif -+ -+#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE -+#define HAVE_TX_TIMEOUT_TXQUEUE -+#endif -diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c -index 97fe85be9..c82c881a2 100644 ---- a/kernel/linux/kni/kni_net.c -+++ b/kernel/linux/kni/kni_net.c -@@ -623,8 +623,13 @@ kni_net_rx(struct kni_dev *kni) - /* - * Deal with a transmit timeout. - */ -+#ifdef HAVE_TX_TIMEOUT_TXQUEUE -+static void -+kni_net_tx_timeout(struct net_device *dev, unsigned int txqueue) -+#else - static void - kni_net_tx_timeout(struct net_device *dev) -+#endif - { - pr_debug("Transmit timeout at %ld, latency %ld\n", jiffies, - jiffies - dev_trans_start(dev)); diff --git a/v2-kni-fix-build-with-Linux-5.9.patch b/v2-kni-fix-build-with-Linux-5.9.patch deleted file mode 100644 index b2ac953..0000000 --- a/v2-kni-fix-build-with-Linux-5.9.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Ferruh Yigit -Date: Mon, 17 Aug 2020 11:32:47 +0100 -Message-Id: <20200817103247.1564204-1-ferruh.yigit@intel.com> -Subject: [dpdk-dev] [PATCH v2] kni: fix build with Linux 5.9 - -Starting from Linux 5.9 'get_user_pages_remote()' API doesn't get -'struct task_struct' parameter: -commit 64019a2e467a ("mm/gup: remove task_struct pointer for all gup code") - -The change reflected to the KNI with version check. - -Signed-off-by: Ferruh Yigit ---- -v2: -* Add stable tag to request backport. ---- - kernel/linux/kni/compat.h | 4 ++++ - kernel/linux/kni/kni_dev.h | 5 +++++ - 2 files changed, 9 insertions(+) - -diff --git a/kernel/linux/kni/compat.h b/kernel/linux/kni/compat.h -index 9ee45dbf6f..d515b27669 100644 ---- a/kernel/linux/kni/compat.h -+++ b/kernel/linux/kni/compat.h -@@ -134,3 +134,7 @@ - #if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE - #define HAVE_TX_TIMEOUT_TXQUEUE - #endif -+ -+#if KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE -+#define HAVE_TSK_IN_GUP -+#endif -diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h -index ca5f92a47b..c15da311ba 100644 ---- a/kernel/linux/kni/kni_dev.h -+++ b/kernel/linux/kni/kni_dev.h -@@ -101,8 +101,13 @@ static inline phys_addr_t iova_to_phys(struct task_struct *tsk, - offset = iova & (PAGE_SIZE - 1); - - /* Read one page struct info */ -+#ifdef HAVE_TSK_IN_GUP - ret = get_user_pages_remote(tsk, tsk->mm, iova, 1, - FOLL_TOUCH, &page, NULL, NULL); -+#else -+ ret = get_user_pages_remote(tsk->mm, iova, 1, -+ FOLL_TOUCH, &page, NULL, NULL); -+#endif - if (ret < 0) - return 0; - -