From 087fa3439ff2f5d9592a4eb393ce529095d44d04 Mon Sep 17 00:00:00 2001 From: speech_white Date: Tue, 31 Aug 2021 08:30:22 +0800 Subject: [PATCH] support set link up/down for PF Signed-off-by: speech_white --- ...tart-stop-Tx-datapath-request-for-MP.patch | 188 ++++++++++++ ...hns3-support-set-link-up-down-for-PF.patch | 287 ++++++++++++++++++ dpdk.spec | 7 +- 3 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 0215-net-hns3-add-start-stop-Tx-datapath-request-for-MP.patch create mode 100644 0216-net-hns3-support-set-link-up-down-for-PF.patch diff --git a/0215-net-hns3-add-start-stop-Tx-datapath-request-for-MP.patch b/0215-net-hns3-add-start-stop-Tx-datapath-request-for-MP.patch new file mode 100644 index 0000000..386f8e8 --- /dev/null +++ b/0215-net-hns3-add-start-stop-Tx-datapath-request-for-MP.patch @@ -0,0 +1,188 @@ +From 15c150affb3d486df5e7a4ab55e3ed1cdf8504ef Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Mon, 26 Jul 2021 18:59:39 +0800 +Subject: [PATCH] net/hns3: add start/stop Tx datapath request for MP + +Currently, hns3 PMD has supported start/stop RxTx datapath request message +between the primary and secondary processes. However, there are some cases +only to start/stop Tx datapath. This patch adds start/stop Tx datapath +request for MP. + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.h | 4 +++- + drivers/net/hns3/hns3_mp.c | 50 ++++++++++++++++++++++++++++++++++-------- + drivers/net/hns3/hns3_mp.h | 3 +++ + drivers/net/hns3/hns3_rxtx.c | 4 ++-- + drivers/net/hns3/hns3_rxtx.h | 6 +++++ + 5 files changed, 55 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 8e66d9f..2e48ff6 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -699,7 +699,9 @@ struct hns3_vtag_cfg { + /* Request types for IPC. */ + enum hns3_mp_req_type { + HNS3_MP_REQ_START_RXTX = 1, +- HNS3_MP_REQ_STOP_RXTX, ++ HNS3_MP_REQ_STOP_RXTX = 2, ++ HNS3_MP_REQ_START_TX = 3, ++ HNS3_MP_REQ_STOP_TX = 4, + HNS3_MP_REQ_MAX + }; + +diff --git a/drivers/net/hns3/hns3_mp.c b/drivers/net/hns3/hns3_mp.c +index a8485f5..cd514ac 100644 +--- a/drivers/net/hns3/hns3_mp.c ++++ b/drivers/net/hns3/hns3_mp.c +@@ -73,6 +73,7 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + struct hns3_mp_param *res = (struct hns3_mp_param *)mp_res.param; + const struct hns3_mp_param *param = + (const struct hns3_mp_param *)mp_msg->param; ++ eth_tx_prep_t prep = NULL; + struct rte_eth_dev *dev; + int ret; + +@@ -87,19 +88,23 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + PMD_INIT_LOG(INFO, "port %u starting datapath", + dev->data->port_id); + 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); + break; + case HNS3_MP_REQ_STOP_RXTX: + PMD_INIT_LOG(INFO, "port %u stopping datapath", + dev->data->port_id); + 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); ++ break; ++ case HNS3_MP_REQ_START_TX: ++ PMD_INIT_LOG(INFO, "port %u starting Tx datapath", ++ dev->data->port_id); ++ dev->tx_pkt_burst = hns3_get_tx_function(dev, &prep); ++ dev->tx_pkt_prepare = prep; ++ break; ++ case HNS3_MP_REQ_STOP_TX: ++ PMD_INIT_LOG(INFO, "port %u stopping Tx datapath", ++ dev->data->port_id); ++ dev->tx_pkt_burst = hns3_dummy_rxtx_burst; ++ dev->tx_pkt_prepare = NULL; + break; + default: + rte_errno = EINVAL; +@@ -107,9 +112,24 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + dev->data->port_id); + return -rte_errno; + } ++ ++ rte_mb(); ++ mp_init_msg(dev, &mp_res, param->type); ++ res->result = 0; ++ ret = rte_mp_reply(&mp_res, peer); ++ + return ret; + } + ++static bool ++mp_req_type_is_valid(enum hns3_mp_req_type type) ++{ ++ return type == HNS3_MP_REQ_START_RXTX || ++ type == HNS3_MP_REQ_STOP_RXTX || ++ type == HNS3_MP_REQ_START_TX || ++ type == HNS3_MP_REQ_STOP_TX; ++} ++ + /* + * Broadcast request of stopping/starting data-path to secondary processes. + * +@@ -132,7 +152,7 @@ mp_req_on_rxtx(struct rte_eth_dev *dev, enum hns3_mp_req_type type) + + 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) { ++ if (!mp_req_type_is_valid(type)) { + hns3_err(hw, "port %u unknown request (req_type %d)", + dev->data->port_id, type); + return; +@@ -189,6 +209,18 @@ void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev) + mp_req_on_rxtx(dev, HNS3_MP_REQ_STOP_RXTX); + } + ++void ++hns3_mp_req_stop_tx(struct rte_eth_dev *dev) ++{ ++ mp_req_on_rxtx(dev, HNS3_MP_REQ_STOP_TX); ++} ++ ++void ++hns3_mp_req_start_tx(struct rte_eth_dev *dev) ++{ ++ mp_req_on_rxtx(dev, HNS3_MP_REQ_START_TX); ++} ++ + /* + * Initialize by primary process. + */ +diff --git a/drivers/net/hns3/hns3_mp.h b/drivers/net/hns3/hns3_mp.h +index 1a73598..e0e4aea 100644 +--- a/drivers/net/hns3/hns3_mp.h ++++ b/drivers/net/hns3/hns3_mp.h +@@ -7,6 +7,9 @@ + + void hns3_mp_req_start_rxtx(struct rte_eth_dev *dev); + void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev); ++void hns3_mp_req_start_tx(struct rte_eth_dev *dev); ++void hns3_mp_req_stop_tx(struct rte_eth_dev *dev); ++ + int hns3_mp_init_primary(void); + void hns3_mp_uninit_primary(void); + int hns3_mp_init_secondary(void); +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index d3fbe08..7d8176f 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -4309,7 +4309,7 @@ hns3_get_tx_prep_needed(struct rte_eth_dev *dev) + #endif + } + +-static eth_tx_burst_t ++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; +@@ -4346,7 +4346,7 @@ hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep) + return hns3_xmit_pkts; + } + +-static uint16_t ++uint16_t + hns3_dummy_rxtx_burst(void *dpdk_txq __rte_unused, + struct rte_mbuf **pkts __rte_unused, + uint16_t pkts_n __rte_unused) +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 56c1b80..141de7a 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -729,6 +729,12 @@ 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); ++eth_tx_burst_t hns3_get_tx_function(struct rte_eth_dev *dev, ++ eth_tx_prep_t *prep); ++uint16_t hns3_dummy_rxtx_burst(void *dpdk_txq __rte_unused, ++ struct rte_mbuf **pkts __rte_unused, ++ uint16_t pkts_n __rte_unused); ++ + 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); +-- +2.7.4 + diff --git a/0216-net-hns3-support-set-link-up-down-for-PF.patch b/0216-net-hns3-support-set-link-up-down-for-PF.patch new file mode 100644 index 0000000..e760176 --- /dev/null +++ b/0216-net-hns3-support-set-link-up-down-for-PF.patch @@ -0,0 +1,287 @@ +From 0a3e6a5d6e2ab6eec0a16db1d5d5f5d0b75bcf8b Mon Sep 17 00:00:00 2001 +From: Huisong Li +Date: Mon, 26 Jul 2021 18:59:40 +0800 +Subject: [PATCH] net/hns3: support set link up/down for PF + +This patch adds set link up/down feature. RxTx datapath and link status +will be disabled when dev_set_link_down() is called, and can be enabled by +dev_start() or dev_set_link_up(). + +Signed-off-by: Huisong Li +Signed-off-by: Min Hu (Connor) +--- + drivers/net/hns3/hns3_ethdev.c | 107 ++++++++++++++++++++++++++++++++++++++--- + drivers/net/hns3/hns3_ethdev.h | 11 +++-- + drivers/net/hns3/hns3_rxtx.c | 28 ++++++++++- + drivers/net/hns3/hns3_rxtx.h | 2 + + 4 files changed, 138 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index a374fa7..7d37004 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -103,6 +103,7 @@ 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); ++static int hns3_cfg_mac_mode(struct hns3_hw *hw, bool enable); + + void hns3_ether_format_addr(char *buf, uint16_t size, + const struct rte_ether_addr *ether_addr) +@@ -2924,6 +2925,88 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete) + } + + static int ++hns3_dev_set_link_up(struct rte_eth_dev *dev) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ /* ++ * The "tx_pkt_burst" will be restored. But the secondary process does ++ * not support the mechanism for notifying the primary process. ++ */ ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ hns3_err(hw, "secondary process does not support to set link up."); ++ return -ENOTSUP; ++ } ++ ++ /* ++ * If device isn't started Rx/Tx function is still disabled, setting ++ * link up is not allowed. But it is probably better to return success ++ * to reduce the impact on the upper layer. ++ */ ++ if (hw->adapter_state != HNS3_NIC_STARTED) { ++ hns3_info(hw, "device isn't started, can't set link up."); ++ return 0; ++ } ++ ++ if (!hw->set_link_down) ++ return 0; ++ ++ rte_spinlock_lock(&hw->lock); ++ ret = hns3_cfg_mac_mode(hw, true); ++ if (ret) { ++ rte_spinlock_unlock(&hw->lock); ++ hns3_err(hw, "failed to set link up, ret = %d", ret); ++ return ret; ++ } ++ ++ hw->set_link_down = false; ++ hns3_start_tx_datapath(dev); ++ rte_spinlock_unlock(&hw->lock); ++ ++ return 0; ++} ++ ++static int ++hns3_dev_set_link_down(struct rte_eth_dev *dev) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ int ret; ++ ++ /* ++ * The "tx_pkt_burst" will be set to dummy function. But the secondary ++ * process does not support the mechanism for notifying the primary ++ * process. ++ */ ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ hns3_err(hw, "secondary process does not support to set link down."); ++ return -ENOTSUP; ++ } ++ ++ /* ++ * If device isn't started or the API has been called, link status is ++ * down, return success. ++ */ ++ if (hw->adapter_state != HNS3_NIC_STARTED || hw->set_link_down) ++ return 0; ++ ++ rte_spinlock_lock(&hw->lock); ++ hns3_stop_tx_datapath(dev); ++ ret = hns3_cfg_mac_mode(hw, false); ++ if (ret) { ++ hns3_start_tx_datapath(dev); ++ rte_spinlock_unlock(&hw->lock); ++ hns3_err(hw, "failed to set link down, ret = %d", ret); ++ return ret; ++ } ++ ++ hw->set_link_down = true; ++ rte_spinlock_unlock(&hw->lock); ++ ++ return 0; ++} ++ ++static int + hns3_parse_func_status(struct hns3_hw *hw, struct hns3_func_status_cmd *status) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +@@ -5576,6 +5659,7 @@ static int + hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + { + struct hns3_hw *hw = &hns->hw; ++ bool link_en; + int ret; + + ret = hns3_update_queue_map_configure(hns); +@@ -5600,7 +5684,8 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) + return ret; + } + +- ret = hns3_cfg_mac_mode(hw, true); ++ link_en = hw->set_link_down ? false : true; ++ ret = hns3_cfg_mac_mode(hw, link_en); + if (ret) { + PMD_INIT_LOG(ERR, "failed to enable MAC, ret = %d", ret); + goto err_config_mac_mode; +@@ -5731,6 +5816,7 @@ hns3_dev_start(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; ++ bool old_state = hw->set_link_down; + int ret; + + PMD_INIT_FUNC_TRACE(); +@@ -5740,12 +5826,17 @@ hns3_dev_start(struct rte_eth_dev *dev) + rte_spinlock_lock(&hw->lock); + hw->adapter_state = HNS3_NIC_STARTING; + ++ /* ++ * If the dev_set_link_down() API has been called, the "set_link_down" ++ * flag can be cleared by dev_start() API. In addition, the flag should ++ * also be cleared before calling hns3_do_start() so that MAC can be ++ * enabled in dev_start stage. ++ */ ++ hw->set_link_down = false; + ret = hns3_do_start(hns, true); +- if (ret) { +- hw->adapter_state = HNS3_NIC_CONFIGURED; +- rte_spinlock_unlock(&hw->lock); +- return ret; +- } ++ if (ret) ++ goto do_start_fail; ++ + ret = hns3_map_rx_interrupt(dev); + if (ret) + goto map_rx_inter_err; +@@ -5801,6 +5892,8 @@ hns3_dev_start(struct rte_eth_dev *dev) + hns3_stop_all_txqs(dev); + map_rx_inter_err: + (void)hns3_do_stop(hns); ++do_start_fail: ++ hw->set_link_down = old_state; + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + +@@ -7345,6 +7438,8 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { + .mac_addr_set = hns3_set_default_mac_addr, + .set_mc_addr_list = hns3_set_mc_mac_addr_list, + .link_update = hns3_dev_link_update, ++ .dev_set_link_up = hns3_dev_set_link_up, ++ .dev_set_link_down = hns3_dev_set_link_down, + .rss_hash_update = hns3_dev_rss_hash_update, + .rss_hash_conf_get = hns3_dev_rss_hash_conf_get, + .reta_update = hns3_dev_rss_reta_update, +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index 2e48ff6..0e4e426 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -481,6 +481,11 @@ struct hns3_hw { + struct hns3_cmq cmq; + struct hns3_mbx_resp_status mbx_resp; /* mailbox response */ + struct hns3_mac mac; ++ /* ++ * This flag indicates dev_set_link_down() API is called, and is cleared ++ * by dev_set_link_up() or dev_start(). ++ */ ++ bool set_link_down; + unsigned int secondary_cnt; /* Number of secondary processes init'd. */ + struct hns3_tqp_stats tqp_stats; + /* Include Mac stats | Rx stats | Tx stats */ +@@ -699,9 +704,9 @@ struct hns3_vtag_cfg { + /* Request types for IPC. */ + enum hns3_mp_req_type { + HNS3_MP_REQ_START_RXTX = 1, +- HNS3_MP_REQ_STOP_RXTX = 2, +- HNS3_MP_REQ_START_TX = 3, +- HNS3_MP_REQ_STOP_TX = 4, ++ HNS3_MP_REQ_STOP_RXTX, ++ HNS3_MP_REQ_START_TX, ++ HNS3_MP_REQ_STOP_TX, + HNS3_MP_REQ_MAX + }; + +diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c +index 7d8176f..0f222b3 100644 +--- a/drivers/net/hns3/hns3_rxtx.c ++++ b/drivers/net/hns3/hns3_rxtx.c +@@ -20,6 +20,7 @@ + #include "hns3_rxtx.h" + #include "hns3_regs.h" + #include "hns3_logs.h" ++#include "hns3_mp.h" + + #define HNS3_CFG_DESC_NUM(num) ((num) / 8 - 1) + #define HNS3_RX_RING_PREFETCTH_MASK 3 +@@ -4372,6 +4373,7 @@ hns3_trace_rxtx_function(struct rte_eth_dev *dev) + + void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + { ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + struct hns3_adapter *hns = eth_dev->data->dev_private; + eth_tx_prep_t prep = NULL; + +@@ -4379,7 +4381,9 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + __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_burst = hw->set_link_down ? ++ hns3_dummy_rxtx_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); +@@ -4703,3 +4707,25 @@ hns3_enable_rxd_adv_layout(struct hns3_hw *hw) + if (hns3_dev_rxd_adv_layout_supported(hw)) + hns3_write_dev(hw, HNS3_RXD_ADV_LAYOUT_EN_REG, 1); + } ++ ++void ++hns3_stop_tx_datapath(struct rte_eth_dev *dev) ++{ ++ dev->tx_pkt_burst = hns3_dummy_rxtx_burst; ++ dev->tx_pkt_prepare = NULL; ++ rte_wmb(); ++ /* Disable tx datapath on secondary process. */ ++ hns3_mp_req_stop_tx(dev); ++ /* Prevent crashes when queues are still in use. */ ++ rte_delay_ms(dev->data->nb_tx_queues); ++} ++ ++void ++hns3_start_tx_datapath(struct rte_eth_dev *dev) ++{ ++ eth_tx_prep_t prep = NULL; ++ ++ dev->tx_pkt_burst = hns3_get_tx_function(dev, &prep); ++ dev->tx_pkt_prepare = prep; ++ hns3_mp_req_start_tx(dev); ++} +diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h +index 141de7a..cd7c21c 100644 +--- a/drivers/net/hns3/hns3_rxtx.h ++++ b/drivers/net/hns3/hns3_rxtx.h +@@ -766,5 +766,7 @@ 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); + void hns3_tx_push_init(struct rte_eth_dev *dev); ++void hns3_stop_tx_datapath(struct rte_eth_dev *dev); ++void hns3_start_tx_datapath(struct rte_eth_dev *dev); + + #endif /* _HNS3_RXTX_H_ */ +-- +2.7.4 + diff --git a/dpdk.spec b/dpdk.spec index fe4521f..8c76981 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 20.11 -Release: 8 +Release: 9 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 20.11 @@ -221,6 +221,8 @@ Patch211: 0211-net-hns3-disable-PFC-if-not-configured.patch Patch212: 0212-net-hns3-use-the-correct-HiSilicon-copyright.patch Patch213: 0213-app-testpmd-change-port-link-speed-without-stopping-.patch Patch214: 0214-ethdev-add-dev-configured-flag.patch +Patch215: 0215-net-hns3-add-start-stop-Tx-datapath-request-for-MP.patch +Patch216: 0216-net-hns3-support-set-link-up-down-for-PF.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -346,6 +348,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/${namer}/extra/dpdk/rte_kni.ko /usr/sbin/depmod %changelog +* Tur Aug 30 2021 Min Hu - 20.11-9 +- support link up/down for PF in hns3 PMD + * Tur Jul 29 2021 Min Hu - 20.11-8 - add lib and testpmd functions to sync upstream -- Gitee