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

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
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "ixgbe.h" #include "ixgbe.h"
#include "ixgbe_phy.h" #include "ixgbe_phy.h"
#include "ixgbe_mbx.h"
#define IXGBE_82599_MAX_TX_QUEUES 128 #define IXGBE_82599_MAX_TX_QUEUES 128
#define IXGBE_82599_MAX_RX_QUEUES 128 #define IXGBE_82599_MAX_RX_QUEUES 128
...@@ -951,8 +952,6 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) ...@@ -951,8 +952,6 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
msleep(50); msleep(50);
/* /*
* Store the original AUTOC/AUTOC2 values if they have not been * Store the original AUTOC/AUTOC2 values if they have not been
* stored off yet. Otherwise restore the stored original * 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, ...@@ -1095,9 +1094,11 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
bool vlan_on) bool vlan_on)
{ {
u32 regindex; u32 regindex;
u32 vlvf_index;
u32 bitindex; u32 bitindex;
u32 bits; u32 bits;
u32 first_empty_slot; u32 first_empty_slot;
u32 vt_ctl;
if (vlan > 4095) if (vlan > 4095)
return IXGBE_ERR_PARAM; return IXGBE_ERR_PARAM;
...@@ -1124,28 +1125,31 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, ...@@ -1124,28 +1125,31 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
/* Part 2 /* Part 2
* If the vind is set * If VT mode is set
* Either vlan_on * Either vlan_on
* make sure the vlan is in VLVF * make sure the vlan is in VLVF
* set the vind bit in the matching VLVFB * set the vind bit in the matching VLVFB
* Or !vlan_on * Or !vlan_on
* clear the pool bit and possibly the vind * 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 */ /* find the vlanid or the first empty slot */
first_empty_slot = 0; first_empty_slot = 0;
for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { for (vlvf_index = 1; vlvf_index < IXGBE_VLVF_ENTRIES; vlvf_index++) {
bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); bits = IXGBE_READ_REG(hw, IXGBE_VLVF(vlvf_index));
if (!bits && !first_empty_slot) if (!bits && !first_empty_slot)
first_empty_slot = regindex; first_empty_slot = vlvf_index;
else if ((bits & 0x0FFF) == vlan) else if ((bits & 0x0FFF) == vlan)
break; break;
} }
if (regindex >= IXGBE_VLVF_ENTRIES) { if (vlvf_index >= IXGBE_VLVF_ENTRIES) {
if (first_empty_slot) if (first_empty_slot)
regindex = first_empty_slot; vlvf_index = first_empty_slot;
else { else {
hw_dbg(hw, "No space in VLVF.\n"); hw_dbg(hw, "No space in VLVF.\n");
goto out; goto out;
...@@ -1156,44 +1160,49 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind, ...@@ -1156,44 +1160,49 @@ static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
/* set the pool bit */ /* set the pool bit */
if (vind < 32) { if (vind < 32) {
bits = IXGBE_READ_REG(hw, bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB(regindex * 2)); IXGBE_VLVFB(vlvf_index * 2));
bits |= (1 << vind); bits |= (1 << vind);
IXGBE_WRITE_REG(hw, IXGBE_WRITE_REG(hw,
IXGBE_VLVFB(regindex * 2), bits); IXGBE_VLVFB(vlvf_index * 2), bits);
} else { } else {
bits = IXGBE_READ_REG(hw, bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB((regindex * 2) + 1)); IXGBE_VLVFB((vlvf_index * 2) + 1));
bits |= (1 << vind); bits |= (1 << (vind - 32));
IXGBE_WRITE_REG(hw, IXGBE_WRITE_REG(hw,
IXGBE_VLVFB((regindex * 2) + 1), bits); IXGBE_VLVFB((vlvf_index * 2) + 1), bits);
} }
} else { } else {
/* clear the pool bit */ /* clear the pool bit */
if (vind < 32) { if (vind < 32) {
bits = IXGBE_READ_REG(hw, bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB(regindex * 2)); IXGBE_VLVFB(vlvf_index * 2));
bits &= ~(1 << vind); bits &= ~(1 << vind);
IXGBE_WRITE_REG(hw, IXGBE_WRITE_REG(hw,
IXGBE_VLVFB(regindex * 2), bits); IXGBE_VLVFB(vlvf_index * 2), bits);
bits |= IXGBE_READ_REG(hw, bits |= IXGBE_READ_REG(hw,
IXGBE_VLVFB((regindex * 2) + 1)); IXGBE_VLVFB((vlvf_index * 2) + 1));
} else { } else {
bits = IXGBE_READ_REG(hw, bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB((regindex * 2) + 1)); IXGBE_VLVFB((vlvf_index * 2) + 1));
bits &= ~(1 << vind); bits &= ~(1 << (vind - 32));
IXGBE_WRITE_REG(hw, IXGBE_WRITE_REG(hw,
IXGBE_VLVFB((regindex * 2) + 1), bits); IXGBE_VLVFB((vlvf_index * 2) + 1), bits);
bits |= IXGBE_READ_REG(hw, bits |= IXGBE_READ_REG(hw,
IXGBE_VLVFB(regindex * 2)); IXGBE_VLVFB(vlvf_index * 2));
} }
} }
if (bits) if (bits) {
IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
(IXGBE_VLVF_VIEN | vlan)); (IXGBE_VLVF_VIEN | vlan));
else /* if bits is non-zero then some pools/VFs are still
IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0); * 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: out:
return 0; return 0;
...@@ -2655,4 +2664,5 @@ struct ixgbe_info ixgbe_82599_info = { ...@@ -2655,4 +2664,5 @@ struct ixgbe_info ixgbe_82599_info = {
.mac_ops = &mac_ops_82599, .mac_ops = &mac_ops_82599,
.eeprom_ops = &eeprom_ops_82599, .eeprom_ops = &eeprom_ops_82599,
.phy_ops = &phy_ops_82599, .phy_ops = &phy_ops_82599,
.mbx_ops = &mbx_ops_82599,
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment