net/qede: support 100G
authorHarish Patil <harish.patil@qlogic.com>
Thu, 16 Jun 2016 05:47:09 +0000 (22:47 -0700)
committerBruce Richardson <bruce.richardson@intel.com>
Thu, 23 Jun 2016 14:34:04 +0000 (16:34 +0200)
 - Add device id to the PCI table
 - Add polling for the slowpath events for CMT mode device
 - Add prerequisites to allow 100g mode
        * Min number of queues needed is 2
        * Only even number of queues are allowed
 - Update documentation

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
config/common_base
doc/guides/nics/qede.rst
drivers/net/qede/qede_ethdev.c
drivers/net/qede/qede_ethdev.h

index 4f1761e..845d0d5 100644 (file)
@@ -312,7 +312,7 @@ CONFIG_RTE_LIBRTE_PMD_BOND=y
 CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB=n
 CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
 
-# QLogic 25G/40G PMD
+# QLogic 25G/40G/100G PMD
 #
 CONFIG_RTE_LIBRTE_QEDE_PMD=n
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_INIT=n
index c5fbd83..f7ca8eb 100644 (file)
@@ -55,7 +55,7 @@ Supported Features
 - TSS
 - Multiple MAC address
 - Default pause flow control
-- SR-IOV VF
+- SR-IOV VF for 25G/40G modes
 
 Non-supported Features
 ----------------------
@@ -70,13 +70,13 @@ Non-supported Features
 Supported QLogic Adapters
 -------------------------
 
-- QLogic FastLinQ QL4xxxx 25G/40G CNAs
+- QLogic FastLinQ QL4xxxx 25G/40G/100G CNAs.
 
 Prerequisites
 -------------
 
-- Requires firmware version **8.7.x.** and management
-  firmware version **8.7.x or higher**. Firmware may be available
+- Requires firmware version **8.7.x.** and management firmware
+  version **8.7.x or higher**. Firmware may be available
   inbox in certain newer Linux distros under the standard directory
   ``E.g. /lib/firmware/qed/qed_init_values_zipped-8.7.7.0.bin``
 
index af16277..bb531be 100644 (file)
@@ -7,10 +7,12 @@
  */
 
 #include "qede_ethdev.h"
+#include <rte_alarm.h>
 
 /* Globals */
 static const struct qed_eth_ops *qed_ops;
 static const char *drivername = "qede pmd";
+static int64_t timer_period = 1;
 
 static void qede_interrupt_action(struct ecore_hwfn *p_hwfn)
 {
@@ -358,6 +360,21 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
                return -EINVAL;
        }
 
+       /* Check requirements for 100G mode */
+       if (edev->num_hwfns > 1) {
+               if (eth_dev->data->nb_rx_queues < 2) {
+                       DP_NOTICE(edev, false,
+                                 "100G mode requires minimum two queues\n");
+                       return -EINVAL;
+               }
+
+               if ((eth_dev->data->nb_rx_queues % 2) != 0) {
+                       DP_NOTICE(edev, false,
+                                 "100G mode requires even number of queues\n");
+                       return -EINVAL;
+               }
+       }
+
        qdev->num_rss = eth_dev->data->nb_rx_queues;
 
        /* Initial state */
@@ -540,6 +557,26 @@ static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
                qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_REGULAR);
 }
 
+static void qede_poll_sp_sb_cb(void *param)
+{
+       struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+       struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+       struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+       int rc;
+
+       qede_interrupt_action(ECORE_LEADING_HWFN(edev));
+       qede_interrupt_action(&edev->hwfns[1]);
+
+       rc = rte_eal_alarm_set(timer_period * US_PER_S,
+                              qede_poll_sp_sb_cb,
+                              (void *)eth_dev);
+       if (rc != 0) {
+               DP_ERR(edev, "Unable to start periodic"
+                            " timer rc %d\n", rc);
+               assert(false && "Unable to start periodic timer");
+       }
+}
+
 static void qede_dev_close(struct rte_eth_dev *eth_dev)
 {
        struct qede_dev *qdev = eth_dev->data->dev_private;
@@ -572,6 +609,9 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
        rte_intr_callback_unregister(&eth_dev->pci_dev->intr_handle,
                                     qede_interrupt_handler, (void *)eth_dev);
 
+       if (edev->num_hwfns > 1)
+               rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev);
+
        qdev->state = QEDE_CLOSE;
 }
 
@@ -1070,9 +1110,26 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
        params.drv_eng = QEDE_ENGINEERING_VERSION;
        strncpy((char *)params.name, "qede LAN", QED_DRV_VER_STR_SIZE);
 
+       /* For CMT mode device do periodic polling for slowpath events.
+        * This is required since uio device uses only one MSI-x
+        * interrupt vector but we need one for each engine.
+        */
+       if (edev->num_hwfns > 1) {
+               rc = rte_eal_alarm_set(timer_period * US_PER_S,
+                                      qede_poll_sp_sb_cb,
+                                      (void *)eth_dev);
+               if (rc != 0) {
+                       DP_ERR(edev, "Unable to start periodic"
+                                    " timer rc %d\n", rc);
+                       return -EINVAL;
+               }
+       }
+
        rc = qed_ops->common->slowpath_start(edev, &params);
        if (rc) {
                DP_ERR(edev, "Cannot start slowpath rc = %d\n", rc);
+               rte_eal_alarm_cancel(qede_poll_sp_sb_cb,
+                                    (void *)eth_dev);
                return -ENODEV;
        }
 
@@ -1081,6 +1138,8 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
                DP_ERR(edev, "Cannot get device_info rc %d\n", rc);
                qed_ops->common->slowpath_stop(edev);
                qed_ops->common->remove(edev);
+               rte_eal_alarm_cancel(qede_poll_sp_sb_cb,
+                                    (void *)eth_dev);
                return -ENODEV;
        }
 
@@ -1106,6 +1165,8 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
                DP_ERR(edev, "Failed to allocate MAC address\n");
                qed_ops->common->slowpath_stop(edev);
                qed_ops->common->remove(edev);
+               rte_eal_alarm_cancel(qede_poll_sp_sb_cb,
+                                    (void *)eth_dev);
                return -ENOMEM;
        }
 
@@ -1221,6 +1282,9 @@ static struct rte_pci_id pci_id_qede_map[] = {
        {
                QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_57980S_25)
        },
+       {
+               QEDE_RTE_PCI_DEVICE(PCI_DEVICE_ID_57980S_100)
+       },
        {.vendor_id = 0,}
 };
 
index 64d5f08..b080f5f 100644 (file)
@@ -81,7 +81,7 @@
        struct ecore_dev *edev = &qdev->edev;                   \
 }
 
-/************* QLogic 25G/40G vendor/devices ids *************/
+/************* QLogic 25G/40G/100G vendor/devices ids *************/
 #define PCI_VENDOR_ID_QLOGIC            0x1077
 
 #define CHIP_NUM_57980E                 0x1634
@@ -90,6 +90,7 @@
 #define CHIP_NUM_57980S_40              0x1634
 #define CHIP_NUM_57980S_25              0x1656
 #define CHIP_NUM_57980S_IOV             0x1664
+#define CHIP_NUM_57980S_100             0x1644
 
 #define PCI_DEVICE_ID_NX2_57980E        CHIP_NUM_57980E
 #define PCI_DEVICE_ID_NX2_57980S        CHIP_NUM_57980S
@@ -97,6 +98,7 @@
 #define PCI_DEVICE_ID_57980S_40         CHIP_NUM_57980S_40
 #define PCI_DEVICE_ID_57980S_25         CHIP_NUM_57980S_25
 #define PCI_DEVICE_ID_57980S_IOV        CHIP_NUM_57980S_IOV
+#define PCI_DEVICE_ID_57980S_100        CHIP_NUM_57980S_100
 
 extern char fw_file[];