net/cxgbe: disable Rx during port link down
authorRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Mon, 15 Mar 2021 21:51:46 +0000 (03:21 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 22 Mar 2021 18:21:55 +0000 (19:21 +0100)
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 <rahul.lakkireddy@chelsio.com>
doc/guides/nics/cxgbe.rst
drivers/net/cxgbe/base/adapter.h
drivers/net/cxgbe/base/common.h
drivers/net/cxgbe/base/t4_hw.c
drivers/net/cxgbe/base/t4fw_interface.h
drivers/net/cxgbe/cxgbe_main.c

index 4b99136..4a8fef0 100644 (file)
@@ -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 <http://service.chelsio.com>`_ 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)
index a5a3313..01a2a9d 100644 (file)
@@ -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);
index ab100d7..2f8569c 100644 (file)
@@ -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.
index 0e3033b..7ebf4a9 100644 (file)
@@ -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) {
index 240e0ee..0310a7c 100644 (file)
@@ -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,
 };
 
 /*
index 83ad758..c759d97 100644 (file)
@@ -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;