From 23d5fee348d4c7c6c6df5c4557e1c416f1545e4b Mon Sep 17 00:00:00 2001 From: Rahul Lakkireddy Date: Tue, 16 Mar 2021 03:21:46 +0530 Subject: [PATCH] net/cxgbe: disable Rx during port link down When link goes down, disable the port's Rx path to drop the incoming traffic closer to the wire, instead of accepting them in for further Rx processing, only to eventually drop them at the port's RxQs. This prevents unnecessary congestion in the Rx path. The port's Rx path will be re-enabled once the link up event is received in the firmware event queue. Signed-off-by: Rahul Lakkireddy --- doc/guides/nics/cxgbe.rst | 14 +++---- drivers/net/cxgbe/base/adapter.h | 4 ++ drivers/net/cxgbe/base/common.h | 1 + drivers/net/cxgbe/base/t4_hw.c | 1 + drivers/net/cxgbe/base/t4fw_interface.h | 1 + drivers/net/cxgbe/cxgbe_main.c | 52 +++++++++++++++++++++---- 6 files changed, 58 insertions(+), 15 deletions(-) diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst index 4b9913669b..4a8fef07b8 100644 --- a/doc/guides/nics/cxgbe.rst +++ b/doc/guides/nics/cxgbe.rst @@ -70,7 +70,7 @@ in :ref:`t5-nics` and :ref:`t6-nics`. Prerequisites ------------- -- Requires firmware version **1.24.17.0** and higher. Visit +- Requires firmware version **1.25.4.0** and higher. Visit `Chelsio Download Center `_ to get latest firmware bundled with the latest Chelsio Unified Wire package. @@ -404,7 +404,7 @@ Unified Wire package for Linux operating system are as follows: .. code-block:: console - firmware-version: 1.24.17.0, TP 0.1.23.2 + firmware-version: 1.25.4.0, TP 0.1.23.2 Running testpmd ~~~~~~~~~~~~~~~ @@ -462,7 +462,7 @@ devices managed by librte_net_cxgbe in Linux operating system. EAL: PCI memory mapped at 0x7fd7c0200000 EAL: PCI memory mapped at 0x7fd77cdfd000 EAL: PCI memory mapped at 0x7fd7c10b7000 - PMD: rte_cxgbe_pmd: fw: 1.24.17.0, TP: 0.1.23.2 + PMD: rte_cxgbe_pmd: fw: 1.25.4.0, TP: 0.1.23.2 PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter Interactive-mode selected Configuring Port 0 (socket 0) @@ -568,7 +568,7 @@ virtual functions. [...] EAL: PCI device 0000:02:01.0 on NUMA socket 0 EAL: probe driver: 1425:5803 net_cxgbevf - PMD: rte_cxgbe_pmd: Firmware version: 1.24.17.0 + PMD: rte_cxgbe_pmd: Firmware version: 1.25.4.0 PMD: rte_cxgbe_pmd: TP Microcode version: 0.1.23.2 PMD: rte_cxgbe_pmd: Chelsio rev 0 PMD: rte_cxgbe_pmd: No bootstrap loaded @@ -576,7 +576,7 @@ virtual functions. PMD: rte_cxgbe_pmd: 0000:02:01.0 Chelsio rev 0 1G/10GBASE-SFP EAL: PCI device 0000:02:01.1 on NUMA socket 0 EAL: probe driver: 1425:5803 net_cxgbevf - PMD: rte_cxgbe_pmd: Firmware version: 1.24.17.0 + PMD: rte_cxgbe_pmd: Firmware version: 1.25.4.0 PMD: rte_cxgbe_pmd: TP Microcode version: 0.1.23.2 PMD: rte_cxgbe_pmd: Chelsio rev 0 PMD: rte_cxgbe_pmd: No bootstrap loaded @@ -654,7 +654,7 @@ Unified Wire package for FreeBSD operating system are as follows: .. code-block:: console - dev.t5nex.0.firmware_version: 1.24.17.0 + dev.t5nex.0.firmware_version: 1.25.4.0 Running testpmd ~~~~~~~~~~~~~~~ @@ -772,7 +772,7 @@ devices managed by librte_net_cxgbe in FreeBSD operating system. EAL: PCI memory mapped at 0x8007ec000 EAL: PCI memory mapped at 0x842800000 EAL: PCI memory mapped at 0x80086c000 - PMD: rte_cxgbe_pmd: fw: 1.24.17.0, TP: 0.1.23.2 + PMD: rte_cxgbe_pmd: fw: 1.25.4.0, TP: 0.1.23.2 PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter Interactive-mode selected Configuring Port 0 (socket 0) diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h index a5a3313c25..01a2a9d147 100644 --- a/drivers/net/cxgbe/base/adapter.h +++ b/drivers/net/cxgbe/base/adapter.h @@ -58,6 +58,9 @@ struct port_info { */ u8 vin; u8 vivld; + + u8 vi_en_rx; /* Enable/disable VI Rx */ + u8 vi_en_tx; /* Enable/disable VI Tx */ }; enum { /* adapter flags */ @@ -792,6 +795,7 @@ void t4_free_mem(void *addr); #define t4_os_free(_ptr) t4_free_mem((_ptr)) void t4_os_portmod_changed(const struct adapter *adap, int port_id); +void t4_os_link_changed(struct adapter *adap, int port_id); void reclaim_completed_tx(struct sge_txq *q); void t4_free_sge_resources(struct adapter *adap); diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h index ab100d784c..2f8569cbbc 100644 --- a/drivers/net/cxgbe/base/common.h +++ b/drivers/net/cxgbe/base/common.h @@ -265,6 +265,7 @@ struct adapter_params { u8 filter2_wr_support; /* FW support for FILTER2_WR */ u32 viid_smt_extn_support:1; /* FW returns vin and smt index */ u32 max_tx_coalesce_num; /* Max # of Tx packets that can be coalesced */ + u8 vi_enable_rx; /* FW support for enable/disable VI Rx at runtime */ }; /* Firmware Port Capabilities types. diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c index 0e3033b550..7ebf4a9a70 100644 --- a/drivers/net/cxgbe/base/t4_hw.c +++ b/drivers/net/cxgbe/base/t4_hw.c @@ -4595,6 +4595,7 @@ static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) lc->link_ok = link_ok; lc->acaps = acaps; lc->link_caps = link_caps; + t4_os_link_changed(adapter, pi->pidx); } if (mod_changed) { diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h index 240e0ee49d..0310a7ce8b 100644 --- a/drivers/net/cxgbe/base/t4fw_interface.h +++ b/drivers/net/cxgbe/base/t4fw_interface.h @@ -702,6 +702,7 @@ enum fw_params_param_dev { FW_PARAMS_PARAM_DEV_OPAQUE_VIID_SMT_EXTN = 0x27, FW_PARAMS_PARAM_DEV_HASHFILTER_WITH_OFLD = 0x28, FW_PARAMS_PARAM_DEV_FILTER = 0x2E, + FW_PARAMS_PARAM_DEV_VI_ENABLE_INGRESS_AFTER_LINKUP = 0x32, }; /* diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c index 83ad758e88..c759d97f8c 100644 --- a/drivers/net/cxgbe/cxgbe_main.c +++ b/drivers/net/cxgbe/cxgbe_main.c @@ -1496,6 +1496,10 @@ static int adap_init0(struct adapter *adap) else adap->params.max_tx_coalesce_num = ETH_COALESCE_PKT_NUM; + params[0] = CXGBE_FW_PARAM_DEV(VI_ENABLE_INGRESS_AFTER_LINKUP); + ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, params, val); + adap->params.vi_enable_rx = (ret == 0 && val[0] != 0); + /* * The MTU/MSS Table is initialized by now, so load their values. If * we're initializing the adapter, then we'll make any modifications @@ -1594,6 +1598,33 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id) pi->port_id, pi->link_cfg.mod_type); } +void t4_os_link_changed(struct adapter *adap, int port_id) +{ + struct port_info *pi = adap2pinfo(adap, port_id); + + /* If link status has not changed or if firmware doesn't + * support enabling/disabling VI's Rx path during runtime, + * then return. + */ + if (adap->params.vi_enable_rx == 0 || + pi->vi_en_rx == pi->link_cfg.link_ok) + return; + + /* Don't enable VI Rx path, if link has been administratively + * turned off. + */ + if (pi->vi_en_tx == 0 && pi->vi_en_rx == 0) + return; + + /* When link goes down, disable the port's Rx path to drop + * Rx traffic closer to the wire, instead of processing it + * further in the Rx pipeline. The Rx path will be re-enabled + * once the link up message comes in firmware event queue. + */ + pi->vi_en_rx = pi->link_cfg.link_ok; + t4_enable_vi(adap, adap->mbox, pi->viid, pi->vi_en_rx, pi->vi_en_tx); +} + bool cxgbe_force_linkup(struct adapter *adap) { if (is_pf4(adap)) @@ -1638,15 +1669,14 @@ int cxgbe_link_start(struct port_info *pi) if (ret == 0 && is_pf4(adapter)) ret = t4_link_l1cfg(pi, pi->link_cfg.admin_caps); if (ret == 0) { - /* - * Enabling a Virtual Interface can result in an interrupt - * during the processing of the VI Enable command and, in some - * paths, result in an attempt to issue another command in the - * interrupt context. Thus, we disable interrupts during the - * course of the VI Enable command ... + /* Disable VI Rx until link up message is received in + * firmware event queue, if firmware supports enabling/ + * disabling VI Rx at runtime. */ + pi->vi_en_rx = adapter->params.vi_enable_rx ? 0 : 1; + pi->vi_en_tx = 1; ret = t4_enable_vi_params(adapter, adapter->mbox, pi->viid, - true, true, false); + pi->vi_en_rx, pi->vi_en_tx, false); } if (ret == 0 && cxgbe_force_linkup(adapter)) @@ -1923,7 +1953,13 @@ int cxgbe_set_link_status(struct port_info *pi, bool status) struct adapter *adapter = pi->adapter; int err = 0; - err = t4_enable_vi(adapter, adapter->mbox, pi->viid, status, status); + /* Wait for link up message from firmware to enable Rx path, + * if firmware supports enabling/disabling VI Rx at runtime. + */ + pi->vi_en_rx = adapter->params.vi_enable_rx ? 0 : status; + pi->vi_en_tx = status; + err = t4_enable_vi(adapter, adapter->mbox, pi->viid, pi->vi_en_rx, + pi->vi_en_tx); if (err) { dev_err(adapter, "%s: disable_vi failed: %d\n", __func__, err); return err; -- 2.20.1