]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ixgbe: Do not allow PF to add VLVF entry unless it actually needs it
authorAlexander Duyck <aduyck@mirantis.com>
Thu, 7 Jan 2016 06:48:44 +0000 (22:48 -0800)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 6 Jul 2016 23:41:03 +0000 (16:41 -0700)
Orabug: 23177316

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>
(cherry picked from commit 18be4fce00fef206dc6f104a6a258b193e9871cf)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

index b0a9e60faf8a31c19a663d2891af0b5116daffc1..096c51fe47af82e3b0941716715a7191a408bc43 100644 (file)
@@ -3902,7 +3902,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;
@@ -3959,9 +3961,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);
index 9e548fd642cb181881499b8339e43a4c7240b148..957c4c56ea62c76a745f6adc0f698d6648f3164f 100644 (file)
@@ -586,40 +586,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)
@@ -635,6 +635,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);