Commit 18be4fce authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher

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: default avatarAlexander Duyck <aduyck@mirantis.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 1d96cf98
...@@ -3908,7 +3908,9 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, ...@@ -3908,7 +3908,9 @@ 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, 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); set_bit(vid, adapter->active_vlans);
return 0; return 0;
...@@ -3965,9 +3967,7 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -3965,9 +3967,7 @@ 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 */
if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) if (vid && !(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); hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
clear_bit(vid, adapter->active_vlans); clear_bit(vid, adapter->active_vlans);
......
...@@ -589,40 +589,40 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf) ...@@ -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) static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
{ {
struct ixgbe_hw *hw = &adapter->hw; 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 */ /* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
for (i = IXGBE_VLVF_ENTRIES; i--;) { for (i = IXGBE_VLVF_ENTRIES; i--;) {
u32 bits[2], vlvfb, vid, vfta, vlvf; u32 bits[2], vlvfb, vid, vfta, vlvf;
u32 word = i * 2 + vf / 32; u32 word = i * 2 + vf / 32;
u32 mask = 1 << (vf % 32); u32 mask;
vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word)); vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
/* if our bit isn't set we can skip it */ /* if our bit isn't set we can skip it */
if (!(vlvfb & mask)) if (!(vlvfb & vlvfb_mask))
continue; continue;
/* clear our bit from vlvfb */ /* clear our bit from vlvfb */
vlvfb ^= mask; vlvfb ^= vlvfb_mask;
/* create 64b mask to chedk to see if we should clear VLVF */ /* create 64b mask to chedk to see if we should clear VLVF */
bits[word % 2] = vlvfb; bits[word % 2] = vlvfb;
bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1)); 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 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; 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 */ /* if we cannot determine VLAN just remove ourselves */
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i)); vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
if (!vlvf) if (!vlvf)
...@@ -638,6 +638,9 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf) ...@@ -638,6 +638,9 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
update_vlvf: update_vlvf:
/* clear POOL selection enable */ /* clear POOL selection enable */
IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0); IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
vlvfb = 0;
update_vlvfb: update_vlvfb:
/* clear pool bits */ /* clear pool bits */
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb); IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
......
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