diff options
Diffstat (limited to 'drivers/net/ethernet/intel/iavf/iavf_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/iavf/iavf_main.c | 57 | 
1 files changed, 31 insertions, 26 deletions
| diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 3273aeb8fa67..2de4baff4c20 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -791,7 +791,8 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter,  		f->vlan = vlan;  		list_add_tail(&f->list, &adapter->vlan_filter_list); -		f->add = true; +		f->state = IAVF_VLAN_ADD; +		adapter->num_vlan_filters++;  		adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;  	} @@ -813,7 +814,7 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)  	f = iavf_find_vlan(adapter, vlan);  	if (f) { -		f->remove = true; +		f->state = IAVF_VLAN_REMOVE;  		adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;  	} @@ -828,14 +829,18 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)   **/  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); + +	list_for_each_entry(f, &adapter->vlan_filter_list, list) { +		if (f->state == IAVF_VLAN_INACTIVE) +			f->state = IAVF_VLAN_ADD; +	} -	for_each_set_bit(vid, adapter->vsi.active_svlans, VLAN_N_VID) -		iavf_add_vlan(adapter, IAVF_VLAN(vid, ETH_P_8021AD)); +	spin_unlock_bh(&adapter->mac_vlan_list_lock); +	adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;  }  /** @@ -844,8 +849,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)   */  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;  }  /** @@ -893,6 +897,10 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,  {  	struct iavf_adapter *adapter = netdev_priv(netdev); +	/* Do not track VLAN 0 filter, always added by the PF on VF init */ +	if (!vid) +		return 0; +  	if (!VLAN_FILTERING_ALLOWED(adapter))  		return -EIO; @@ -919,12 +927,11 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,  {  	struct iavf_adapter *adapter = netdev_priv(netdev); -	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); +	/* We do not track VLAN 0 filter */ +	if (!vid) +		return 0; +	iavf_del_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)));  	return 0;  } @@ -1285,16 +1292,11 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)  		}  	} -	/* remove all VLAN filters */ +	/* disable all VLAN filters */  	list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list, -				 list) { -		if (vlf->add) { -			list_del(&vlf->list); -			kfree(vlf); -		} else { -			vlf->remove = true; -		} -	} +				 list) +		vlf->state = IAVF_VLAN_DISABLE; +  	spin_unlock_bh(&adapter->mac_vlan_list_lock);  } @@ -2906,6 +2908,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)  		list_del(&fv->list);  		kfree(fv);  	} +	adapter->num_vlan_filters = 0;  	spin_unlock_bh(&adapter->mac_vlan_list_lock); @@ -3123,9 +3126,6 @@ continue_reset:  	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 @@ -5066,6 +5066,11 @@ static void iavf_remove(struct pci_dev *pdev)  			mutex_unlock(&adapter->crit_lock);  			break;  		} +		/* Simply return if we already went through iavf_shutdown */ +		if (adapter->state == __IAVF_REMOVE) { +			mutex_unlock(&adapter->crit_lock); +			return; +		}  		mutex_unlock(&adapter->crit_lock);  		usleep_range(500, 1000); |