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 ecb4c84c1bb3..295be92f7c77 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, | |||
2750 | { | 2750 | { |
2751 | struct ieee80211_local *local = sdata->local; | 2751 | struct ieee80211_local *local = sdata->local; |
2752 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2752 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2753 | struct ieee80211_work *wk; | ||
2754 | u8 bssid[ETH_ALEN]; | 2753 | u8 bssid[ETH_ALEN]; |
2755 | bool assoc_bss = false; | 2754 | bool assoc_bss = false; |
2756 | 2755 | ||
@@ -2763,30 +2762,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2763 | assoc_bss = true; | 2762 | assoc_bss = true; |
2764 | } else { | 2763 | } else { |
2765 | bool not_auth_yet = false; | 2764 | bool not_auth_yet = false; |
2765 | struct ieee80211_work *tmp, *wk = NULL; | ||
2766 | 2766 | ||
2767 | mutex_unlock(&ifmgd->mtx); | 2767 | mutex_unlock(&ifmgd->mtx); |
2768 | 2768 | ||
2769 | mutex_lock(&local->mtx); | 2769 | mutex_lock(&local->mtx); |
2770 | list_for_each_entry(wk, &local->work_list, list) { | 2770 | list_for_each_entry(tmp, &local->work_list, list) { |
2771 | if (wk->sdata != sdata) | 2771 | if (tmp->sdata != sdata) |
2772 | continue; | 2772 | continue; |
2773 | 2773 | ||
2774 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && | 2774 | if (tmp->type != IEEE80211_WORK_DIRECT_PROBE && |
2775 | wk->type != IEEE80211_WORK_AUTH && | 2775 | tmp->type != IEEE80211_WORK_AUTH && |
2776 | wk->type != IEEE80211_WORK_ASSOC && | 2776 | tmp->type != IEEE80211_WORK_ASSOC && |
2777 | wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) | 2777 | tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) |
2778 | continue; | 2778 | continue; |
2779 | 2779 | ||
2780 | if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) | 2780 | if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN)) |
2781 | continue; | 2781 | continue; |
2782 | 2782 | ||
2783 | not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE; | 2783 | not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE; |
2784 | list_del_rcu(&wk->list); | 2784 | list_del_rcu(&tmp->list); |
2785 | free_work(wk); | 2785 | synchronize_rcu(); |
2786 | wk = tmp; | ||
2786 | break; | 2787 | break; |
2787 | } | 2788 | } |
2788 | mutex_unlock(&local->mtx); | 2789 | mutex_unlock(&local->mtx); |
2789 | 2790 | ||
2791 | if (wk && wk->type == IEEE80211_WORK_ASSOC) { | ||
2792 | /* clean up dummy sta & TX sync */ | ||
2793 | sta_info_destroy_addr(wk->sdata, wk->filter_ta); | ||
2794 | if (wk->assoc.synced) | ||
2795 | drv_finish_tx_sync(local, wk->sdata, | ||
2796 | wk->filter_ta, | ||
2797 | IEEE80211_TX_SYNC_ASSOC); | ||
2798 | } else if (wk && wk->type == IEEE80211_WORK_AUTH) { | ||
2799 | if (wk->probe_auth.synced) | ||
2800 | drv_finish_tx_sync(local, wk->sdata, | ||
2801 | wk->filter_ta, | ||
2802 | IEEE80211_TX_SYNC_AUTH); | ||
2803 | } | ||
2804 | kfree(wk); | ||
2805 | |||
2790 | /* | 2806 | /* |
2791 | * If somebody requests authentication and we haven't | 2807 | * If somebody requests authentication and we haven't |
2792 | * sent out an auth frame yet there's no need to send | 2808 | * sent out an auth frame yet there's no need to send |