Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c14db202 authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller
Browse files

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: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarAriel Elior <ariele@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 08c93cd9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
+3 −0
Original line number Diff line number Diff line
@@ -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);

+7 −0
Original line number Diff line number Diff line
@@ -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,
+3 −1
Original line number Diff line number Diff line
@@ -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 */
+61 −0
Original line number Diff line number Diff line
@@ -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);