bnx2x: Correct default Tx switching behaviour
authorYuval Mintz <yuvalmin@broadcom.com>
Sun, 12 Jan 2014 12:37:59 +0000 (14:37 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 15 Jan 2014 01:10:30 +0000 (17:10 -0800)
With this patch bnx2x will configure the PF to perform Tx switching on
out-going traffic as soon as SR-IOV is dynamically enabled and de-activate
it when it is disabled.
This will allow VFs to communicate with their parent PFs.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@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_sp.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c

index 9819a548e3b911fbd00cb7ca3ffc26286b06c828..391f29ef6d2e172849c61140b7c88f99eff365fb 100644 (file)
@@ -1566,6 +1566,7 @@ struct bnx2x {
 #define NO_ISCSI_FLAG                  (1 << 14)
 #define NO_FCOE_FLAG                   (1 << 15)
 #define BC_SUPPORTS_PFC_STATS          (1 << 17)
+#define TX_SWITCHING                   (1 << 18)
 #define BC_SUPPORTS_FCOE_FEATURES      (1 << 19)
 #define USING_SINGLE_MSIX_FLAG         (1 << 20)
 #define BC_SUPPORTS_DCBX_MSG_NON_PMF   (1 << 21)
index f90079acb58c620a5ec9f4d903b355f14a5e48fb..cf17b660b4eead3ba4533bf5384e03f9a7617dca 100644 (file)
@@ -3007,6 +3007,9 @@ static unsigned long bnx2x_get_common_flags(struct bnx2x *bp,
        if (zero_stats)
                __set_bit(BNX2X_Q_FLG_ZERO_STATS, &flags);
 
+       if (bp->flags & TX_SWITCHING)
+               __set_bit(BNX2X_Q_FLG_TX_SWITCH, &flags);
+
        __set_bit(BNX2X_Q_FLG_PCSUM_ON_PKT, &flags);
        __set_bit(BNX2X_Q_FLG_TUN_INC_INNER_IP_ID, &flags);
 
index 9373584e400f1addf2c4827247f1ea9b5d082225..0fb6ff2ac8e3738372bcb95f4278ef600c2bd76b 100644 (file)
@@ -4728,6 +4728,13 @@ static void bnx2x_q_fill_update_data(struct bnx2x *bp,
                test_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM, &params->update_flags);
        data->silent_vlan_value = cpu_to_le16(params->silent_removal_value);
        data->silent_vlan_mask = cpu_to_le16(params->silent_removal_mask);
+
+       /* tx switching */
+       data->tx_switching_flg =
+               test_bit(BNX2X_Q_UPDATE_TX_SWITCHING, &params->update_flags);
+       data->tx_switching_change_flg =
+               test_bit(BNX2X_Q_UPDATE_TX_SWITCHING_CHNG,
+                        &params->update_flags);
 }
 
 static inline int bnx2x_q_send_update(struct bnx2x *bp,
index c8b939b141dec7c146686c094d9b88a0f8f3de76..00d7f214a40a2caf2619fac0343ad3798b4bdaed 100644 (file)
@@ -767,7 +767,9 @@ enum {
        BNX2X_Q_UPDATE_DEF_VLAN_EN,
        BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG,
        BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG,
-       BNX2X_Q_UPDATE_SILENT_VLAN_REM
+       BNX2X_Q_UPDATE_SILENT_VLAN_REM,
+       BNX2X_Q_UPDATE_TX_SWITCHING_CHNG,
+       BNX2X_Q_UPDATE_TX_SWITCHING
 };
 
 /* Allowed Queue states */
index 208636d05cc0d51e97b8703c5fb22fd5a21cdffb..d0e246b8a8718c9baf1eec5b9f9ccd306fa240ed 100644 (file)
@@ -3130,6 +3130,60 @@ void bnx2x_unlock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
           vf->abs_vfid, vf->op_current);
 }
 
+static int bnx2x_set_pf_tx_switching(struct bnx2x *bp, bool enable)
+{
+       struct bnx2x_queue_state_params q_params;
+       u32 prev_flags;
+       int i, rc;
+
+       /* Verify changes are needed and record current Tx switching state */
+       prev_flags = bp->flags;
+       if (enable)
+               bp->flags |= TX_SWITCHING;
+       else
+               bp->flags &= ~TX_SWITCHING;
+       if (prev_flags == bp->flags)
+               return 0;
+
+       /* Verify state enables the sending of queue ramrods */
+       if ((bp->state != BNX2X_STATE_OPEN) ||
+           (bnx2x_get_q_logical_state(bp,
+                                     &bnx2x_sp_obj(bp, &bp->fp[0]).q_obj) !=
+            BNX2X_Q_LOGICAL_STATE_ACTIVE))
+               return 0;
+
+       /* send q. update ramrod to configure Tx switching */
+       memset(&q_params, 0, sizeof(q_params));
+       __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
+       q_params.cmd = BNX2X_Q_CMD_UPDATE;
+       __set_bit(BNX2X_Q_UPDATE_TX_SWITCHING_CHNG,
+                 &q_params.params.update.update_flags);
+       if (enable)
+               __set_bit(BNX2X_Q_UPDATE_TX_SWITCHING,
+                         &q_params.params.update.update_flags);
+       else
+               __clear_bit(BNX2X_Q_UPDATE_TX_SWITCHING,
+                           &q_params.params.update.update_flags);
+
+       /* send the ramrod on all the queues of the PF */
+       for_each_eth_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+
+               /* Set the appropriate Queue object */
+               q_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj;
+
+               /* Update the Queue state */
+               rc = bnx2x_queue_state_change(bp, &q_params);
+               if (rc) {
+                       BNX2X_ERR("Failed to configure Tx switching\n");
+                       return rc;
+               }
+       }
+
+       DP(BNX2X_MSG_IOV, "%s Tx Switching\n", enable ? "Enabled" : "Disabled");
+       return 0;
+}
+
 int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param)
 {
        struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev));
@@ -3157,12 +3211,14 @@ int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param)
 
        bp->requested_nr_virtfn = num_vfs_param;
        if (num_vfs_param == 0) {
+               bnx2x_set_pf_tx_switching(bp, false);
                pci_disable_sriov(dev);
                return 0;
        } else {
                return bnx2x_enable_sriov(bp);
        }
 }
+
 #define IGU_ENTRY_SIZE 4
 
 int bnx2x_enable_sriov(struct bnx2x *bp)
@@ -3240,6 +3296,11 @@ int bnx2x_enable_sriov(struct bnx2x *bp)
         */
        DP(BNX2X_MSG_IOV, "about to call enable sriov\n");
        bnx2x_disable_sriov(bp);
+
+       rc = bnx2x_set_pf_tx_switching(bp, true);
+       if (rc)
+               return rc;
+
        rc = pci_enable_sriov(bp->pdev, req_vfs);
        if (rc) {
                BNX2X_ERR("pci_enable_sriov failed with %d\n", rc);