Commit 1d72135d authored by David S. Miller's avatar David S. Miller

Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
10GbE Intel Wired LAN Driver Updates 2015-12-12

This series contains updates to ixgbe only.

Alex Duyck provides almost off of the changes in this series.  First, add a
check to make sure mac_table was actually allocated and is not NULL to
ensure we do not get a NULL pointer dereference further down the line.
Fixed SR-IOV VLAN pool configuration since the code for checking the PF bit
in ixgbe_set_vf_vlan_msg() was using the wrong offset.  Cleanup/simplify
the logic for setting the VFTA register by removing the number of
conditional checks needed.  Fixed a number of issues within the VLVF and
VLFB configuration by simplifying the code.  Added support for bypassing
the VLVF entry creation when the PF is adding a new VLAN.  Reduced the
complexity of the search function used for finding a VLVF entry associated
with a given VLAN ID.  Added support for VLAN promiscuous with SR-IOV
enabled by setting all the bits in the VFTA and all of the VLVF bits
associated with teh pool belonging to the PF, in addition to cleaning up
those same bits in the event of promiscuous mode being disabled.  Fixed
and issue where we ran the risk of leaking an address into pool 0 which
really belongs to VF 0 when SR-IOV is enabled.

Emil fixes an issue with some X550 devices which can connect at 2.5Gbps,
but only with certain link partners during fail-over, so to avoid
confusion, we do not report it as supported.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bb35a6ef d3428001
...@@ -664,6 +664,7 @@ struct ixgbe_adapter { ...@@ -664,6 +664,7 @@ struct ixgbe_adapter {
#ifdef CONFIG_IXGBE_VXLAN #ifdef CONFIG_IXGBE_VXLAN
#define IXGBE_FLAG2_VXLAN_REREG_NEEDED BIT(12) #define IXGBE_FLAG2_VXLAN_REREG_NEEDED BIT(12)
#endif #endif
#define IXGBE_FLAG2_VLAN_PROMISC BIT(13)
/* Tx fast path data */ /* Tx fast path data */
int num_tx_queues; int num_tx_queues;
...@@ -897,6 +898,7 @@ int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, ...@@ -897,6 +898,7 @@ int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
const u8 *addr, u16 queue); const u8 *addr, u16 queue);
int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
const u8 *addr, u16 queue); const u8 *addr, u16 queue);
void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid);
void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *, netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
struct ixgbe_ring *); struct ixgbe_ring *);
......
...@@ -880,11 +880,12 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) ...@@ -880,11 +880,12 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
* @vlan: VLAN id to write to VLAN filter * @vlan: VLAN id to write to VLAN filter
* @vind: VMDq output index that maps queue to VLAN id in VFTA * @vind: VMDq output index that maps queue to VLAN id in VFTA
* @vlan_on: boolean flag to turn on/off VLAN in VFTA * @vlan_on: boolean flag to turn on/off VLAN in VFTA
* @vlvf_bypass: boolean flag - unused
* *
* Turn on/off specified VLAN in the VLAN filter table. * Turn on/off specified VLAN in the VLAN filter table.
**/ **/
static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, static s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
bool vlan_on) bool vlan_on, bool vlvf_bypass)
{ {
u32 regindex; u32 regindex;
u32 bitindex; u32 bitindex;
......
...@@ -1083,12 +1083,16 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) ...@@ -1083,12 +1083,16 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
/* Add the SAN MAC address to the RAR only if it's a valid address */ /* Add the SAN MAC address to the RAR only if it's a valid address */
if (is_valid_ether_addr(hw->mac.san_addr)) { if (is_valid_ether_addr(hw->mac.san_addr)) {
hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
hw->mac.san_addr, 0, IXGBE_RAH_AV);
/* Save the SAN MAC RAR index */ /* Save the SAN MAC RAR index */
hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
hw->mac.san_addr, 0, IXGBE_RAH_AV);
/* clear VMDq pool/queue selection for this RAR */
hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
IXGBE_CLEAR_VMDQ_ALL);
/* Reserve the last RAR for the SAN MAC address */ /* Reserve the last RAR for the SAN MAC address */
hw->mac.num_rar_entries--; hw->mac.num_rar_entries--;
} }
......
...@@ -1884,10 +1884,11 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) ...@@ -1884,10 +1884,11 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr); hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
/* clear VMDq pool/queue selection for RAR 0 */
hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
} }
/* clear VMDq pool/queue selection for RAR 0 */
hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
hw->addr_ctrl.overflow_promisc = 0; hw->addr_ctrl.overflow_promisc = 0;
hw->addr_ctrl.rar_used_count = 1; hw->addr_ctrl.rar_used_count = 1;
...@@ -2999,43 +3000,44 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) ...@@ -2999,43 +3000,44 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
* return the VLVF index where this VLAN id should be placed * return the VLVF index where this VLAN id should be placed
* *
**/ **/
static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass)
{ {
u32 bits = 0; s32 regindex, first_empty_slot;
u32 first_empty_slot = 0; u32 bits;
s32 regindex;
/* short cut the special case */ /* short cut the special case */
if (vlan == 0) if (vlan == 0)
return 0; return 0;
/* /* if vlvf_bypass is set we don't want to use an empty slot, we
* Search for the vlan id in the VLVF entries. Save off the first empty * will simply bypass the VLVF if there are no entries present in the
* slot found along the way * VLVF that contain our VLAN
*/ */
for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0;
/* add VLAN enable bit for comparison */
vlan |= IXGBE_VLVF_VIEN;
/* Search for the vlan id in the VLVF entries. Save off the first empty
* slot found along the way.
*
* pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1
*/
for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) {
bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
if (!bits && !(first_empty_slot)) if (bits == vlan)
return regindex;
if (!first_empty_slot && !bits)
first_empty_slot = regindex; first_empty_slot = regindex;
else if ((bits & 0x0FFF) == vlan)
break;
} }
/* /* If we are here then we didn't find the VLAN. Return first empty
* If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan * slot we found during our search, else error.
* in the VLVF. Else use the first empty VLVF register for this */
* vlan id. if (!first_empty_slot)
*/ hw_dbg(hw, "No space in VLVF.\n");
if (regindex >= IXGBE_VLVF_ENTRIES) {
if (first_empty_slot)
regindex = first_empty_slot;
else {
hw_dbg(hw, "No space in VLVF.\n");
regindex = IXGBE_ERR_NO_SPACE;
}
}
return regindex; return first_empty_slot ? : IXGBE_ERR_NO_SPACE;
} }
/** /**
...@@ -3044,21 +3046,17 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) ...@@ -3044,21 +3046,17 @@ static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
* @vlan: VLAN id to write to VLAN filter * @vlan: VLAN id to write to VLAN filter
* @vind: VMDq output index that maps queue to VLAN id in VFVFB * @vind: VMDq output index that maps queue to VLAN id in VFVFB
* @vlan_on: boolean flag to turn on/off VLAN in VFVF * @vlan_on: boolean flag to turn on/off VLAN in VFVF
* @vlvf_bypass: boolean flag indicating updating default pool is okay
* *
* Turn on/off specified VLAN in the VLAN filter table. * Turn on/off specified VLAN in the VLAN filter table.
**/ **/
s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
bool vlan_on) bool vlan_on, bool vlvf_bypass)
{ {
s32 regindex; u32 regidx, vfta_delta, vfta, bits;
u32 bitindex; s32 vlvf_index;
u32 vfta;
u32 bits;
u32 vt;
u32 targetbit;
bool vfta_changed = false;
if (vlan > 4095) if ((vlan > 4095) || (vind > 63))
return IXGBE_ERR_PARAM; return IXGBE_ERR_PARAM;
/* /*
...@@ -3073,22 +3071,16 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, ...@@ -3073,22 +3071,16 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
* bits[11-5]: which register * bits[11-5]: which register
* bits[4-0]: which bit in the register * bits[4-0]: which bit in the register
*/ */
regindex = (vlan >> 5) & 0x7F; regidx = vlan / 32;
bitindex = vlan & 0x1F; vfta_delta = 1 << (vlan % 32);
targetbit = (1 << bitindex); vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx));
vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
/* vfta_delta represents the difference between the current value
if (vlan_on) { * of vfta and the value we want in the register. Since the diff
if (!(vfta & targetbit)) { * is an XOR mask we can just update vfta using an XOR.
vfta |= targetbit; */
vfta_changed = true; vfta_delta &= vlan_on ? ~vfta : vfta;
} vfta ^= vfta_delta;
} else {
if ((vfta & targetbit)) {
vfta &= ~targetbit;
vfta_changed = true;
}
}
/* Part 2 /* Part 2
* If VT Mode is set * If VT Mode is set
...@@ -3098,85 +3090,67 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, ...@@ -3098,85 +3090,67 @@ s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
* Or !vlan_on * Or !vlan_on
* clear the pool bit and possibly the vind * clear the pool bit and possibly the vind
*/ */
vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE))
if (vt & IXGBE_VT_CTL_VT_ENABLE) { goto vfta_update;
s32 vlvf_index;
vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass);
vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); if (vlvf_index < 0) {
if (vlvf_index < 0) if (vlvf_bypass)
return vlvf_index; goto vfta_update;
return vlvf_index;
if (vlan_on) { }
/* set the pool bit */
if (vind < 32) {
bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB(vlvf_index*2));
bits |= (1 << vind);
IXGBE_WRITE_REG(hw,
IXGBE_VLVFB(vlvf_index*2),
bits);
} else {
bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB((vlvf_index*2)+1));
bits |= (1 << (vind-32));
IXGBE_WRITE_REG(hw,
IXGBE_VLVFB((vlvf_index*2)+1),
bits);
}
} else {
/* clear the pool bit */
if (vind < 32) {
bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB(vlvf_index*2));
bits &= ~(1 << vind);
IXGBE_WRITE_REG(hw,
IXGBE_VLVFB(vlvf_index*2),
bits);
bits |= IXGBE_READ_REG(hw,
IXGBE_VLVFB((vlvf_index*2)+1));
} else {
bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB((vlvf_index*2)+1));
bits &= ~(1 << (vind-32));
IXGBE_WRITE_REG(hw,
IXGBE_VLVFB((vlvf_index*2)+1),
bits);
bits |= IXGBE_READ_REG(hw,
IXGBE_VLVFB(vlvf_index*2));
}
}
/* bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32));
* If there are still bits set in the VLVFB registers
* for the VLAN ID indicated we need to see if the /* set the pool bit */
* caller is requesting that we clear the VFTA entry bit. bits |= 1 << (vind % 32);
* If the caller has requested that we clear the VFTA if (vlan_on)
* entry bit but there are still pools/VFs using this VLAN goto vlvf_update;
* ID entry then ignore the request. We're not worried
* about the case where we're turning the VFTA VLAN ID /* clear the pool bit */
* entry bit on, only when requested to turn it off as bits ^= 1 << (vind % 32);
* there may be multiple pools and/or VFs using the
* VLAN ID entry. In that case we cannot clear the if (!bits &&
* VFTA bit until all pools/VFs using that VLAN ID have also !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) {
* been cleared. This will be indicated by "bits" being /* Clear VFTA first, then disable VLVF. Otherwise
* zero. * we run the risk of stray packets leaking into
* the PF via the default pool
*/ */
if (bits) { if (vfta_delta)
IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
(IXGBE_VLVF_VIEN | vlan));
if (!vlan_on) { /* disable VLVF and clear remaining bit from pool */
/* someone wants to clear the vfta entry IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
* but some pools/VFs are still using it. IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0);
* Ignore it. */
vfta_changed = false; return 0;
}
} else {
IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
}
} }
if (vfta_changed) /* If there are still bits set in the VLVFB registers
IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); * for the VLAN ID indicated we need to see if the
* caller is requesting that we clear the VFTA entry bit.
* If the caller has requested that we clear the VFTA
* entry bit but there are still pools/VFs using this VLAN
* ID entry then ignore the request. We're not worried
* about the case where we're turning the VFTA VLAN ID
* entry bit on, only when requested to turn it off as
* there may be multiple pools and/or VFs using the
* VLAN ID entry. In that case we cannot clear the
* VFTA bit until all pools/VFs using that VLAN ID have also
* been cleared. This will be indicated by "bits" being
* zero.
*/
vfta_delta = 0;
vlvf_update:
/* record pool change and enable VLAN ID if not already enabled */
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits);
IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan);
vfta_update:
/* Update VFTA now that we are ready for traffic */
if (vfta_delta)
IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta);
return 0; return 0;
} }
...@@ -3196,8 +3170,8 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) ...@@ -3196,8 +3170,8 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0); IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0); IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0);
} }
return 0; return 0;
......
...@@ -92,7 +92,7 @@ s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq); ...@@ -92,7 +92,7 @@ s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq);
s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw); s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw);
s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan,
u32 vind, bool vlan_on); u32 vind, bool vlan_on, bool vlvf_bypass);
s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw);
s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw,
ixgbe_link_speed *speed, ixgbe_link_speed *speed,
......
...@@ -166,8 +166,6 @@ static int ixgbe_get_settings(struct net_device *netdev, ...@@ -166,8 +166,6 @@ static int ixgbe_get_settings(struct net_device *netdev,
/* set the supported link speeds */ /* set the supported link speeds */
if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
ecmd->supported |= SUPPORTED_10000baseT_Full; ecmd->supported |= SUPPORTED_10000baseT_Full;
if (supported_link & IXGBE_LINK_SPEED_2_5GB_FULL)
ecmd->supported |= SUPPORTED_2500baseX_Full;
if (supported_link & IXGBE_LINK_SPEED_1GB_FULL) if (supported_link & IXGBE_LINK_SPEED_1GB_FULL)
ecmd->supported |= SUPPORTED_1000baseT_Full; ecmd->supported |= SUPPORTED_1000baseT_Full;
if (supported_link & IXGBE_LINK_SPEED_100_FULL) if (supported_link & IXGBE_LINK_SPEED_100_FULL)
...@@ -179,8 +177,6 @@ static int ixgbe_get_settings(struct net_device *netdev, ...@@ -179,8 +177,6 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->advertising |= ADVERTISED_100baseT_Full; ecmd->advertising |= ADVERTISED_100baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
ecmd->advertising |= ADVERTISED_10000baseT_Full; ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
ecmd->advertising |= ADVERTISED_2500baseX_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
ecmd->advertising |= ADVERTISED_1000baseT_Full; ecmd->advertising |= ADVERTISED_1000baseT_Full;
} else { } else {
......
...@@ -3702,6 +3702,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) ...@@ -3702,6 +3702,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* Map PF MAC address in RAR Entry 0 to first pool following VFs */ /* Map PF MAC address in RAR Entry 0 to first pool following VFs */
hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0)); hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0));
/* clear VLAN promisc flag so VFTA will be updated if necessary */
adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
/* /*
* Set up VF register offsets for selected VT Mode, * Set up VF register offsets for selected VT Mode,
* i.e. 32 or 64 VFs for SR-IOV * i.e. 32 or 64 VFs for SR-IOV
...@@ -3899,12 +3902,56 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, ...@@ -3899,12 +3902,56 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
/* add VID to filter table */ /* add VID to filter table */
hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true); hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, true);
set_bit(vid, adapter->active_vlans); set_bit(vid, adapter->active_vlans);
return 0; return 0;
} }
static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
{
u32 vlvf;
int idx;
/* short cut the special case */
if (vlan == 0)
return 0;
/* Search for the vlan id in the VLVF entries */
for (idx = IXGBE_VLVF_ENTRIES; --idx;) {
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(idx));
if ((vlvf & VLAN_VID_MASK) == vlan)
break;
}
return idx;
}
void ixgbe_update_pf_promisc_vlvf(struct ixgbe_adapter *adapter, u32 vid)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 bits, word;
int idx;
idx = ixgbe_find_vlvf_entry(hw, vid);
if (!idx)
return;
/* See if any other pools are set for this VLAN filter
* entry other than the PF.
*/
word = idx * 2 + (VMDQ_P(0) / 32);
bits = ~(1 << (VMDQ_P(0)) % 32);
bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
/* Disable the filter so this falls into the default pool. */
if (!bits && !IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1))) {
if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), 0);
IXGBE_WRITE_REG(hw, IXGBE_VLVF(idx), 0);
}
}
static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
__be16 proto, u16 vid) __be16 proto, u16 vid)
{ {
...@@ -3912,7 +3959,11 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -3912,7 +3959,11 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
/* remove VID from filter table */ /* remove VID from filter table */
hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), false); if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
ixgbe_update_pf_promisc_vlvf(adapter, vid);
else
hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
clear_bit(vid, adapter->active_vlans); clear_bit(vid, adapter->active_vlans);
return 0; return 0;
...@@ -3990,6 +4041,129 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) ...@@ -3990,6 +4041,129 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
} }
} }
static void ixgbe_vlan_promisc_enable(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 vlnctrl, i;
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
default:
if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
break;
/* fall through */
case ixgbe_mac_82598EB:
/* legacy case, we can just disable VLAN filtering */
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
return;
}
/* We are already in VLAN promisc, nothing to do */
if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
return;
/* Set flag so we don't redo unnecessary work */
adapter->flags2 |= IXGBE_FLAG2_VLAN_PROMISC;
/* Add PF to all active pools */
for (i = IXGBE_VLVF_ENTRIES; --i;) {
u32 reg_offset = IXGBE_VLVFB(i * 2 + VMDQ_P(0) / 32);
u32 vlvfb = IXGBE_READ_REG(hw, reg_offset);
vlvfb |= 1 << (VMDQ_P(0) % 32);
IXGBE_WRITE_REG(hw, reg_offset, vlvfb);
}
/* Set all bits in the VLAN filter table array */
for (i = hw->mac.vft_size; i--;)
IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), ~0U);
}
#define VFTA_BLOCK_SIZE 8
static void ixgbe_scrub_vfta(struct ixgbe_adapter *adapter, u32 vfta_offset)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 vfta[VFTA_BLOCK_SIZE] = { 0 };
u32 vid_start = vfta_offset * 32;
u32 vid_end = vid_start + (VFTA_BLOCK_SIZE * 32);
u32 i, vid, word, bits;
for (i = IXGBE_VLVF_ENTRIES; --i;) {
u32 vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
/* pull VLAN ID from VLVF */
vid = vlvf & VLAN_VID_MASK;
/* only concern outselves with a certain range */
if (vid < vid_start || vid >= vid_end)
continue;
if (vlvf) {
/* record VLAN ID in VFTA */
vfta[(vid - vid_start) / 32] |= 1 << (vid % 32);
/* if PF is part of this then continue */
if (test_bit(vid, adapter->active_vlans))
continue;
}
/* remove PF from the pool */
word = i * 2 + VMDQ_P(0) / 32;
bits = ~(1 << (VMDQ_P(0) % 32));
bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), bits);
}
/* extract values from active_vlans and write back to VFTA */
for (i = VFTA_BLOCK_SIZE; i--;) {
vid = (vfta_offset + i) * 32;
word = vid / BITS_PER_LONG;
bits = vid % BITS_PER_LONG;
vfta[i] |= adapter->active_vlans[word] >> bits;
IXGBE_WRITE_REG(hw, IXGBE_VFTA(vfta_offset + i), vfta[i]);
}
}
static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 vlnctrl, i;
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
default:
if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
break;
/* fall through */
case ixgbe_mac_82598EB:
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
vlnctrl |= IXGBE_VLNCTRL_VFE;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
return;
}
/* We are not in VLAN promisc, nothing to do */
if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
return;
/* Set flag so we don't redo unnecessary work */
adapter->flags2 &= ~IXGBE_FLAG2_VLAN_PROMISC;
for (i = 0; i < hw->mac.vft_size; i += VFTA_BLOCK_SIZE)
ixgbe_scrub_vfta(adapter, i);
}
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
{ {
u16 vid; u16 vid;
...@@ -4246,12 +4420,10 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4246,12 +4420,10 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE; u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
u32 vlnctrl;
int count; int count;
/* Check for Promiscuous and All Multicast modes */ /* Check for Promiscuous and All Multicast modes */
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
/* set all bits that we expect to always be set */ /* set all bits that we expect to always be set */
fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */ fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
...@@ -4261,25 +4433,18 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4261,25 +4433,18 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
/* clear the bits we are changing the status of */ /* clear the bits we are changing the status of */
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
hw->addr_ctrl.user_set_promisc = true; hw->addr_ctrl.user_set_promisc = true;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vmolr |= IXGBE_VMOLR_MPE; vmolr |= IXGBE_VMOLR_MPE;
/* Only disable hardware filter vlans in promiscuous mode ixgbe_vlan_promisc_enable(adapter);
* if SR-IOV and VMDQ are disabled - otherwise ensure
* that hardware VLAN filters remain enabled.
*/
if (adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
IXGBE_FLAG_SRIOV_ENABLED))
vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
} else { } else {
if (netdev->flags & IFF_ALLMULTI) { if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE; fctrl |= IXGBE_FCTRL_MPE;
vmolr |= IXGBE_VMOLR_MPE; vmolr |= IXGBE_VMOLR_MPE;
} }
vlnctrl |= IXGBE_VLNCTRL_VFE;
hw->addr_ctrl.user_set_promisc = false; hw->addr_ctrl.user_set_promisc = false;
ixgbe_vlan_promisc_disable(adapter);
} }
/* /*
...@@ -4323,7 +4488,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4323,7 +4488,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
/* NOTE: VLAN filtering is disabled by setting PROMISC */ /* NOTE: VLAN filtering is disabled by setting PROMISC */
} }
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
...@@ -5381,6 +5545,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) ...@@ -5381,6 +5545,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) * adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
hw->mac.num_rar_entries, hw->mac.num_rar_entries,
GFP_ATOMIC); GFP_ATOMIC);
if (!adapter->mac_table)
return -ENOMEM;
/* Set MAC specific capability flags and exceptions */ /* Set MAC specific capability flags and exceptions */
switch (hw->mac.type) { switch (hw->mac.type) {
......
...@@ -452,11 +452,34 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) ...@@ -452,11 +452,34 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
u32 vf) u32 vf)
{ {
/* VLAN 0 is a special case, don't allow it to be removed */ struct ixgbe_hw *hw = &adapter->hw;
if (!vid && !add) int err;
return 0;
/* If VLAN overlaps with one the PF is currently monitoring make
* sure that we are able to allocate a VLVF entry. This may be
* redundant but it guarantees PF will maintain visibility to
* the VLAN.
*/
if (add && test_bit(vid, adapter->active_vlans)) {
err = hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), true, false);
if (err)
return err;
}
return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); err = hw->mac.ops.set_vfta(hw, vid, vf, !!add, false);
if (add && !err)
return err;
/* If we failed to add the VF VLAN or we are removing the VF VLAN
* we may need to drop the PF pool bit in order to allow us to free
* up the VLVF resources.
*/
if (test_bit(vid, adapter->active_vlans) ||
(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
ixgbe_update_pf_promisc_vlvf(adapter, vid);
return err;
} }
static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
...@@ -562,13 +585,75 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf) ...@@ -562,13 +585,75 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
} }
static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 i;
/* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
for (i = IXGBE_VLVF_ENTRIES; i--;) {
u32 word = IXGBE_VLVFB(i * 2 + vf / 32);
u32 bits[2], vlvfb, vid, vfta, vlvf;
u32 mask = 1 << (vf / 32);
vlvfb = IXGBE_READ_REG(hw, word);
/* if our bit isn't set we can skip it */
if (!(vlvfb & mask))
continue;
/* clear our bit from vlvfb */
vlvfb ^= mask;
/* create 64b mask to chedk to see if we should clear VLVF */
bits[word % 2] = vlvfb;
bits[(word % 2) ^ 1] = IXGBE_READ_REG(hw, word ^ 1);
/* if promisc is enabled, PF will be present, leave VFTA */
if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) {
bits[VMDQ_P(0) / 32] &= ~(1 << (VMDQ_P(0) % 32));
if (bits[0] || bits[1])
goto update_vlvfb;
goto update_vlvf;
}
/* if other pools are present, just remove ourselves */
if (bits[0] || bits[1])
goto update_vlvfb;
/* if we cannot determine VLAN just remove ourselves */
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
if (!vlvf)
goto update_vlvfb;
vid = vlvf & VLAN_VID_MASK;
mask = 1 << (vid % 32);
/* clear bit from VFTA */
vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(vid / 32));
if (vfta & mask)
IXGBE_WRITE_REG(hw, IXGBE_VFTA(vid / 32), vfta ^ mask);
update_vlvf:
/* clear POOL selection enable */
IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
update_vlvfb:
/* clear pool bits */
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
}
}
static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
u8 num_tcs = netdev_get_num_tc(adapter->netdev); u8 num_tcs = netdev_get_num_tc(adapter->netdev);
/* add PF assigned VLAN or VLAN 0 */ /* remove VLAN filters beloning to this VF */
ixgbe_clear_vf_vlans(adapter, vf);
/* add back PF assigned VLAN or VLAN 0 */
ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf); ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);
/* reset offloads to defaults */ /* reset offloads to defaults */
...@@ -814,40 +899,14 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter, ...@@ -814,40 +899,14 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0; return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0;
} }
static int ixgbe_find_vlvf_entry(struct ixgbe_hw *hw, u32 vlan)
{
u32 vlvf;
s32 regindex;
/* short cut the special case */
if (vlan == 0)
return 0;
/* Search for the vlan id in the VLVF entries */
for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
if ((vlvf & VLAN_VID_MASK) == vlan)
break;
}
/* Return a negative value if not found */
if (regindex >= IXGBE_VLVF_ENTRIES)
regindex = -1;
return regindex;
}
static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter, static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
u32 *msgbuf, u32 vf) u32 *msgbuf, u32 vf)
{ {
u32 add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
u32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
u8 tcs = netdev_get_num_tc(adapter->netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
int err; int err;
s32 reg_ndx;
u32 vlvf;
u32 bits;
u8 tcs = netdev_get_num_tc(adapter->netdev);
if (adapter->vfinfo[vf].pf_vlan || tcs) { if (adapter->vfinfo[vf].pf_vlan || tcs) {
e_warn(drv, e_warn(drv,
...@@ -857,54 +916,23 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter, ...@@ -857,54 +916,23 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
return -1; return -1;
} }
if (add) /* VLAN 0 is a special case, don't allow it to be removed */
adapter->vfinfo[vf].vlan_count++; if (!vid && !add)
else if (adapter->vfinfo[vf].vlan_count) return 0;
adapter->vfinfo[vf].vlan_count--;
/* in case of promiscuous mode any VLAN filter set for a VF must
* also have the PF pool added to it.
*/
if (add && adapter->netdev->flags & IFF_PROMISC)
err = ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
err = ixgbe_set_vf_vlan(adapter, add, vid, vf); err = ixgbe_set_vf_vlan(adapter, add, vid, vf);
if (!err && adapter->vfinfo[vf].spoofchk_enabled) if (err)
hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); return err;
/* Go through all the checks to see if the VLAN filter should if (adapter->vfinfo[vf].spoofchk_enabled)
* be wiped completely. hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
*/
if (!add && adapter->netdev->flags & IFF_PROMISC) {
reg_ndx = ixgbe_find_vlvf_entry(hw, vid);
if (reg_ndx < 0)
return err;
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx));
/* See if any other pools are set for this VLAN filter
* entry other than the PF.
*/
if (VMDQ_P(0) < 32) {
bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
bits &= ~(1 << VMDQ_P(0));
bits |= IXGBE_READ_REG(hw,
IXGBE_VLVFB(reg_ndx * 2) + 1);
} else {
bits = IXGBE_READ_REG(hw,
IXGBE_VLVFB(reg_ndx * 2) + 1);
bits &= ~(1 << (VMDQ_P(0) - 32));
bits |= IXGBE_READ_REG(hw, IXGBE_VLVFB(reg_ndx * 2));
}
/* If the filter was removed then ensure PF pool bit if (add)
* is cleared if the PF only added itself to the pool adapter->vfinfo[vf].vlan_count++;
* because the PF is in promiscuous mode. else if (adapter->vfinfo[vf].vlan_count)
*/ adapter->vfinfo[vf].vlan_count--;
if ((vlvf & VLAN_VID_MASK) == vid &&
!test_bit(vid, adapter->active_vlans) && !bits)
ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
}
return err; return 0;
} }
static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter, static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
...@@ -1285,6 +1313,9 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf, ...@@ -1285,6 +1313,9 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,
if (err) if (err)
goto out; goto out;
/* Revoke tagless access via VLAN 0 */
ixgbe_set_vf_vlan(adapter, false, 0, vf);
ixgbe_set_vmvir(adapter, vlan, qos, vf); ixgbe_set_vmvir(adapter, vlan, qos, vf);
ixgbe_set_vmolr(hw, vf, false); ixgbe_set_vmolr(hw, vf, false);
if (adapter->vfinfo[vf].spoofchk_enabled) if (adapter->vfinfo[vf].spoofchk_enabled)
...@@ -1318,6 +1349,8 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf) ...@@ -1318,6 +1349,8 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)
err = ixgbe_set_vf_vlan(adapter, false, err = ixgbe_set_vf_vlan(adapter, false,
adapter->vfinfo[vf].pf_vlan, vf); adapter->vfinfo[vf].pf_vlan, vf);
/* Restore tagless access via VLAN 0 */
ixgbe_set_vf_vlan(adapter, true, 0, vf);
ixgbe_clear_vmvir(adapter, vf); ixgbe_clear_vmvir(adapter, vf);
ixgbe_set_vmolr(hw, vf, true); ixgbe_set_vmolr(hw, vf, true);
hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
......
...@@ -3300,7 +3300,7 @@ struct ixgbe_mac_operations { ...@@ -3300,7 +3300,7 @@ struct ixgbe_mac_operations {
s32 (*enable_mc)(struct ixgbe_hw *); s32 (*enable_mc)(struct ixgbe_hw *);
s32 (*disable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *);
s32 (*clear_vfta)(struct ixgbe_hw *); s32 (*clear_vfta)(struct ixgbe_hw *);
s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool, bool);
s32 (*init_uta_tables)(struct ixgbe_hw *); s32 (*init_uta_tables)(struct ixgbe_hw *);
void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int); void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int);
void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int); void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int);
......
...@@ -154,12 +154,16 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) ...@@ -154,12 +154,16 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
/* Add the SAN MAC address to the RAR only if it's a valid address */ /* Add the SAN MAC address to the RAR only if it's a valid address */
if (is_valid_ether_addr(hw->mac.san_addr)) { if (is_valid_ether_addr(hw->mac.san_addr)) {
hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
hw->mac.san_addr, 0, IXGBE_RAH_AV);
/* Save the SAN MAC RAR index */ /* Save the SAN MAC RAR index */
hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
hw->mac.san_addr, 0, IXGBE_RAH_AV);
/* clear VMDq pool/queue selection for this RAR */
hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
IXGBE_CLEAR_VMDQ_ALL);
/* Reserve the last RAR for the SAN MAC address */ /* Reserve the last RAR for the SAN MAC address */
hw->mac.num_rar_entries--; hw->mac.num_rar_entries--;
} }
......
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