|
@@ -2759,7 +2759,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|
{
|
|
{
|
|
struct ieee80211_local *local = sdata->local;
|
|
struct ieee80211_local *local = sdata->local;
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
- struct ieee80211_work *wk;
|
|
|
|
u8 bssid[ETH_ALEN];
|
|
u8 bssid[ETH_ALEN];
|
|
bool assoc_bss = false;
|
|
bool assoc_bss = false;
|
|
|
|
|
|
@@ -2772,30 +2771,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|
assoc_bss = true;
|
|
assoc_bss = true;
|
|
} else {
|
|
} else {
|
|
bool not_auth_yet = false;
|
|
bool not_auth_yet = false;
|
|
|
|
+ struct ieee80211_work *tmp, *wk = NULL;
|
|
|
|
|
|
mutex_unlock(&ifmgd->mtx);
|
|
mutex_unlock(&ifmgd->mtx);
|
|
|
|
|
|
mutex_lock(&local->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;
|
|
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;
|
|
continue;
|
|
|
|
|
|
- if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
|
|
|
|
|
|
+ if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
|
|
continue;
|
|
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;
|
|
break;
|
|
}
|
|
}
|
|
mutex_unlock(&local->mtx);
|
|
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
|
|
* If somebody requests authentication and we haven't
|
|
* sent out an auth frame yet there's no need to send
|
|
* sent out an auth frame yet there's no need to send
|