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

Commit 096a58fd authored by Greg Rose's avatar Greg Rose Committed by David S. Miller
Browse files

ixgbe: Add SR-IOV feature enablement code



Adds code to the core 82599 module to support SR-IOV features of the 82599
network controller

Signed-off-by: default avatarGreg Rose <gregory.v.rose@intel.com>
Acked-by: default avatarPeter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 92ed72d5
Loading
Loading
Loading
Loading
+68 −58
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include "ixgbe.h"
#include "ixgbe_phy.h"
#include "ixgbe_mbx.h"

#define IXGBE_82599_MAX_TX_QUEUES 128
#define IXGBE_82599_MAX_RX_QUEUES 128
@@ -951,8 +952,6 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)

	msleep(50);



	/*
	 * Store the original AUTOC/AUTOC2 values if they have not been
	 * stored off yet.  Otherwise restore the stored original
@@ -1095,9 +1094,11 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
                                bool vlan_on)
{
	u32 regindex;
	u32 vlvf_index;
	u32 bitindex;
	u32 bits;
	u32 first_empty_slot;
	u32 vt_ctl;

	if (vlan > 4095)
		return IXGBE_ERR_PARAM;
@@ -1124,28 +1125,31 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,


	/* Part 2
	 * If the vind is set
	 * If VT mode is set
	 *   Either vlan_on
	 *     make sure the vlan is in VLVF
	 *     set the vind bit in the matching VLVFB
	 *   Or !vlan_on
	 *     clear the pool bit and possibly the vind
	 */
	if (vind) {
	vt_ctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
	if (!(vt_ctl & IXGBE_VT_CTL_VT_ENABLE))
		goto out;

	/* find the vlanid or the first empty slot */
	first_empty_slot = 0;

		for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
			bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
	for (vlvf_index = 1; vlvf_index < IXGBE_VLVF_ENTRIES; vlvf_index++) {
		bits = IXGBE_READ_REG(hw, IXGBE_VLVF(vlvf_index));
		if (!bits && !first_empty_slot)
				first_empty_slot = regindex;
			first_empty_slot = vlvf_index;
		else if ((bits & 0x0FFF) == vlan)
			break;
	}

		if (regindex >= IXGBE_VLVF_ENTRIES) {
	if (vlvf_index >= IXGBE_VLVF_ENTRIES) {
		if (first_empty_slot)
				regindex = first_empty_slot;
			vlvf_index = first_empty_slot;
		else {
			hw_dbg(hw, "No space in VLVF.\n");
			goto out;
@@ -1156,44 +1160,49 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
		/* set the pool bit */
		if (vind < 32) {
			bits = IXGBE_READ_REG(hw,
				                    IXGBE_VLVFB(regindex * 2));
					      IXGBE_VLVFB(vlvf_index * 2));
			bits |= (1 << vind);
			IXGBE_WRITE_REG(hw,
				              IXGBE_VLVFB(regindex * 2), bits);
					IXGBE_VLVFB(vlvf_index * 2), bits);
		} else {
			bits = IXGBE_READ_REG(hw,
				              IXGBE_VLVFB((regindex * 2) + 1));
				bits |= (1 << vind);
				IXGBE_VLVFB((vlvf_index * 2) + 1));
			bits |= (1 << (vind - 32));
			IXGBE_WRITE_REG(hw,
				        IXGBE_VLVFB((regindex * 2) + 1), bits);
				IXGBE_VLVFB((vlvf_index * 2) + 1), bits);
		}
	} else {
		/* clear the pool bit */
		if (vind < 32) {
			bits = IXGBE_READ_REG(hw,
				     IXGBE_VLVFB(regindex * 2));
					      IXGBE_VLVFB(vlvf_index * 2));
			bits &= ~(1 << vind);
			IXGBE_WRITE_REG(hw,
				              IXGBE_VLVFB(regindex * 2), bits);
					IXGBE_VLVFB(vlvf_index * 2), bits);
			bits |= IXGBE_READ_REG(hw,
				              IXGBE_VLVFB((regindex * 2) + 1));
					IXGBE_VLVFB((vlvf_index * 2) + 1));
		} else {
			bits = IXGBE_READ_REG(hw,
				              IXGBE_VLVFB((regindex * 2) + 1));
				bits &= ~(1 << vind);
				IXGBE_VLVFB((vlvf_index * 2) + 1));
			bits &= ~(1 << (vind - 32));
			IXGBE_WRITE_REG(hw,
				        IXGBE_VLVFB((regindex * 2) + 1), bits);
				IXGBE_VLVFB((vlvf_index * 2) + 1), bits);
			bits |= IXGBE_READ_REG(hw,
				                    IXGBE_VLVFB(regindex * 2));
					       IXGBE_VLVFB(vlvf_index * 2));
		}
	}

		if (bits)
			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
	if (bits) {
		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
				(IXGBE_VLVF_VIEN | vlan));
		else
			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
		/* if bits is non-zero then some pools/VFs are still
		 * using this VLAN ID.  Force the VFTA entry to on */
		bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
		bits |= (1 << bitindex);
		IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
	}
	else
		IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);

out:
	return 0;
@@ -2655,4 +2664,5 @@ struct ixgbe_info ixgbe_82599_info = {
	.mac_ops                = &mac_ops_82599,
	.eeprom_ops             = &eeprom_ops_82599,
	.phy_ops                = &phy_ops_82599,
	.mbx_ops                = &mbx_ops_82599,
};