[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.3 / 0018-mac80211-fix-work-removal-on-deauth-request.patch
1 From a4dc17d578486fb19207d32f2beb5d6526089777 Mon Sep 17 00:00:00 2001
2 From: Johannes Berg <johannes.berg@intel.com>
3 Date: Wed, 18 Jan 2012 14:10:25 +0100
4 Subject: [PATCH 18/90] mac80211: fix work removal on deauth request
6 commit bc4934bc61d0a11fd62c5187ff83645628f8be8b upstream.
8 When deauth is requested while an auth or assoc
9 work item is in progress, we currently delete it
10 without regard for any state it might need to
11 clean up. Fix it by cleaning up for those items.
13 In the case Pontus found, the problem manifested
14 itself as such:
16 authenticate with 00:23:69:aa:dd:7b (try 1)
17 authenticated
18 failed to insert Dummy STA entry for the AP (error -17)
19 deauthenticating from 00:23:69:aa:dd:7b by local choice (reason=2)
21 It could also happen differently if the driver
22 uses the tx_sync callback.
24 We can't just call the ->done() method of the work
25 items because that will lock up due to the locking
26 in cfg80211. This fix isn't very clean, but that
27 seems acceptable since I have patches pending to
28 remove this code completely.
30 Reported-by: Pontus Fuchs <pontus.fuchs@gmail.com>
31 Tested-by: Pontus Fuchs <pontus.fuchs@gmail.com>
32 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
33 Signed-off-by: John W. Linville <linville@tuxdriver.com>
34 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35 ---
36 net/mac80211/mlme.c | 38 +++++++++++++++++++++++++++-----------
37 1 file changed, 27 insertions(+), 11 deletions(-)
39 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
40 index b1b1bb3..9da8626 100644
41 --- a/net/mac80211/mlme.c
42 +++ b/net/mac80211/mlme.c
43 @@ -2719,7 +2719,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
44 {
45 struct ieee80211_local *local = sdata->local;
46 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
47 - struct ieee80211_work *wk;
48 u8 bssid[ETH_ALEN];
49 bool assoc_bss = false;
51 @@ -2732,30 +2731,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
52 assoc_bss = true;
53 } else {
54 bool not_auth_yet = false;
55 + struct ieee80211_work *tmp, *wk = NULL;
57 mutex_unlock(&ifmgd->mtx);
59 mutex_lock(&local->mtx);
60 - list_for_each_entry(wk, &local->work_list, list) {
61 - if (wk->sdata != sdata)
62 + list_for_each_entry(tmp, &local->work_list, list) {
63 + if (tmp->sdata != sdata)
64 continue;
66 - if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
67 - wk->type != IEEE80211_WORK_AUTH &&
68 - wk->type != IEEE80211_WORK_ASSOC &&
69 - wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
70 + if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
71 + tmp->type != IEEE80211_WORK_AUTH &&
72 + tmp->type != IEEE80211_WORK_ASSOC &&
73 + tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
74 continue;
76 - if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
77 + if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
78 continue;
80 - not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
81 - list_del_rcu(&wk->list);
82 - free_work(wk);
83 + not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
84 + list_del_rcu(&tmp->list);
85 + synchronize_rcu();
86 + wk = tmp;
87 break;
88 }
89 mutex_unlock(&local->mtx);
91 + if (wk && wk->type == IEEE80211_WORK_ASSOC) {
92 + /* clean up dummy sta & TX sync */
93 + sta_info_destroy_addr(wk->sdata, wk->filter_ta);
94 + if (wk->assoc.synced)
95 + drv_finish_tx_sync(local, wk->sdata,
96 + wk->filter_ta,
97 + IEEE80211_TX_SYNC_ASSOC);
98 + } else if (wk && wk->type == IEEE80211_WORK_AUTH) {
99 + if (wk->probe_auth.synced)
100 + drv_finish_tx_sync(local, wk->sdata,
101 + wk->filter_ta,
102 + IEEE80211_TX_SYNC_AUTH);
103 + }
104 + kfree(wk);
105 +
106 /*
107 * If somebody requests authentication and we haven't
108 * sent out an auth frame yet there's no need to send
109 --
110 1.7.9.4