struct iavf_vsi {
        struct iavf_adapter *back;
        struct net_device *netdev;
-       unsigned long active_cvlans[BITS_TO_LONGS(VLAN_N_VID)];
-       unsigned long active_svlans[BITS_TO_LONGS(VLAN_N_VID)];
        u16 seid;
        u16 id;
        DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
        IAVF_VLAN_ADD,          /* filter needs to be added */
        IAVF_VLAN_IS_NEW,       /* filter is new, wait for PF answer */
        IAVF_VLAN_ACTIVE,       /* filter is accepted by PF */
-       IAVF_VLAN_REMOVE,       /* filter needs to be removed */
+       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 */
 };
 
 struct iavf_vlan_filter {
        wait_queue_head_t vc_waitqueue;
        struct iavf_q_vector *q_vectors;
        struct list_head vlan_filter_list;
+       int num_vlan_filters;
        struct list_head mac_filter_list;
        struct mutex crit_lock;
        struct mutex client_lock;
 
 
                list_add_tail(&f->list, &adapter->vlan_filter_list);
                f->state = IAVF_VLAN_ADD;
+               adapter->num_vlan_filters++;
                adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
        }
 
  **/
 static void iavf_restore_filters(struct iavf_adapter *adapter)
 {
-       u16 vid;
+       struct iavf_vlan_filter *f;
 
        /* re-add all VLAN filters */
-       for_each_set_bit(vid, adapter->vsi.active_cvlans, VLAN_N_VID)
-               iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021Q));
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
 
-       for_each_set_bit(vid, adapter->vsi.active_svlans, VLAN_N_VID)
-               iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021AD));
+       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;
 }
 
 /**
  */
 u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
 {
-       return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
-               bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
+       return adapter->num_vlan_filters;
 }
 
 /**
                return 0;
 
        iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));
-       if (proto == cpu_to_be16(ETH_P_8021Q))
-               clear_bit(vid, adapter->vsi.active_cvlans);
-       else
-               clear_bit(vid, adapter->vsi.active_svlans);
-
        return 0;
 }
 
                }
        }
 
-       /* remove all VLAN filters */
+       /* disable all VLAN filters */
        list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
-                                list) {
-               if (vlf->state == IAVF_VLAN_ADD) {
-                       list_del(&vlf->list);
-                       kfree(vlf);
-               } else {
-                       vlf->state = IAVF_VLAN_REMOVE;
-               }
-       }
+                                list)
+               vlf->state = IAVF_VLAN_DISABLE;
+
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 }
 
                list_del(&fv->list);
                kfree(fv);
        }
+       adapter->num_vlan_filters = 0;
 
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
        adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
        iavf_misc_irq_enable(adapter);
 
-       bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
-       bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
-
        mod_delayed_work(adapter->wq, &adapter->watchdog_task, 2);
 
        /* We were running when the reset started, so we need to restore some
 
        spin_lock_bh(&adapter->mac_vlan_list_lock);
        list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
                if (f->state == IAVF_VLAN_IS_NEW) {
-                       if (f->vlan.tpid == ETH_P_8021Q)
-                               clear_bit(f->vlan.vid,
-                                         adapter->vsi.active_cvlans);
-                       else
-                               clear_bit(f->vlan.vid,
-                                         adapter->vsi.active_svlans);
-
                        list_del(&f->list);
                        kfree(f);
+                       adapter->num_vlan_filters--;
                }
        }
        spin_unlock_bh(&adapter->mac_vlan_list_lock);
                    !VLAN_FILTERING_ALLOWED(adapter)) {
                        list_del(&f->list);
                        kfree(f);
-               } else if (f->state == IAVF_VLAN_REMOVE) {
+                       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) {
                        count++;
                }
        }
                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_REMOVE) {
+                       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) {
+                               vvfl->vlan_id[i] = f->vlan.vid;
                                list_del(&f->list);
                                kfree(f);
+                               adapter->num_vlan_filters--;
+                               i++;
                                if (i == count)
                                        break;
                        }
                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_REMOVE) {
+                       if (f->state == IAVF_VLAN_DISABLE ||
+                           f->state == IAVF_VLAN_REMOVE) {
                                struct virtchnl_vlan_supported_caps *filtering_support =
                                        &adapter->vlan_v2_caps.filtering.filtering_support;
                                struct virtchnl_vlan *vlan;
                                vlan->tci = f->vlan.vid;
                                vlan->tpid = f->vlan.tpid;
 
-                               list_del(&f->list);
-                               kfree(f);
+                               if (f->state == IAVF_VLAN_DISABLE) {
+                                       f->state = IAVF_VLAN_INACTIVE;
+                               } else {
+                                       list_del(&f->list);
+                                       kfree(f);
+                                       adapter->num_vlan_filters--;
+                               }
                                i++;
                                if (i == count)
                                        break;
 
                spin_lock_bh(&adapter->mac_vlan_list_lock);
                list_for_each_entry(f, &adapter->vlan_filter_list, list) {
-                       if (f->state == IAVF_VLAN_IS_NEW) {
+                       if (f->state == IAVF_VLAN_IS_NEW)
                                f->state = IAVF_VLAN_ACTIVE;
-                               if (f->vlan.tpid == ETH_P_8021Q)
-                                       set_bit(f->vlan.vid,
-                                               adapter->vsi.active_cvlans);
-                               else
-                                       set_bit(f->vlan.vid,
-                                               adapter->vsi.active_svlans);
-                       }
                }
                spin_unlock_bh(&adapter->mac_vlan_list_lock);
                }