net/cxgbevf: fix inter-VM traffic when physical link down
authorShagun Agrawal <shaguna@chelsio.com>
Mon, 21 May 2018 08:05:07 +0000 (13:35 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 22 May 2018 22:35:01 +0000 (00:35 +0200)
Add force_link_up devargs to always force link as up for VFs.
This enables VFs on the same NIC to send traffic to each other
even when physical link is down.

Also add RTE_PMD_REGISTER_PARAM_STRING to export all supported
devargs.

Fixes: 011ebc236ddc ("net/cxgbe: add skeleton VF driver")

Signed-off-by: Shagun Agrawal <shaguna@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
doc/guides/nics/cxgbe.rst
drivers/net/cxgbe/cxgbe.h
drivers/net/cxgbe/cxgbe_ethdev.c
drivers/net/cxgbe/cxgbe_main.c

index 38d4348..78e3914 100644 (file)
@@ -143,6 +143,12 @@ be passed as part of EAL arguments. For example,
   enabled, the outer VLAN tag is preserved in Q-in-Q packets. Otherwise,
   the outer VLAN tag is stripped in Q-in-Q packets.
 
+- ``force_link_up`` (default **0**)
+
+  When set to 1, CXGBEVF PMD always forces link as up for all VFs on
+  underlying Chelsio NICs. This enables multiple VFs on the same NIC
+  to send traffic to each other even when the physical link is down.
+
 .. _driver-compilation:
 
 Driver compilation and testing
index b1a4e08..e4a5256 100644 (file)
                          ETH_RSS_NONFRAG_IPV6_TCP | \
                          ETH_RSS_NONFRAG_IPV6_UDP)
 
+#define CXGBE_DEVARG_KEEP_OVLAN "keep_ovlan"
+#define CXGBE_DEVARG_FORCE_LINK_UP "force_link_up"
+
+bool force_linkup(struct adapter *adap);
 int cxgbe_probe(struct adapter *adapter);
 int cxgbevf_probe(struct adapter *adapter);
 void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps);
@@ -45,5 +49,6 @@ int setup_rss(struct port_info *pi);
 void cxgbe_enable_rx_queues(struct port_info *pi);
 void print_port_info(struct adapter *adap);
 void print_adapter_info(struct adapter *adap);
+int cxgbe_get_devargs(struct rte_devargs *devargs, const char *key);
 
 #endif /* _CXGBE_H_ */
index 3ee7c44..61115e2 100644 (file)
@@ -204,19 +204,17 @@ int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
        struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private);
        struct adapter *adapter = pi->adapter;
        struct sge *s = &adapter->sge;
-       struct rte_eth_link *old_link = &eth_dev->data->dev_link;
+       struct rte_eth_link new_link;
        unsigned int work_done, budget = 4;
 
        cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
-       if (old_link->link_status == pi->link_cfg.link_ok)
-               return -1;  /* link not changed */
 
-       eth_dev->data->dev_link.link_status = pi->link_cfg.link_ok;
-       eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-       eth_dev->data->dev_link.link_speed = pi->link_cfg.speed;
+       new_link.link_status = force_linkup(adapter) ?
+                              ETH_LINK_UP : pi->link_cfg.link_ok;
+       new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+       new_link.link_speed = pi->link_cfg.speed;
 
-       /* link has changed */
-       return 0;
+       return rte_eth_linkstatus_set(eth_dev, &new_link);
 }
 
 int cxgbe_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
@@ -1158,3 +1156,6 @@ static struct rte_pci_driver rte_cxgbe_pmd = {
 RTE_PMD_REGISTER_PCI(net_cxgbe, rte_cxgbe_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_cxgbe, cxgb4_pci_tbl);
 RTE_PMD_REGISTER_KMOD_DEP(net_cxgbe, "* igb_uio | uio_pci_generic | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_cxgbe,
+                             CXGBE_DEVARG_KEEP_OVLAN "=<0|1> "
+                             CXGBE_DEVARG_FORCE_LINK_UP "=<0|1> ");
index 9ad5e54..54eb23d 100644 (file)
@@ -38,8 +38,6 @@
 #include "t4_msg.h"
 #include "cxgbe.h"
 
-#define CXGBE_DEVARG_KEEP_OVLAN "keep_ovlan"
-
 /*
  * Response queue handler for the FW event queue.
  */
@@ -404,7 +402,7 @@ check_devargs_handler(__rte_unused const char *key, const char *value,
        return 0;
 }
 
-static int cxgbe_get_devargs(struct rte_devargs *devargs, const char *key)
+int cxgbe_get_devargs(struct rte_devargs *devargs, const char *key)
 {
        struct rte_kvargs *kvlist;
 
@@ -942,6 +940,18 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id)
                         pi->port_id, pi->mod_type);
 }
 
+inline bool force_linkup(struct adapter *adap)
+{
+       struct rte_pci_device *pdev = adap->pdev;
+
+       if (is_pf4(adap))
+               return false;   /* force_linkup not required for pf driver*/
+       if (!cxgbe_get_devargs(pdev->device.devargs,
+                              CXGBE_DEVARG_FORCE_LINK_UP))
+               return false;
+       return true;
+}
+
 /**
  * link_start - enable a port
  * @dev: the port to enable
@@ -987,6 +997,9 @@ int link_start(struct port_info *pi)
                ret = t4_enable_vi_params(adapter, adapter->mbox, pi->viid,
                                          true, true, false);
        }
+
+       if (ret == 0 && force_linkup(adapter))
+               pi->eth_dev->data->dev_link.link_status = ETH_LINK_UP;
        return ret;
 }