iavf: Restore VLAN filters after link down
authorAkeem G Abodunrin <akeem.g.abodunrin@intel.com>
Fri, 4 Jun 2021 16:53:27 +0000 (09:53 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Nov 2021 08:48:36 +0000 (09:48 +0100)
[ Upstream commit 4293014230b887d94b68aa460ff00153454a3709 ]

Restore VLAN filters after the link is brought down, and up - since all
filters are deleted from HW during the netdev link down routine.

Fixes: ed1f5b58ea01 ("i40evf: remove VLAN filters on close")
Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Tested-by: George Kuruvinakunnel <george.kuruvinakunnel@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/iavf/iavf.h
drivers/net/ethernet/intel/iavf/iavf_main.c

index 68c80f04113c8dd32ecbeb3049e543cb40547d76..46312a4415baf75932e29fc33ccb90843ea176c2 100644 (file)
@@ -39,6 +39,7 @@
 #include "iavf_txrx.h"
 #include "iavf_fdir.h"
 #include "iavf_adv_rss.h"
+#include <linux/bitmap.h>
 
 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
 #define PFX "iavf: "
index d537d50525e3f1730b29b213f45d68c25a86f02e..aaf8a2f396e46d2a202af515339ad259f7d433dc 100644 (file)
@@ -687,6 +687,23 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan)
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
+/**
+ * iavf_restore_filters
+ * @adapter: board private structure
+ *
+ * Restore existing non MAC filters when VF netdev comes back up
+ **/
+static void iavf_restore_filters(struct iavf_adapter *adapter)
+{
+       /* re-add all VLAN filters */
+       if (VLAN_ALLOWED(adapter)) {
+               u16 vid;
+
+               for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID)
+                       iavf_add_vlan(adapter, vid);
+       }
+}
+
 /**
  * iavf_vlan_rx_add_vid - Add a VLAN filter to a device
  * @netdev: network device struct
@@ -700,8 +717,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
 
        if (!VLAN_ALLOWED(adapter))
                return -EIO;
+
        if (iavf_add_vlan(adapter, vid) == NULL)
                return -ENOMEM;
+
+       set_bit(vid, adapter->vsi.active_vlans);
        return 0;
 }
 
@@ -716,11 +736,13 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
 {
        struct iavf_adapter *adapter = netdev_priv(netdev);
 
-       if (VLAN_ALLOWED(adapter)) {
-               iavf_del_vlan(adapter, vid);
-               return 0;
-       }
-       return -EIO;
+       if (!VLAN_ALLOWED(adapter))
+               return -EIO;
+
+       iavf_del_vlan(adapter, vid);
+       clear_bit(vid, adapter->vsi.active_vlans);
+
+       return 0;
 }
 
 /**
@@ -3248,6 +3270,9 @@ static int iavf_open(struct net_device *netdev)
 
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
+       /* Restore VLAN filters that were removed with IFF_DOWN */
+       iavf_restore_filters(adapter);
+
        iavf_configure(adapter);
 
        iavf_up_complete(adapter);