bnx2x: Add VF device ids and enable feature
authorAriel Elior <ariele@broadcom.com>
Tue, 1 Jan 2013 05:22:44 +0000 (05:22 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Jan 2013 09:45:08 +0000 (01:45 -0800)
Add the various VF device ids (of all supported hardware)
Add the calls to enable_sriov and disable_sriov to enable the
SR-IOV feature. This patch also advances the version and release
date of the bnx2x module.

Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c

index 335b536d36711c7dbf8d9a01b668aad966f3307f..85969170eb06e1921526b5d310521dec4d9e7b5b 100644 (file)
@@ -26,8 +26,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.78.00-0"
-#define DRV_MODULE_RELDATE      "2012/09/27"
+#define DRV_MODULE_VERSION      "1.78.01-0"
+#define DRV_MODULE_RELDATE      "2012/10/30"
 #define BNX2X_BC_VER            0x040200
 
 #if defined(CONFIG_DCB)
@@ -802,36 +802,46 @@ struct bnx2x_common {
 #define CHIP_NUM_57711E                        0x1650
 #define CHIP_NUM_57712                 0x1662
 #define CHIP_NUM_57712_MF              0x1663
+#define CHIP_NUM_57712_VF              0x166f
 #define CHIP_NUM_57713                 0x1651
 #define CHIP_NUM_57713E                        0x1652
 #define CHIP_NUM_57800                 0x168a
 #define CHIP_NUM_57800_MF              0x16a5
+#define CHIP_NUM_57800_VF              0x16a9
 #define CHIP_NUM_57810                 0x168e
 #define CHIP_NUM_57810_MF              0x16ae
+#define CHIP_NUM_57810_VF              0x16af
 #define CHIP_NUM_57811                 0x163d
 #define CHIP_NUM_57811_MF              0x163e
+#define CHIP_NUM_57811_VF              0x163f
 #define CHIP_NUM_57840_OBSOLETE        0x168d
 #define CHIP_NUM_57840_MF_OBSOLETE     0x16ab
 #define CHIP_NUM_57840_4_10            0x16a1
 #define CHIP_NUM_57840_2_20            0x16a2
 #define CHIP_NUM_57840_MF              0x16a4
+#define CHIP_NUM_57840_VF              0x16ad
 #define CHIP_IS_E1(bp)                 (CHIP_NUM(bp) == CHIP_NUM_57710)
 #define CHIP_IS_57711(bp)              (CHIP_NUM(bp) == CHIP_NUM_57711)
 #define CHIP_IS_57711E(bp)             (CHIP_NUM(bp) == CHIP_NUM_57711E)
 #define CHIP_IS_57712(bp)              (CHIP_NUM(bp) == CHIP_NUM_57712)
+#define CHIP_IS_57712_VF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57712_VF)
 #define CHIP_IS_57712_MF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57712_MF)
 #define CHIP_IS_57800(bp)              (CHIP_NUM(bp) == CHIP_NUM_57800)
 #define CHIP_IS_57800_MF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57800_MF)
+#define CHIP_IS_57800_VF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57800_VF)
 #define CHIP_IS_57810(bp)              (CHIP_NUM(bp) == CHIP_NUM_57810)
 #define CHIP_IS_57810_MF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57810_MF)
+#define CHIP_IS_57810_VF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57810_VF)
 #define CHIP_IS_57811(bp)              (CHIP_NUM(bp) == CHIP_NUM_57811)
 #define CHIP_IS_57811_MF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57811_MF)
+#define CHIP_IS_57811_VF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57811_VF)
 #define CHIP_IS_57840(bp)              \
                ((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) || \
                 (CHIP_NUM(bp) == CHIP_NUM_57840_2_20) || \
                 (CHIP_NUM(bp) == CHIP_NUM_57840_OBSOLETE))
 #define CHIP_IS_57840_MF(bp)   ((CHIP_NUM(bp) == CHIP_NUM_57840_MF) || \
                                 (CHIP_NUM(bp) == CHIP_NUM_57840_MF_OBSOLETE))
+#define CHIP_IS_57840_VF(bp)           (CHIP_NUM(bp) == CHIP_NUM_57840_VF)
 #define CHIP_IS_E1H(bp)                        (CHIP_IS_57711(bp) || \
                                         CHIP_IS_57711E(bp))
 #define CHIP_IS_E2(bp)                 (CHIP_IS_57712(bp) || \
@@ -840,10 +850,13 @@ struct bnx2x_common {
                                         CHIP_IS_57800_MF(bp) || \
                                         CHIP_IS_57810(bp) || \
                                         CHIP_IS_57810_MF(bp) || \
+                                        CHIP_IS_57810_VF(bp) || \
                                         CHIP_IS_57811(bp) || \
                                         CHIP_IS_57811_MF(bp) || \
+                                        CHIP_IS_57811_VF(bp) || \
                                         CHIP_IS_57840(bp) || \
-                                        CHIP_IS_57840_MF(bp))
+                                        CHIP_IS_57840_MF(bp) || \
+                                        CHIP_IS_57840_VF(bp))
 #define CHIP_IS_E1x(bp)                        (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp)))
 #define USES_WARPCORE(bp)              (CHIP_IS_E3(bp))
 #define IS_E1H_OFFSET                  (!CHIP_IS_E1(bp))
@@ -1195,8 +1208,9 @@ struct bnx2x_fw_stats_data {
 enum {
        BNX2X_SP_RTNL_SETUP_TC,
        BNX2X_SP_RTNL_TX_TIMEOUT,
-       BNX2X_SP_RTNL_AFEX_F_UPDATE,
        BNX2X_SP_RTNL_FAN_FAILURE,
+       BNX2X_SP_RTNL_AFEX_F_UPDATE,
+       BNX2X_SP_RTNL_ENABLE_SRIOV,
        BNX2X_SP_RTNL_VFPF_MCAST,
        BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
 };
index 216802a5176d7b5af35c5272d061092d27a879be..2b6a919b6bc4d63873530e8b042093469f6e7c00 100644 (file)
@@ -195,12 +195,18 @@ static struct {
 #ifndef PCI_DEVICE_ID_NX2_57712_MF
 #define PCI_DEVICE_ID_NX2_57712_MF     CHIP_NUM_57712_MF
 #endif
+#ifndef PCI_DEVICE_ID_NX2_57712_VF
+#define PCI_DEVICE_ID_NX2_57712_VF     CHIP_NUM_57712_VF
+#endif
 #ifndef PCI_DEVICE_ID_NX2_57800
 #define PCI_DEVICE_ID_NX2_57800                CHIP_NUM_57800
 #endif
 #ifndef PCI_DEVICE_ID_NX2_57800_MF
 #define PCI_DEVICE_ID_NX2_57800_MF     CHIP_NUM_57800_MF
 #endif
+#ifndef PCI_DEVICE_ID_NX2_57800_VF
+#define PCI_DEVICE_ID_NX2_57800_VF     CHIP_NUM_57800_VF
+#endif
 #ifndef PCI_DEVICE_ID_NX2_57810
 #define PCI_DEVICE_ID_NX2_57810                CHIP_NUM_57810
 #endif
@@ -210,6 +216,9 @@ static struct {
 #ifndef PCI_DEVICE_ID_NX2_57840_O
 #define PCI_DEVICE_ID_NX2_57840_O      CHIP_NUM_57840_OBSOLETE
 #endif
+#ifndef PCI_DEVICE_ID_NX2_57810_VF
+#define PCI_DEVICE_ID_NX2_57810_VF     CHIP_NUM_57810_VF
+#endif
 #ifndef PCI_DEVICE_ID_NX2_57840_4_10
 #define PCI_DEVICE_ID_NX2_57840_4_10   CHIP_NUM_57840_4_10
 #endif
@@ -222,29 +231,41 @@ static struct {
 #ifndef PCI_DEVICE_ID_NX2_57840_MF
 #define PCI_DEVICE_ID_NX2_57840_MF     CHIP_NUM_57840_MF
 #endif
+#ifndef PCI_DEVICE_ID_NX2_57840_VF
+#define PCI_DEVICE_ID_NX2_57840_VF     CHIP_NUM_57840_VF
+#endif
 #ifndef PCI_DEVICE_ID_NX2_57811
 #define PCI_DEVICE_ID_NX2_57811                CHIP_NUM_57811
 #endif
 #ifndef PCI_DEVICE_ID_NX2_57811_MF
 #define PCI_DEVICE_ID_NX2_57811_MF     CHIP_NUM_57811_MF
 #endif
+#ifndef PCI_DEVICE_ID_NX2_57811_VF
+#define PCI_DEVICE_ID_NX2_57811_VF     CHIP_NUM_57811_VF
+#endif
+
 static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = {
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712), BCM57712 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712_MF), BCM57712_MF },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712_VF), BCM57712_VF },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57800), BCM57800 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57800_MF), BCM57800_MF },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57800_VF), BCM57800_VF },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810), BCM57810 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810_MF), BCM57810_MF },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_O), BCM57840_O },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_4_10), BCM57840_4_10 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_2_20), BCM57840_2_20 },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810_VF), BCM57810_VF },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_MFO), BCM57840_MFO },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_MF), BCM57840_MF },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_VF), BCM57840_VF },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811), BCM57811 },
        { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811_MF), BCM57811_MF },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811_VF), BCM57811_VF },
        { 0 }
 };
 
@@ -9428,8 +9449,10 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
 
        rtnl_lock();
 
-       if (!netif_running(bp->dev))
-               goto sp_rtnl_exit;
+       if (!netif_running(bp->dev)) {
+               rtnl_unlock();
+               return;
+       }
 
        /* if stop on error is defined no recovery flows should be executed */
 #ifdef BNX2X_STOP_ON_ERROR
@@ -9448,7 +9471,8 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
 
                bnx2x_parity_recover(bp);
 
-               goto sp_rtnl_exit;
+               rtnl_unlock();
+               return;
        }
 
        if (test_and_clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state)) {
@@ -9462,7 +9486,8 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
                bnx2x_nic_unload(bp, UNLOAD_NORMAL, true);
                bnx2x_nic_load(bp, LOAD_NORMAL);
 
-               goto sp_rtnl_exit;
+               rtnl_unlock();
+               return;
        }
 #ifdef BNX2X_STOP_ON_ERROR
 sp_rtnl_not_reset:
@@ -9480,6 +9505,8 @@ sp_rtnl_not_reset:
                DP(NETIF_MSG_HW, "fan failure detected. Unloading driver\n");
                netif_device_detach(bp->dev);
                bnx2x_close(bp->dev);
+               rtnl_unlock();
+               return;
        }
 
        if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_MCAST, &bp->sp_rtnl_state)) {
@@ -9495,8 +9522,28 @@ sp_rtnl_not_reset:
                bnx2x_vfpf_storm_rx_mode(bp);
        }
 
-sp_rtnl_exit:
+       /* work which needs rtnl lock not-taken (as it takes the lock itself and
+        * can be called from other contexts as well)
+        */
+
        rtnl_unlock();
+
+       if (IS_SRIOV(bp) && test_and_clear_bit(BNX2X_SP_RTNL_ENABLE_SRIOV,
+                                              &bp->sp_rtnl_state)) {
+               int rc = 0;
+
+               /* disbale sriov in case it is still enabled */
+               pci_disable_sriov(bp->pdev);
+               DP(BNX2X_MSG_IOV, "sriov disabled\n");
+
+               /* enable sriov */
+               DP(BNX2X_MSG_IOV, "vf num (%d)\n", (bp->vfdb->sriov.nr_virtfn));
+               rc = pci_enable_sriov(bp->pdev, (bp->vfdb->sriov.nr_virtfn));
+               if (rc)
+                       BNX2X_ERR("pci_enable_sriov failed with %d\n", rc);
+               else
+                       DP(BNX2X_MSG_IOV, "sriov enabled\n");
+       }
 }
 
 /* end of nic load/unload */
@@ -11355,6 +11402,26 @@ static int bnx2x_init_bp(struct bnx2x *bp)
  * net_device service functions
  */
 
+static int bnx2x_open_epilog(struct bnx2x *bp)
+{
+       /* Enable sriov via delayed work. This must be done via delayed work
+        * because it causes the probe of the vf devices to be run, which invoke
+        * register_netdevice which must have rtnl lock taken. As we are holding
+        * the lock right now, that could only work if the probe would not take
+        * the lock. However, as the probe of the vf may be called from other
+        * contexts as well (such as passthrough to vm failes) it can't assume
+        * the lock is being held for it. Using delayed work here allows the
+        * probe code to simply take the lock (i.e. wait for it to be released
+        * if it is being held).
+        */
+       smp_mb__before_clear_bit();
+       set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state);
+       smp_mb__after_clear_bit();
+       schedule_delayed_work(&bp->sp_rtnl_task, 0);
+
+       return 0;
+}
+
 /* called with rtnl_lock */
 static int bnx2x_open(struct net_device *dev)
 {
@@ -11362,6 +11429,7 @@ static int bnx2x_open(struct net_device *dev)
        bool global = false;
        int other_engine = BP_PATH(bp) ? 0 : 1;
        bool other_load_status, load_status;
+       int rc;
 
        bp->stats_init = true;
 
@@ -11416,7 +11484,10 @@ static int bnx2x_open(struct net_device *dev)
        }
 
        bp->recovery_state = BNX2X_RECOVERY_DONE;
-       return bnx2x_nic_load(bp, LOAD_OPEN);
+       rc = bnx2x_nic_load(bp, LOAD_OPEN);
+       if (rc)
+               return rc;
+       return bnx2x_open_epilog(bp);
 }
 
 /* called with rtnl_lock */
index 1f1e823b7bdfad142c4239824a47fa3f1c9dd3ed..71fcef0d4071d27690d8bc605da8ab5bcf752c3f 100644 (file)
@@ -2034,6 +2034,10 @@ void bnx2x_iov_remove_one(struct bnx2x *bp)
        if (!IS_SRIOV(bp))
                return;
 
+       DP(BNX2X_MSG_IOV, "about to call disable sriov\n");
+       pci_disable_sriov(bp->pdev);
+       DP(BNX2X_MSG_IOV, "sriov disabled\n");
+
        /* free vf database */
        __bnx2x_iov_free_vfdb(bp);
 }