ixgbe: Do not allow PF to add VLVF entry unless it actually needs it
While doing the work on igb I realized there were a few cases where we were still adding VLANs to the VLVF entries for the PF when they were not needed. This patch cleans that up so that the only time we add a PF entry to the VLVF is either for VLAN 0 or if the PF has requested a VLAN that a VF is already using. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
1d96cf9822
commit
18be4fce00
|
@ -3908,7 +3908,9 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
|
|||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
/* add VID to filter table */
|
||||
hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, true);
|
||||
if (!vid || !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
|
||||
hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, !!vid);
|
||||
|
||||
set_bit(vid, adapter->active_vlans);
|
||||
|
||||
return 0;
|
||||
|
@ -3965,9 +3967,7 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
|
|||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
/* remove VID from filter table */
|
||||
if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC)
|
||||
ixgbe_update_pf_promisc_vlvf(adapter, vid);
|
||||
else
|
||||
if (vid && !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
|
||||
hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
|
||||
|
||||
clear_bit(vid, adapter->active_vlans);
|
||||
|
|
|
@ -589,40 +589,40 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
|
|||
static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u32 i;
|
||||
u32 vlvfb_mask, pool_mask, i;
|
||||
|
||||
/* create mask for VF and other pools */
|
||||
pool_mask = ~(1 << (VMDQ_P(0) % 32));
|
||||
vlvfb_mask = 1 << (vf % 32);
|
||||
|
||||
/* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
|
||||
for (i = IXGBE_VLVF_ENTRIES; i--;) {
|
||||
u32 bits[2], vlvfb, vid, vfta, vlvf;
|
||||
u32 word = i * 2 + vf / 32;
|
||||
u32 mask = 1 << (vf % 32);
|
||||
u32 mask;
|
||||
|
||||
vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
|
||||
|
||||
/* if our bit isn't set we can skip it */
|
||||
if (!(vlvfb & mask))
|
||||
if (!(vlvfb & vlvfb_mask))
|
||||
continue;
|
||||
|
||||
/* clear our bit from vlvfb */
|
||||
vlvfb ^= mask;
|
||||
vlvfb ^= vlvfb_mask;
|
||||
|
||||
/* create 64b mask to chedk to see if we should clear VLVF */
|
||||
bits[word % 2] = vlvfb;
|
||||
bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(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])
|
||||
if (bits[(VMDQ_P(0) / 32) ^ 1] ||
|
||||
(bits[VMDQ_P(0) / 32] & pool_mask))
|
||||
goto update_vlvfb;
|
||||
|
||||
/* if PF is present, leave VFTA */
|
||||
if (bits[0] || bits[1])
|
||||
goto update_vlvf;
|
||||
|
||||
/* if we cannot determine VLAN just remove ourselves */
|
||||
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
|
||||
if (!vlvf)
|
||||
|
@ -638,6 +638,9 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
|
|||
update_vlvf:
|
||||
/* clear POOL selection enable */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
|
||||
|
||||
if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
|
||||
vlvfb = 0;
|
||||
update_vlvfb:
|
||||
/* clear pool bits */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
|
||||
|
|
Loading…
Reference in New Issue