When a VF goes down, the driver currently sends DEL_VLAN to the PF for
every VLAN filter (ACTIVE -> DISABLE -> send DEL -> INACTIVE), then
re-adds them all on UP (INACTIVE -> ADD -> send ADD -> ADDING ->
ACTIVE). This round-trip is unnecessary because:

 1. The PF disables the VF's queues via VIRTCHNL_OP_DISABLE_QUEUES,
    which already prevents all RX/TX traffic regardless of VLAN filter
    state.

 2. The VLAN filters remaining in PF HW while the VF is down is
    harmless - packets matching those filters have nowhere to go with
    queues disabled.

 3. The DEL+ADD cycle during down/up creates race windows where the
    VLAN filter list is incomplete. With spoofcheck enabled, the PF
    enables TX VLAN filtering on the first non-zero VLAN add, blocking
    traffic for any VLANs not yet re-added.

Remove the entire DISABLE/INACTIVE state machinery:
 - Remove IAVF_VLAN_DISABLE and IAVF_VLAN_INACTIVE enum values
 - Remove iavf_restore_filters() and its call from iavf_open()
 - Remove VLAN filter handling from iavf_clear_mac_vlan_filters(),
   rename it to iavf_clear_mac_filters()
 - Remove DEL_VLAN_FILTER scheduling from iavf_down()
 - Remove all DISABLE/INACTIVE handling from iavf_del_vlans()

VLAN filters now stay ACTIVE across down/up cycles. Only explicit
user removal (ndo_vlan_rx_kill_vid) or PF/VF reset triggers VLAN
filter deletion/re-addition.

Signed-off-by: Petr Oros <[email protected]>
---
 drivers/net/ethernet/intel/iavf/iavf.h        |  6 +--
 drivers/net/ethernet/intel/iavf/iavf_main.c   | 39 ++-----------------
 .../net/ethernet/intel/iavf/iavf_virtchnl.c   | 33 +++-------------
 3 files changed, 12 insertions(+), 66 deletions(-)

diff --git a/drivers/net/ethernet/intel/iavf/iavf.h 
b/drivers/net/ethernet/intel/iavf/iavf.h
index 8e6db72828ae14..1ad00690622c8e 100644
--- a/drivers/net/ethernet/intel/iavf/iavf.h
+++ b/drivers/net/ethernet/intel/iavf/iavf.h
@@ -159,10 +159,8 @@ enum iavf_vlan_state_t {
        IAVF_VLAN_INVALID,
        IAVF_VLAN_ADD,          /* filter needs to be added */
        IAVF_VLAN_ADDING,       /* ADD sent to PF, waiting for response */
-       IAVF_VLAN_ACTIVE,       /* filter is accepted by PF */
-       IAVF_VLAN_DISABLE,      /* filter needs to be deleted by PF, then 
marked INACTIVE */
-       IAVF_VLAN_INACTIVE,     /* filter is inactive, we are in IFF_DOWN */
-       IAVF_VLAN_REMOVE,       /* filter needs to be removed from list */
+       IAVF_VLAN_ACTIVE,       /* PF confirmed, filter is in HW */
+       IAVF_VLAN_REMOVE,       /* filter queued for DEL from PF */
 };
 
 struct iavf_vlan_filter {
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c 
b/drivers/net/ethernet/intel/iavf/iavf_main.c
index bceaf4b1b85d5f..f1ab68f5f4050b 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -823,27 +823,6 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, 
struct iavf_vlan 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)
-{
-       struct iavf_vlan_filter *f;
-
-       /* re-add all VLAN filters */
-       spin_lock_bh(&adapter->mac_vlan_list_lock);
-
-       list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-               if (f->state == IAVF_VLAN_INACTIVE)
-                       f->state = IAVF_VLAN_ADD;
-       }
-
-       spin_unlock_bh(&adapter->mac_vlan_list_lock);
-       adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
-}
 
 /**
  * iavf_get_num_vlans_added - get number of VLANs added
@@ -1262,13 +1241,12 @@ static void iavf_up_complete(struct iavf_adapter 
*adapter)
 }
 
 /**
- * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF
- * yet and mark other to be removed.
+ * iavf_clear_mac_filters - Remove MAC filters not sent to PF yet and mark
+ * others to be removed.
  * @adapter: board private structure
  **/
-static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
+static void iavf_clear_mac_filters(struct iavf_adapter *adapter)
 {
-       struct iavf_vlan_filter *vlf, *vlftmp;
        struct iavf_mac_filter *f, *ftmp;
 
        spin_lock_bh(&adapter->mac_vlan_list_lock);
@@ -1287,11 +1265,6 @@ static void iavf_clear_mac_vlan_filters(struct 
iavf_adapter *adapter)
                }
        }
 
-       /* disable all VLAN filters */
-       list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
-                                list)
-               vlf->state = IAVF_VLAN_DISABLE;
-
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
@@ -1387,7 +1360,7 @@ void iavf_down(struct iavf_adapter *adapter)
        iavf_napi_disable_all(adapter);
        iavf_irq_disable(adapter);
 
-       iavf_clear_mac_vlan_filters(adapter);
+       iavf_clear_mac_filters(adapter);
        iavf_clear_cloud_filters(adapter);
        iavf_clear_fdir_filters(adapter);
        iavf_clear_adv_rss_conf(adapter);
@@ -1404,8 +1377,6 @@ void iavf_down(struct iavf_adapter *adapter)
                 */
                if (!list_empty(&adapter->mac_filter_list))
                        adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER;
-               if (!list_empty(&adapter->vlan_filter_list))
-                       adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
                if (!list_empty(&adapter->cloud_filter_list))
                        adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
                if (!list_empty(&adapter->fdir_list_head))
@@ -4487,8 +4458,6 @@ static int iavf_open(struct net_device *netdev)
        iavf_add_filter(adapter, adapter->hw.mac.addr);
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
-       /* Restore filters that were removed with IFF_DOWN */
-       iavf_restore_filters(adapter);
        iavf_restore_fdir_filters(adapter);
 
        iavf_configure(adapter);
diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c 
b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
index 5114934fe81fa6..d62c0d6394149e 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
@@ -911,22 +911,12 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
        spin_lock_bh(&adapter->mac_vlan_list_lock);
 
        list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
-               /* since VLAN capabilities are not allowed, we dont want to send
-                * a VLAN delete request because it will most likely fail and
-                * create unnecessary errors/noise, so just free the VLAN
-                * filters marked for removal to enable bailing out before
-                * sending a virtchnl message
-                */
                if (f->state == IAVF_VLAN_REMOVE &&
                    !VLAN_FILTERING_ALLOWED(adapter)) {
                        list_del(&f->list);
                        kfree(f);
                        adapter->num_vlan_filters--;
-               } else if (f->state == IAVF_VLAN_DISABLE &&
-                   !VLAN_FILTERING_ALLOWED(adapter)) {
-                       f->state = IAVF_VLAN_INACTIVE;
-               } else if (f->state == IAVF_VLAN_REMOVE ||
-                          f->state == IAVF_VLAN_DISABLE) {
+               } else if (f->state == IAVF_VLAN_REMOVE) {
                        count++;
                }
        }
@@ -959,13 +949,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                vvfl->vsi_id = adapter->vsi_res->vsi_id;
                vvfl->num_elements = count;
                list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, 
list) {
-                       if (f->state == IAVF_VLAN_DISABLE) {
-                               vvfl->vlan_id[i] = f->vlan.vid;
-                               f->state = IAVF_VLAN_INACTIVE;
-                               i++;
-                               if (i == count)
-                                       break;
-                       } else if (f->state == IAVF_VLAN_REMOVE) {
+                       if (f->state == IAVF_VLAN_REMOVE) {
                                vvfl->vlan_id[i] = f->vlan.vid;
                                list_del(&f->list);
                                kfree(f);
@@ -1007,8 +991,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
                vvfl_v2->num_elements = count;
                list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, 
list) {
-                       if (f->state == IAVF_VLAN_DISABLE ||
-                           f->state == IAVF_VLAN_REMOVE) {
+                       if (f->state == IAVF_VLAN_REMOVE) {
                                struct virtchnl_vlan_supported_caps 
*filtering_support =
                                        
&adapter->vlan_v2_caps.filtering.filtering_support;
                                struct virtchnl_vlan *vlan;
@@ -1022,13 +1005,9 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
                                vlan->tci = f->vlan.vid;
                                vlan->tpid = f->vlan.tpid;
 
-                               if (f->state == IAVF_VLAN_DISABLE) {
-                                       f->state = IAVF_VLAN_INACTIVE;
-                               } else {
-                                       list_del(&f->list);
-                                       kfree(f);
-                                       adapter->num_vlan_filters--;
-                               }
+                               list_del(&f->list);
+                               kfree(f);
+                               adapter->num_vlan_filters--;
                                i++;
                                if (i == count)
                                        break;
-- 
2.52.0

Reply via email to