diff options
Diffstat (limited to 'net/mac80211/iface.c')
| -rw-r--r-- | net/mac80211/iface.c | 26 | 
1 files changed, 26 insertions, 0 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 40ff0307d08..86c83084542 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -680,6 +680,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,  	struct sk_buff *skb, *tmp;  	u32 hw_reconf_flags = 0;  	int i, flushed; +	struct ps_data *ps;  	clear_bit(SDATA_STATE_RUNNING, &sdata->state); @@ -749,6 +750,16 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,  	cancel_work_sync(&sdata->recalc_smps); +	cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); + +	if (sdata->wdev.cac_started) { +		mutex_lock(&local->iflist_mtx); +		ieee80211_vif_release_channel(sdata); +		mutex_unlock(&local->iflist_mtx); +		cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, +				   GFP_KERNEL); +	} +  	/* APs need special treatment */  	if (sdata->vif.type == NL80211_IFTYPE_AP) {  		struct ieee80211_sub_if_data *vlan, *tmpsdata; @@ -758,6 +769,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,  					 u.vlan.list)  			dev_close(vlan->dev);  		WARN_ON(!list_empty(&sdata->u.ap.vlans)); +	} else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { +		/* remove all packets in parent bc_buf pointing to this dev */ +		ps = &sdata->bss->ps; + +		spin_lock_irqsave(&ps->bc_buf.lock, flags); +		skb_queue_walk_safe(&ps->bc_buf, skb, tmp) { +			if (skb->dev == sdata->dev) { +				__skb_unlink(skb, &ps->bc_buf); +				local->total_ps_buffered--; +				ieee80211_free_txskb(&local->hw, skb); +			} +		} +		spin_unlock_irqrestore(&ps->bc_buf.lock, flags);  	} else if (sdata->vif.type == NL80211_IFTYPE_STATION) {  		ieee80211_mgd_stop(sdata);  	} @@ -1513,6 +1537,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,  	spin_lock_init(&sdata->cleanup_stations_lock);  	INIT_LIST_HEAD(&sdata->cleanup_stations);  	INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk); +	INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work, +			  ieee80211_dfs_cac_timer_work);  	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {  		struct ieee80211_supported_band *sband;  |