diff options
Diffstat (limited to 'net/mac80211/mlme.c')
| -rw-r--r-- | net/mac80211/mlme.c | 38 | 
1 files changed, 27 insertions, 11 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ecb4c84c1bb..295be92f7c7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2750,7 +2750,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,  {  	struct ieee80211_local *local = sdata->local;  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; -	struct ieee80211_work *wk;  	u8 bssid[ETH_ALEN];  	bool assoc_bss = false; @@ -2763,30 +2762,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,  		assoc_bss = true;  	} else {  		bool not_auth_yet = false; +		struct ieee80211_work *tmp, *wk = NULL;  		mutex_unlock(&ifmgd->mtx);  		mutex_lock(&local->mtx); -		list_for_each_entry(wk, &local->work_list, list) { -			if (wk->sdata != sdata) +		list_for_each_entry(tmp, &local->work_list, list) { +			if (tmp->sdata != sdata)  				continue; -			if (wk->type != IEEE80211_WORK_DIRECT_PROBE && -			    wk->type != IEEE80211_WORK_AUTH && -			    wk->type != IEEE80211_WORK_ASSOC && -			    wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) +			if (tmp->type != IEEE80211_WORK_DIRECT_PROBE && +			    tmp->type != IEEE80211_WORK_AUTH && +			    tmp->type != IEEE80211_WORK_ASSOC && +			    tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)  				continue; -			if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) +			if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))  				continue; -			not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE; -			list_del_rcu(&wk->list); -			free_work(wk); +			not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE; +			list_del_rcu(&tmp->list); +			synchronize_rcu(); +			wk = tmp;  			break;  		}  		mutex_unlock(&local->mtx); +		if (wk && wk->type == IEEE80211_WORK_ASSOC) { +			/* clean up dummy sta & TX sync */ +			sta_info_destroy_addr(wk->sdata, wk->filter_ta); +			if (wk->assoc.synced) +				drv_finish_tx_sync(local, wk->sdata, +						   wk->filter_ta, +						   IEEE80211_TX_SYNC_ASSOC); +		} else if (wk && wk->type == IEEE80211_WORK_AUTH) { +			if (wk->probe_auth.synced) +				drv_finish_tx_sync(local, wk->sdata, +						   wk->filter_ta, +						   IEEE80211_TX_SYNC_AUTH); +		} +		kfree(wk); +  		/*  		 * If somebody requests authentication and we haven't  		 * sent out an auth frame yet there's no need to send  |