bnx2x: Correct default Tx switching behaviour

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>
This commit is contained in:
Yuval Mintz 2014-01-12 14:37:59 +02:00 committed by David S. Miller
parent 08c93cd99b
commit c14db20259
5 changed files with 75 additions and 1 deletions

View 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)

View 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);

View 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,

View 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 */

View 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);