aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c1332
1 files changed, 700 insertions, 632 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 29575eea3ed1..108e8c9c60fd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -27,20 +27,51 @@
27#include "rate.h" 27#include "rate.h"
28#include "led.h" 28#include "led.h"
29 29
30#define IEEE80211_ASSOC_SCANS_MAX_TRIES 2
31#define IEEE80211_AUTH_TIMEOUT (HZ / 5) 30#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
32#define IEEE80211_AUTH_MAX_TRIES 3 31#define IEEE80211_AUTH_MAX_TRIES 3
33#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
34#define IEEE80211_ASSOC_MAX_TRIES 3 33#define IEEE80211_ASSOC_MAX_TRIES 3
35#define IEEE80211_MONITORING_INTERVAL (2 * HZ) 34#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
36#define IEEE80211_PROBE_WAIT (HZ / 5) 35#define IEEE80211_PROBE_WAIT (HZ / 5)
37#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
38#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
39 36
40#define TMR_RUNNING_TIMER 0 37#define TMR_RUNNING_TIMER 0
41#define TMR_RUNNING_CHANSW 1 38#define TMR_RUNNING_CHANSW 1
42 39
40/*
41 * All cfg80211 functions have to be called outside a locked
42 * section so that they can acquire a lock themselves... This
43 * is much simpler than queuing up things in cfg80211, but we
44 * do need some indirection for that here.
45 */
46enum rx_mgmt_action {
47 /* no action required */
48 RX_MGMT_NONE,
49
50 /* caller must call cfg80211_send_rx_auth() */
51 RX_MGMT_CFG80211_AUTH,
52
53 /* caller must call cfg80211_send_rx_assoc() */
54 RX_MGMT_CFG80211_ASSOC,
55
56 /* caller must call cfg80211_send_deauth() */
57 RX_MGMT_CFG80211_DEAUTH,
58
59 /* caller must call cfg80211_send_disassoc() */
60 RX_MGMT_CFG80211_DISASSOC,
61
62 /* caller must call cfg80211_auth_timeout() & free work */
63 RX_MGMT_CFG80211_AUTH_TO,
64
65 /* caller must call cfg80211_assoc_timeout() & free work */
66 RX_MGMT_CFG80211_ASSOC_TO,
67};
68
43/* utils */ 69/* utils */
70static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
71{
72 WARN_ON(!mutex_is_locked(&ifmgd->mtx));
73}
74
44static int ecw2cw(int ecw) 75static int ecw2cw(int ecw)
45{ 76{
46 return (1 << ecw) - 1; 77 return (1 << ecw) - 1;
@@ -74,11 +105,10 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
74 */ 105 */
75static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, 106static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
76 struct ieee80211_ht_info *hti, 107 struct ieee80211_ht_info *hti,
77 u16 ap_ht_cap_flags) 108 const u8 *bssid, u16 ap_ht_cap_flags)
78{ 109{
79 struct ieee80211_local *local = sdata->local; 110 struct ieee80211_local *local = sdata->local;
80 struct ieee80211_supported_band *sband; 111 struct ieee80211_supported_band *sband;
81 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
82 struct sta_info *sta; 112 struct sta_info *sta;
83 u32 changed = 0; 113 u32 changed = 0;
84 u16 ht_opmode; 114 u16 ht_opmode;
@@ -127,12 +157,10 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
127 ieee80211_hw_config(local, 0); 157 ieee80211_hw_config(local, 0);
128 158
129 rcu_read_lock(); 159 rcu_read_lock();
130 160 sta = sta_info_get(local, bssid);
131 sta = sta_info_get(local, ifmgd->bssid);
132 if (sta) 161 if (sta)
133 rate_control_rate_update(local, sband, sta, 162 rate_control_rate_update(local, sband, sta,
134 IEEE80211_RC_HT_CHANGED); 163 IEEE80211_RC_HT_CHANGED);
135
136 rcu_read_unlock(); 164 rcu_read_unlock();
137 } 165 }
138 166
@@ -155,7 +183,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
155 183
156/* frame sending functions */ 184/* frame sending functions */
157 185
158static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 186static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
187 struct ieee80211_mgd_work *wk)
159{ 188{
160 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 189 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
161 struct ieee80211_local *local = sdata->local; 190 struct ieee80211_local *local = sdata->local;
@@ -165,14 +194,13 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
165 const u8 *ies, *ht_ie; 194 const u8 *ies, *ht_ie;
166 int i, len, count, rates_len, supp_rates_len; 195 int i, len, count, rates_len, supp_rates_len;
167 u16 capab; 196 u16 capab;
168 struct ieee80211_bss *bss;
169 int wmm = 0; 197 int wmm = 0;
170 struct ieee80211_supported_band *sband; 198 struct ieee80211_supported_band *sband;
171 u32 rates = 0; 199 u32 rates = 0;
172 200
173 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 201 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
174 sizeof(*mgmt) + 200 + ifmgd->extra_ie_len + 202 sizeof(*mgmt) + 200 + wk->ie_len +
175 ifmgd->ssid_len); 203 wk->ssid_len);
176 if (!skb) { 204 if (!skb) {
177 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 205 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
178 "frame\n", sdata->dev->name); 206 "frame\n", sdata->dev->name);
@@ -191,45 +219,35 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
191 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; 219 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
192 } 220 }
193 221
194 bss = ieee80211_rx_bss_get(local, ifmgd->bssid, 222 if (wk->bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
195 local->hw.conf.channel->center_freq, 223 capab |= WLAN_CAPABILITY_PRIVACY;
196 ifmgd->ssid, ifmgd->ssid_len); 224 if (wk->bss->wmm_used)
197 if (bss) { 225 wmm = 1;
198 if (bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
199 capab |= WLAN_CAPABILITY_PRIVACY;
200 if (bss->wmm_used)
201 wmm = 1;
202 226
203 /* get all rates supported by the device and the AP as 227 /* get all rates supported by the device and the AP as
204 * some APs don't like getting a superset of their rates 228 * some APs don't like getting a superset of their rates
205 * in the association request (e.g. D-Link DAP 1353 in 229 * in the association request (e.g. D-Link DAP 1353 in
206 * b-only mode) */ 230 * b-only mode) */
207 rates_len = ieee80211_compatible_rates(bss, sband, &rates); 231 rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates);
208 232
209 if ((bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && 233 if ((wk->bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
210 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) 234 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
211 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; 235 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
212
213 ieee80211_rx_bss_put(local, bss);
214 } else {
215 rates = ~0;
216 rates_len = sband->n_bitrates;
217 }
218 236
219 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 237 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
220 memset(mgmt, 0, 24); 238 memset(mgmt, 0, 24);
221 memcpy(mgmt->da, ifmgd->bssid, ETH_ALEN); 239 memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN);
222 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 240 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
223 memcpy(mgmt->bssid, ifmgd->bssid, ETH_ALEN); 241 memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN);
224 242
225 if (ifmgd->flags & IEEE80211_STA_PREV_BSSID_SET) { 243 if (!is_zero_ether_addr(wk->prev_bssid)) {
226 skb_put(skb, 10); 244 skb_put(skb, 10);
227 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 245 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
228 IEEE80211_STYPE_REASSOC_REQ); 246 IEEE80211_STYPE_REASSOC_REQ);
229 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); 247 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
230 mgmt->u.reassoc_req.listen_interval = 248 mgmt->u.reassoc_req.listen_interval =
231 cpu_to_le16(local->hw.conf.listen_interval); 249 cpu_to_le16(local->hw.conf.listen_interval);
232 memcpy(mgmt->u.reassoc_req.current_ap, ifmgd->prev_bssid, 250 memcpy(mgmt->u.reassoc_req.current_ap, wk->prev_bssid,
233 ETH_ALEN); 251 ETH_ALEN);
234 } else { 252 } else {
235 skb_put(skb, 4); 253 skb_put(skb, 4);
@@ -241,10 +259,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
241 } 259 }
242 260
243 /* SSID */ 261 /* SSID */
244 ies = pos = skb_put(skb, 2 + ifmgd->ssid_len); 262 ies = pos = skb_put(skb, 2 + wk->ssid_len);
245 *pos++ = WLAN_EID_SSID; 263 *pos++ = WLAN_EID_SSID;
246 *pos++ = ifmgd->ssid_len; 264 *pos++ = wk->ssid_len;
247 memcpy(pos, ifmgd->ssid, ifmgd->ssid_len); 265 memcpy(pos, wk->ssid, wk->ssid_len);
248 266
249 /* add all rates which were marked to be used above */ 267 /* add all rates which were marked to be used above */
250 supp_rates_len = rates_len; 268 supp_rates_len = rates_len;
@@ -299,9 +317,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
299 } 317 }
300 } 318 }
301 319
302 if (ifmgd->extra_ie) { 320 if (wk->ie_len && wk->ie) {
303 pos = skb_put(skb, ifmgd->extra_ie_len); 321 pos = skb_put(skb, wk->ie_len);
304 memcpy(pos, ifmgd->extra_ie, ifmgd->extra_ie_len); 322 memcpy(pos, wk->ie, wk->ie_len);
305 } 323 }
306 324
307 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) { 325 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) {
@@ -326,7 +344,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
326 */ 344 */
327 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && 345 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
328 sband->ht_cap.ht_supported && 346 sband->ht_cap.ht_supported &&
329 (ht_ie = ieee80211_bss_get_ie(&bss->cbss, WLAN_EID_HT_INFORMATION)) && 347 (ht_ie = ieee80211_bss_get_ie(&wk->bss->cbss, WLAN_EID_HT_INFORMATION)) &&
330 ht_ie[1] >= sizeof(struct ieee80211_ht_info) && 348 ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
331 (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) { 349 (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
332 struct ieee80211_ht_info *ht_info = 350 struct ieee80211_ht_info *ht_info =
@@ -363,18 +381,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
363 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 381 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
364 } 382 }
365 383
366 kfree(ifmgd->assocreq_ies);
367 ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies;
368 ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL);
369 if (ifmgd->assocreq_ies)
370 memcpy(ifmgd->assocreq_ies, ies, ifmgd->assocreq_ies_len);
371
372 ieee80211_tx_skb(sdata, skb, 0); 384 ieee80211_tx_skb(sdata, skb, 0);
373} 385}
374 386
375 387
376static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 388static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
377 u16 stype, u16 reason) 389 const u8 *bssid, u16 stype, u16 reason)
378{ 390{
379 struct ieee80211_local *local = sdata->local; 391 struct ieee80211_local *local = sdata->local;
380 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 392 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -391,9 +403,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
391 403
392 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 404 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
393 memset(mgmt, 0, 24); 405 memset(mgmt, 0, 24);
394 memcpy(mgmt->da, ifmgd->bssid, ETH_ALEN); 406 memcpy(mgmt->da, bssid, ETH_ALEN);
395 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 407 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
396 memcpy(mgmt->bssid, ifmgd->bssid, ETH_ALEN); 408 memcpy(mgmt->bssid, bssid, ETH_ALEN);
397 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype); 409 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
398 skb_put(skb, 2); 410 skb_put(skb, 2);
399 /* u.deauth.reason_code == u.disassoc.reason_code */ 411 /* u.deauth.reason_code == u.disassoc.reason_code */
@@ -477,28 +489,26 @@ static void ieee80211_chswitch_work(struct work_struct *work)
477{ 489{
478 struct ieee80211_sub_if_data *sdata = 490 struct ieee80211_sub_if_data *sdata =
479 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); 491 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
480 struct ieee80211_bss *bss;
481 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 492 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
482 493
483 if (!netif_running(sdata->dev)) 494 if (!netif_running(sdata->dev))
484 return; 495 return;
485 496
486 bss = ieee80211_rx_bss_get(sdata->local, ifmgd->bssid, 497 mutex_lock(&ifmgd->mtx);
487 sdata->local->hw.conf.channel->center_freq, 498 if (!ifmgd->associated)
488 ifmgd->ssid, ifmgd->ssid_len); 499 goto out;
489 if (!bss)
490 goto exit;
491 500
492 sdata->local->oper_channel = sdata->local->csa_channel; 501 sdata->local->oper_channel = sdata->local->csa_channel;
502 ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL);
503
493 /* XXX: shouldn't really modify cfg80211-owned data! */ 504 /* XXX: shouldn't really modify cfg80211-owned data! */
494 if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL)) 505 ifmgd->associated->cbss.channel = sdata->local->oper_channel;
495 bss->cbss.channel = sdata->local->oper_channel;
496 506
497 ieee80211_rx_bss_put(sdata->local, bss);
498exit:
499 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
500 ieee80211_wake_queues_by_reason(&sdata->local->hw, 507 ieee80211_wake_queues_by_reason(&sdata->local->hw,
501 IEEE80211_QUEUE_STOP_REASON_CSA); 508 IEEE80211_QUEUE_STOP_REASON_CSA);
509 out:
510 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
511 mutex_unlock(&ifmgd->mtx);
502} 512}
503 513
504static void ieee80211_chswitch_timer(unsigned long data) 514static void ieee80211_chswitch_timer(unsigned long data)
@@ -523,7 +533,9 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
523 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 533 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
524 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num); 534 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
525 535
526 if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATED) 536 ASSERT_MGD_MTX(ifmgd);
537
538 if (!ifmgd->associated)
527 return; 539 return;
528 540
529 if (sdata->local->sw_scanning || sdata->local->hw_scanning) 541 if (sdata->local->sw_scanning || sdata->local->hw_scanning)
@@ -634,7 +646,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
634 } 646 }
635 647
636 if (count == 1 && found->u.mgd.powersave && 648 if (count == 1 && found->u.mgd.powersave &&
637 (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) && 649 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) &&
638 !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { 650 !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) {
639 s32 beaconint_us; 651 s32 beaconint_us;
640 652
@@ -789,9 +801,6 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
789 u16 capab, bool erp_valid, u8 erp) 801 u16 capab, bool erp_valid, u8 erp)
790{ 802{
791 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 803 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
792#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
793 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
794#endif
795 u32 changed = 0; 804 u32 changed = 0;
796 bool use_protection; 805 bool use_protection;
797 bool use_short_preamble; 806 bool use_short_preamble;
@@ -808,42 +817,16 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
808 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); 817 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
809 818
810 if (use_protection != bss_conf->use_cts_prot) { 819 if (use_protection != bss_conf->use_cts_prot) {
811#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
812 if (net_ratelimit()) {
813 printk(KERN_DEBUG "%s: CTS protection %s (BSSID=%pM)\n",
814 sdata->dev->name,
815 use_protection ? "enabled" : "disabled",
816 ifmgd->bssid);
817 }
818#endif
819 bss_conf->use_cts_prot = use_protection; 820 bss_conf->use_cts_prot = use_protection;
820 changed |= BSS_CHANGED_ERP_CTS_PROT; 821 changed |= BSS_CHANGED_ERP_CTS_PROT;
821 } 822 }
822 823
823 if (use_short_preamble != bss_conf->use_short_preamble) { 824 if (use_short_preamble != bss_conf->use_short_preamble) {
824#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
825 if (net_ratelimit()) {
826 printk(KERN_DEBUG "%s: switched to %s barker preamble"
827 " (BSSID=%pM)\n",
828 sdata->dev->name,
829 use_short_preamble ? "short" : "long",
830 ifmgd->bssid);
831 }
832#endif
833 bss_conf->use_short_preamble = use_short_preamble; 825 bss_conf->use_short_preamble = use_short_preamble;
834 changed |= BSS_CHANGED_ERP_PREAMBLE; 826 changed |= BSS_CHANGED_ERP_PREAMBLE;
835 } 827 }
836 828
837 if (use_short_slot != bss_conf->use_short_slot) { 829 if (use_short_slot != bss_conf->use_short_slot) {
838#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
839 if (net_ratelimit()) {
840 printk(KERN_DEBUG "%s: switched to %s slot time"
841 " (BSSID=%pM)\n",
842 sdata->dev->name,
843 use_short_slot ? "short" : "long",
844 ifmgd->bssid);
845 }
846#endif
847 bss_conf->use_short_slot = use_short_slot; 830 bss_conf->use_short_slot = use_short_slot;
848 changed |= BSS_CHANGED_ERP_SLOT; 831 changed |= BSS_CHANGED_ERP_SLOT;
849 } 832 }
@@ -852,32 +835,23 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
852} 835}
853 836
854static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, 837static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
838 struct ieee80211_bss *bss,
855 u32 bss_info_changed) 839 u32 bss_info_changed)
856{ 840{
857 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
858 struct ieee80211_local *local = sdata->local; 841 struct ieee80211_local *local = sdata->local;
859 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
860
861 struct ieee80211_bss *bss;
862 842
863 bss_info_changed |= BSS_CHANGED_ASSOC; 843 bss_info_changed |= BSS_CHANGED_ASSOC;
864 ifmgd->flags |= IEEE80211_STA_ASSOCIATED; 844 /* set timing information */
845 sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
846 sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
847 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
865 848
866 bss = ieee80211_rx_bss_get(local, ifmgd->bssid, 849 bss_info_changed |= BSS_CHANGED_BEACON_INT;
867 conf->channel->center_freq, 850 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
868 ifmgd->ssid, ifmgd->ssid_len); 851 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
869 if (bss) {
870 /* set timing information */
871 sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
872 sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
873 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
874 852
875 bss_info_changed |= BSS_CHANGED_BEACON_INT; 853 sdata->u.mgd.associated = bss;
876 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 854 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
877 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
878
879 ieee80211_rx_bss_put(local, bss);
880 }
881 855
882 ieee80211_led_assoc(local, 1); 856 ieee80211_led_assoc(local, 1);
883 857
@@ -905,152 +879,133 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
905 netif_carrier_on(sdata->dev); 879 netif_carrier_on(sdata->dev);
906} 880}
907 881
908static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata) 882static enum rx_mgmt_action __must_check
883ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
884 struct ieee80211_mgd_work *wk)
909{ 885{
910 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 886 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
911 struct ieee80211_local *local = sdata->local; 887 struct ieee80211_local *local = sdata->local;
912 888
913 ifmgd->direct_probe_tries++; 889 wk->tries++;
914 if (ifmgd->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { 890 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
915 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", 891 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
916 sdata->dev->name, ifmgd->bssid); 892 sdata->dev->name, wk->bss->cbss.bssid);
917 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
918 ieee80211_recalc_idle(local);
919 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid,
920 GFP_KERNEL);
921 893
922 /* 894 /*
923 * Most likely AP is not in the range so remove the 895 * Most likely AP is not in the range so remove the
924 * bss information associated to the AP 896 * bss struct for that AP.
925 */ 897 */
926 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 898 cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
927 sdata->local->hw.conf.channel->center_freq,
928 ifmgd->ssid, ifmgd->ssid_len);
929 899
930 /* 900 /*
931 * We might have a pending scan which had no chance to run yet 901 * We might have a pending scan which had no chance to run yet
932 * due to state == IEEE80211_STA_MLME_DIRECT_PROBE. 902 * due to work needing to be done. Hence, queue the STAs work
933 * Hence, queue the STAs work again 903 * again for that.
934 */ 904 */
935 queue_work(local->hw.workqueue, &ifmgd->work); 905 queue_work(local->hw.workqueue, &ifmgd->work);
936 return; 906 return RX_MGMT_CFG80211_AUTH_TO;
937 } 907 }
938 908
939 printk(KERN_DEBUG "%s: direct probe to AP %pM try %d\n", 909 printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
940 sdata->dev->name, ifmgd->bssid, 910 sdata->dev->name, wk->bss->cbss.bssid,
941 ifmgd->direct_probe_tries); 911 wk->tries);
942 912
943 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE; 913 /*
944 914 * Direct probe is sent to broadcast address as some APs
945 /* Direct probe is sent to broadcast address as some APs
946 * will not answer to direct packet in unassociated state. 915 * will not answer to direct packet in unassociated state.
947 */ 916 */
948 ieee80211_send_probe_req(sdata, NULL, 917 ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0);
949 ifmgd->ssid, ifmgd->ssid_len, NULL, 0); 918
919 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
920 mod_timer(&ifmgd->timer, wk->timeout);
950 921
951 mod_timer(&ifmgd->timer, jiffies + IEEE80211_AUTH_TIMEOUT); 922 return RX_MGMT_NONE;
952} 923}
953 924
954 925
955static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata) 926static enum rx_mgmt_action __must_check
927ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
928 struct ieee80211_mgd_work *wk)
956{ 929{
957 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 930 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
958 struct ieee80211_local *local = sdata->local; 931 struct ieee80211_local *local = sdata->local;
959 932
960 ifmgd->auth_tries++; 933 wk->tries++;
961 if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) { 934 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
962 printk(KERN_DEBUG "%s: authentication with AP %pM" 935 printk(KERN_DEBUG "%s: authentication with AP %pM"
963 " timed out\n", 936 " timed out\n",
964 sdata->dev->name, ifmgd->bssid); 937 sdata->dev->name, wk->bss->cbss.bssid);
965 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 938
966 ieee80211_recalc_idle(local); 939 /*
967 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid, 940 * Most likely AP is not in the range so remove the
968 GFP_KERNEL); 941 * bss struct for that AP.
969 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 942 */
970 sdata->local->hw.conf.channel->center_freq, 943 cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
971 ifmgd->ssid, ifmgd->ssid_len);
972 944
973 /* 945 /*
974 * We might have a pending scan which had no chance to run yet 946 * We might have a pending scan which had no chance to run yet
975 * due to state == IEEE80211_STA_MLME_AUTHENTICATE. 947 * due to work needing to be done. Hence, queue the STAs work
976 * Hence, queue the STAs work again 948 * again for that.
977 */ 949 */
978 queue_work(local->hw.workqueue, &ifmgd->work); 950 queue_work(local->hw.workqueue, &ifmgd->work);
979 return; 951 return RX_MGMT_CFG80211_AUTH_TO;
980 } 952 }
981 953
982 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE; 954 printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
983 printk(KERN_DEBUG "%s: authenticate with AP %pM\n", 955 sdata->dev->name, wk->bss->cbss.bssid, wk->tries);
984 sdata->dev->name, ifmgd->bssid); 956
957 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
958 wk->bss->cbss.bssid, 0);
959 wk->auth_transaction = 2;
985 960
986 ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, ifmgd->sme_auth_ie, 961 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
987 ifmgd->sme_auth_ie_len, ifmgd->bssid, 0); 962 mod_timer(&ifmgd->timer, wk->timeout);
988 ifmgd->auth_transaction = 2;
989 963
990 mod_timer(&ifmgd->timer, jiffies + IEEE80211_AUTH_TIMEOUT); 964 return RX_MGMT_NONE;
991} 965}
992 966
993/*
994 * The disassoc 'reason' argument can be either our own reason
995 * if self disconnected or a reason code from the AP.
996 */
997static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 967static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
998 bool deauth, bool self_disconnected, 968 const u8 *bssid, bool deauth)
999 u16 reason)
1000{ 969{
1001 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 970 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1002 struct ieee80211_local *local = sdata->local; 971 struct ieee80211_local *local = sdata->local;
1003 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
1004 struct ieee80211_bss *bss;
1005 struct sta_info *sta; 972 struct sta_info *sta;
1006 u32 changed = 0, config_changed = 0; 973 u32 changed = 0, config_changed = 0;
1007 974
1008 if (deauth) { 975 ASSERT_MGD_MTX(ifmgd);
1009 ifmgd->direct_probe_tries = 0; 976
1010 ifmgd->auth_tries = 0; 977 ifmgd->associated = NULL;
1011 } 978 memset(ifmgd->bssid, 0, ETH_ALEN);
1012 ifmgd->assoc_scan_tries = 0; 979
1013 ifmgd->assoc_tries = 0; 980 /*
981 * we need to commit the associated = NULL change because the
982 * scan code uses that to determine whether this iface should
983 * go to/wake up from powersave or not -- and could otherwise
984 * wake the queues erroneously.
985 */
986 smp_mb();
987
988 /*
989 * Thus, we can only afterwards stop the queues -- to account
990 * for the case where another CPU is finishing a scan at this
991 * time -- we don't want the scan code to enable queues.
992 */
1014 993
1015 netif_tx_stop_all_queues(sdata->dev); 994 netif_tx_stop_all_queues(sdata->dev);
1016 netif_carrier_off(sdata->dev); 995 netif_carrier_off(sdata->dev);
1017 996
1018 rcu_read_lock(); 997 rcu_read_lock();
1019 sta = sta_info_get(local, ifmgd->bssid); 998 sta = sta_info_get(local, bssid);
1020 if (sta) 999 if (sta)
1021 ieee80211_sta_tear_down_BA_sessions(sta); 1000 ieee80211_sta_tear_down_BA_sessions(sta);
1022 rcu_read_unlock(); 1001 rcu_read_unlock();
1023 1002
1024 bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
1025 conf->channel->center_freq,
1026 ifmgd->ssid, ifmgd->ssid_len);
1027
1028 if (bss)
1029 ieee80211_rx_bss_put(local, bss);
1030
1031 if (self_disconnected) {
1032 if (deauth)
1033 ieee80211_send_deauth_disassoc(sdata,
1034 IEEE80211_STYPE_DEAUTH, reason);
1035 else
1036 ieee80211_send_deauth_disassoc(sdata,
1037 IEEE80211_STYPE_DISASSOC, reason);
1038 }
1039
1040 ifmgd->flags &= ~IEEE80211_STA_ASSOCIATED;
1041 changed |= ieee80211_reset_erp_info(sdata); 1003 changed |= ieee80211_reset_erp_info(sdata);
1042 1004
1043 ieee80211_led_assoc(local, 0); 1005 ieee80211_led_assoc(local, 0);
1044 changed |= BSS_CHANGED_ASSOC; 1006 changed |= BSS_CHANGED_ASSOC;
1045 sdata->vif.bss_conf.assoc = false; 1007 sdata->vif.bss_conf.assoc = false;
1046 1008
1047 if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) {
1048 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1049 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
1050 sdata->local->hw.conf.channel->center_freq,
1051 ifmgd->ssid, ifmgd->ssid_len);
1052 }
1053
1054 ieee80211_set_wmm_default(sdata); 1009 ieee80211_set_wmm_default(sdata);
1055 1010
1056 ieee80211_recalc_idle(local); 1011 ieee80211_recalc_idle(local);
@@ -1079,7 +1034,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1079 1034
1080 rcu_read_lock(); 1035 rcu_read_lock();
1081 1036
1082 sta = sta_info_get(local, ifmgd->bssid); 1037 sta = sta_info_get(local, bssid);
1083 if (!sta) { 1038 if (!sta) {
1084 rcu_read_unlock(); 1039 rcu_read_unlock();
1085 return; 1040 return;
@@ -1092,38 +1047,42 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1092 sta_info_destroy(sta); 1047 sta_info_destroy(sta);
1093} 1048}
1094 1049
1095static void ieee80211_associate(struct ieee80211_sub_if_data *sdata) 1050static enum rx_mgmt_action __must_check
1051ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1052 struct ieee80211_mgd_work *wk)
1096{ 1053{
1097 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1054 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1098 struct ieee80211_local *local = sdata->local; 1055 struct ieee80211_local *local = sdata->local;
1099 1056
1100 ifmgd->assoc_tries++; 1057 wk->tries++;
1101 if (ifmgd->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { 1058 if (wk->tries > IEEE80211_ASSOC_MAX_TRIES) {
1102 printk(KERN_DEBUG "%s: association with AP %pM" 1059 printk(KERN_DEBUG "%s: association with AP %pM"
1103 " timed out\n", 1060 " timed out\n",
1104 sdata->dev->name, ifmgd->bssid); 1061 sdata->dev->name, wk->bss->cbss.bssid);
1105 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1062
1106 ieee80211_recalc_idle(local); 1063 /*
1107 cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid, 1064 * Most likely AP is not in the range so remove the
1108 GFP_KERNEL); 1065 * bss struct for that AP.
1109 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 1066 */
1110 sdata->local->hw.conf.channel->center_freq, 1067 cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
1111 ifmgd->ssid, ifmgd->ssid_len); 1068
1112 /* 1069 /*
1113 * We might have a pending scan which had no chance to run yet 1070 * We might have a pending scan which had no chance to run yet
1114 * due to state == IEEE80211_STA_MLME_ASSOCIATE. 1071 * due to work needing to be done. Hence, queue the STAs work
1115 * Hence, queue the STAs work again 1072 * again for that.
1116 */ 1073 */
1117 queue_work(local->hw.workqueue, &ifmgd->work); 1074 queue_work(local->hw.workqueue, &ifmgd->work);
1118 return; 1075 return RX_MGMT_CFG80211_ASSOC_TO;
1119 } 1076 }
1120 1077
1121 ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE; 1078 printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n",
1122 printk(KERN_DEBUG "%s: associate with AP %pM\n", 1079 sdata->dev->name, wk->bss->cbss.bssid, wk->tries);
1123 sdata->dev->name, ifmgd->bssid); 1080 ieee80211_send_assoc(sdata, wk);
1124 ieee80211_send_assoc(sdata); 1081
1082 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
1083 mod_timer(&ifmgd->timer, wk->timeout);
1125 1084
1126 mod_timer(&ifmgd->timer, jiffies + IEEE80211_ASSOC_TIMEOUT); 1085 return RX_MGMT_NONE;
1127} 1086}
1128 1087
1129void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1088void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1148,6 +1107,7 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1148 container_of(work, struct ieee80211_sub_if_data, 1107 container_of(work, struct ieee80211_sub_if_data,
1149 u.mgd.beacon_loss_work); 1108 u.mgd.beacon_loss_work);
1150 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1109 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1110 const u8 *ssid;
1151 1111
1152 /* 1112 /*
1153 * The driver has already reported this event and we have 1113 * The driver has already reported this event and we have
@@ -1160,12 +1120,15 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1160 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) 1120 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
1161 return; 1121 return;
1162 1122
1123 mutex_lock(&ifmgd->mtx);
1124
1125 if (!ifmgd->associated)
1126 goto out;
1127
1163#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1128#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1164 if (net_ratelimit()) { 1129 if (net_ratelimit())
1165 printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM " 1130 printk(KERN_DEBUG "%s: driver reports beacon loss from AP "
1166 "- sending probe request\n", sdata->dev->name, 1131 "- sending probe request\n", sdata->dev->name);
1167 sdata->u.mgd.bssid);
1168 }
1169#endif 1132#endif
1170 1133
1171 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; 1134 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
@@ -1174,10 +1137,13 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1174 ieee80211_recalc_ps(sdata->local, -1); 1137 ieee80211_recalc_ps(sdata->local, -1);
1175 mutex_unlock(&sdata->local->iflist_mtx); 1138 mutex_unlock(&sdata->local->iflist_mtx);
1176 1139
1177 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1140 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID);
1178 ifmgd->ssid_len, NULL, 0); 1141 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
1142 ssid + 2, ssid[1], NULL, 0);
1179 1143
1180 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); 1144 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
1145 out:
1146 mutex_unlock(&ifmgd->mtx);
1181} 1147}
1182 1148
1183void ieee80211_beacon_loss(struct ieee80211_vif *vif) 1149void ieee80211_beacon_loss(struct ieee80211_vif *vif)
@@ -1189,102 +1155,16 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1189} 1155}
1190EXPORT_SYMBOL(ieee80211_beacon_loss); 1156EXPORT_SYMBOL(ieee80211_beacon_loss);
1191 1157
1192static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) 1158static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1159 struct ieee80211_mgd_work *wk)
1193{ 1160{
1194 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1161 wk->state = IEEE80211_MGD_STATE_IDLE;
1195 struct ieee80211_local *local = sdata->local;
1196 struct sta_info *sta;
1197 unsigned long last_rx;
1198 bool disassoc = false;
1199
1200 /* TODO: start monitoring current AP signal quality and number of
1201 * missed beacons. Scan other channels every now and then and search
1202 * for better APs. */
1203 /* TODO: remove expired BSSes */
1204
1205 ifmgd->state = IEEE80211_STA_MLME_ASSOCIATED;
1206
1207 rcu_read_lock();
1208
1209 sta = sta_info_get(local, ifmgd->bssid);
1210 if (!sta) {
1211 printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
1212 sdata->dev->name, ifmgd->bssid);
1213 disassoc = true;
1214 rcu_read_unlock();
1215 goto out;
1216 }
1217
1218 last_rx = sta->last_rx;
1219 rcu_read_unlock();
1220
1221 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
1222 time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) {
1223 printk(KERN_DEBUG "%s: no probe response from AP %pM "
1224 "- disassociating\n",
1225 sdata->dev->name, ifmgd->bssid);
1226 disassoc = true;
1227 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1228 goto out;
1229 }
1230
1231 /*
1232 * Beacon filtering is only enabled with power save and then the
1233 * stack should not check for beacon loss.
1234 */
1235 if (!((local->hw.flags & IEEE80211_HW_BEACON_FILTER) &&
1236 (local->hw.conf.flags & IEEE80211_CONF_PS)) &&
1237 time_after(jiffies,
1238 ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) {
1239#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1240 if (net_ratelimit()) {
1241 printk(KERN_DEBUG "%s: beacon loss from AP %pM "
1242 "- sending probe request\n",
1243 sdata->dev->name, ifmgd->bssid);
1244 }
1245#endif
1246 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1247 mutex_lock(&local->iflist_mtx);
1248 ieee80211_recalc_ps(local, -1);
1249 mutex_unlock(&local->iflist_mtx);
1250 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1251 ifmgd->ssid_len, NULL, 0);
1252 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
1253 goto out;
1254 }
1255
1256 if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) {
1257 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
1258 mutex_lock(&local->iflist_mtx);
1259 ieee80211_recalc_ps(local, -1);
1260 mutex_unlock(&local->iflist_mtx);
1261 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1262 ifmgd->ssid_len, NULL, 0);
1263 }
1264
1265 out:
1266 if (!disassoc)
1267 mod_timer(&ifmgd->timer,
1268 jiffies + IEEE80211_MONITORING_INTERVAL);
1269 else
1270 ieee80211_set_disassoc(sdata, true, true,
1271 WLAN_REASON_PREV_AUTH_NOT_VALID);
1272}
1273
1274
1275static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
1276{
1277 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1278
1279 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name); 1162 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1280 ifmgd->flags |= IEEE80211_STA_AUTHENTICATED;
1281 /* Wait for SME to request association */
1282 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1283 ieee80211_recalc_idle(sdata->local);
1284} 1163}
1285 1164
1286 1165
1287static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, 1166static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1167 struct ieee80211_mgd_work *wk,
1288 struct ieee80211_mgmt *mgmt, 1168 struct ieee80211_mgmt *mgmt,
1289 size_t len) 1169 size_t len)
1290{ 1170{
@@ -1295,120 +1175,132 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1295 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); 1175 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1296 if (!elems.challenge) 1176 if (!elems.challenge)
1297 return; 1177 return;
1298 ieee80211_send_auth(sdata, 3, sdata->u.mgd.auth_alg, 1178 ieee80211_send_auth(sdata, 3, wk->auth_alg,
1299 elems.challenge - 2, elems.challenge_len + 2, 1179 elems.challenge - 2, elems.challenge_len + 2,
1300 sdata->u.mgd.bssid, 1); 1180 wk->bss->cbss.bssid, 1);
1301 sdata->u.mgd.auth_transaction = 4; 1181 wk->auth_transaction = 4;
1302} 1182}
1303 1183
1304static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, 1184static enum rx_mgmt_action __must_check
1305 struct ieee80211_mgmt *mgmt, 1185ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1306 size_t len) 1186 struct ieee80211_mgd_work *wk,
1187 struct ieee80211_mgmt *mgmt, size_t len)
1307{ 1188{
1308 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1309 u16 auth_alg, auth_transaction, status_code; 1189 u16 auth_alg, auth_transaction, status_code;
1310 1190
1311 if (ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE) 1191 if (wk->state != IEEE80211_MGD_STATE_AUTH)
1312 return; 1192 return RX_MGMT_NONE;
1313 1193
1314 if (len < 24 + 6) 1194 if (len < 24 + 6)
1315 return; 1195 return RX_MGMT_NONE;
1316 1196
1317 if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN) != 0) 1197 if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
1318 return; 1198 return RX_MGMT_NONE;
1319 1199
1320 if (memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0) 1200 if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0)
1321 return; 1201 return RX_MGMT_NONE;
1322 1202
1323 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 1203 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
1324 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 1204 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1325 status_code = le16_to_cpu(mgmt->u.auth.status_code); 1205 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1326 1206
1327 if (auth_alg != ifmgd->auth_alg || 1207 if (auth_alg != wk->auth_alg ||
1328 auth_transaction != ifmgd->auth_transaction) 1208 auth_transaction != wk->auth_transaction)
1329 return; 1209 return RX_MGMT_NONE;
1330 1210
1331 if (status_code != WLAN_STATUS_SUCCESS) { 1211 if (status_code != WLAN_STATUS_SUCCESS) {
1332 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len, 1212 list_del(&wk->list);
1333 GFP_KERNEL); 1213 kfree(wk);
1334 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1214 return RX_MGMT_CFG80211_AUTH;
1335 ieee80211_recalc_idle(sdata->local);
1336 return;
1337 } 1215 }
1338 1216
1339 switch (ifmgd->auth_alg) { 1217 switch (wk->auth_alg) {
1340 case WLAN_AUTH_OPEN: 1218 case WLAN_AUTH_OPEN:
1341 case WLAN_AUTH_LEAP: 1219 case WLAN_AUTH_LEAP:
1342 case WLAN_AUTH_FT: 1220 case WLAN_AUTH_FT:
1343 ieee80211_auth_completed(sdata); 1221 ieee80211_auth_completed(sdata, wk);
1344 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len, 1222 return RX_MGMT_CFG80211_AUTH;
1345 GFP_KERNEL);
1346 break;
1347 case WLAN_AUTH_SHARED_KEY: 1223 case WLAN_AUTH_SHARED_KEY:
1348 if (ifmgd->auth_transaction == 4) { 1224 if (wk->auth_transaction == 4) {
1349 ieee80211_auth_completed(sdata); 1225 ieee80211_auth_completed(sdata, wk);
1350 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len, 1226 return RX_MGMT_CFG80211_AUTH;
1351 GFP_KERNEL);
1352 } else 1227 } else
1353 ieee80211_auth_challenge(sdata, mgmt, len); 1228 ieee80211_auth_challenge(sdata, wk, mgmt, len);
1354 break; 1229 break;
1355 } 1230 }
1231
1232 return RX_MGMT_NONE;
1356} 1233}
1357 1234
1358 1235
1359static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 1236static enum rx_mgmt_action __must_check
1360 struct ieee80211_mgmt *mgmt, 1237ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1361 size_t len) 1238 struct ieee80211_mgd_work *wk,
1239 struct ieee80211_mgmt *mgmt, size_t len)
1362{ 1240{
1363 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1241 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1242 const u8 *bssid = NULL;
1364 u16 reason_code; 1243 u16 reason_code;
1365 1244
1366 if (len < 24 + 2) 1245 if (len < 24 + 2)
1367 return; 1246 return RX_MGMT_NONE;
1368 1247
1369 if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN)) 1248 ASSERT_MGD_MTX(ifmgd);
1370 return; 1249
1250 if (wk)
1251 bssid = wk->bss->cbss.bssid;
1252 else
1253 bssid = ifmgd->associated->cbss.bssid;
1371 1254
1372 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 1255 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
1373 1256
1374 if (ifmgd->flags & IEEE80211_STA_AUTHENTICATED) 1257 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1375 printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n", 1258 sdata->dev->name, bssid, reason_code);
1376 sdata->dev->name, reason_code); 1259
1260 if (!wk) {
1261 ieee80211_set_disassoc(sdata, bssid, true);
1262 } else {
1263 list_del(&wk->list);
1264 kfree(wk);
1265 }
1377 1266
1378 ieee80211_set_disassoc(sdata, true, false, 0); 1267 return RX_MGMT_CFG80211_DEAUTH;
1379 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
1380 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len, GFP_KERNEL);
1381} 1268}
1382 1269
1383 1270
1384static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, 1271static enum rx_mgmt_action __must_check
1385 struct ieee80211_mgmt *mgmt, 1272ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1386 size_t len) 1273 struct ieee80211_mgmt *mgmt, size_t len)
1387{ 1274{
1388 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1275 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1389 u16 reason_code; 1276 u16 reason_code;
1390 1277
1391 if (len < 24 + 2) 1278 if (len < 24 + 2)
1392 return; 1279 return RX_MGMT_NONE;
1393 1280
1394 if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN)) 1281 ASSERT_MGD_MTX(ifmgd);
1395 return; 1282
1283 if (WARN_ON(!ifmgd->associated))
1284 return RX_MGMT_NONE;
1285
1286 if (WARN_ON(memcmp(ifmgd->associated->cbss.bssid, mgmt->sa, ETH_ALEN)))
1287 return RX_MGMT_NONE;
1396 1288
1397 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 1289 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
1398 1290
1399 if (ifmgd->flags & IEEE80211_STA_ASSOCIATED) 1291 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1400 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1292 sdata->dev->name, reason_code);
1401 sdata->dev->name, reason_code);
1402 1293
1403 ieee80211_set_disassoc(sdata, false, false, reason_code); 1294 ieee80211_set_disassoc(sdata, ifmgd->associated->cbss.bssid, false);
1404 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len, GFP_KERNEL); 1295 return RX_MGMT_CFG80211_DISASSOC;
1405} 1296}
1406 1297
1407 1298
1408static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 1299static enum rx_mgmt_action __must_check
1409 struct ieee80211_mgmt *mgmt, 1300ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1410 size_t len, 1301 struct ieee80211_mgd_work *wk,
1411 int reassoc) 1302 struct ieee80211_mgmt *mgmt, size_t len,
1303 bool reassoc)
1412{ 1304{
1413 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1305 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1414 struct ieee80211_local *local = sdata->local; 1306 struct ieee80211_local *local = sdata->local;
@@ -1424,17 +1316,16 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1424 bool have_higher_than_11mbit = false, newsta = false; 1316 bool have_higher_than_11mbit = false, newsta = false;
1425 u16 ap_ht_cap_flags; 1317 u16 ap_ht_cap_flags;
1426 1318
1427 /* AssocResp and ReassocResp have identical structure, so process both 1319 /*
1428 * of them in this function. */ 1320 * AssocResp and ReassocResp have identical structure, so process both
1429 1321 * of them in this function.
1430 if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE) 1322 */
1431 return;
1432 1323
1433 if (len < 24 + 6) 1324 if (len < 24 + 6)
1434 return; 1325 return RX_MGMT_NONE;
1435 1326
1436 if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN) != 0) 1327 if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
1437 return; 1328 return RX_MGMT_NONE;
1438 1329
1439 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); 1330 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1440 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 1331 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
@@ -1457,21 +1348,19 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1457 printk(KERN_DEBUG "%s: AP rejected association temporarily; " 1348 printk(KERN_DEBUG "%s: AP rejected association temporarily; "
1458 "comeback duration %u TU (%u ms)\n", 1349 "comeback duration %u TU (%u ms)\n",
1459 sdata->dev->name, tu, ms); 1350 sdata->dev->name, tu, ms);
1351 wk->timeout = jiffies + msecs_to_jiffies(ms);
1460 if (ms > IEEE80211_ASSOC_TIMEOUT) 1352 if (ms > IEEE80211_ASSOC_TIMEOUT)
1461 mod_timer(&ifmgd->timer, 1353 mod_timer(&ifmgd->timer,
1462 jiffies + msecs_to_jiffies(ms)); 1354 jiffies + msecs_to_jiffies(ms));
1463 return; 1355 return RX_MGMT_NONE;
1464 } 1356 }
1465 1357
1466 if (status_code != WLAN_STATUS_SUCCESS) { 1358 if (status_code != WLAN_STATUS_SUCCESS) {
1467 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", 1359 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1468 sdata->dev->name, status_code); 1360 sdata->dev->name, status_code);
1469 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len, 1361 list_del(&wk->list);
1470 GFP_KERNEL); 1362 kfree(wk);
1471 /* Wait for SME to decide what to do next */ 1363 return RX_MGMT_CFG80211_ASSOC;
1472 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1473 ieee80211_recalc_idle(local);
1474 return;
1475 } 1364 }
1476 1365
1477 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1366 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
@@ -1482,50 +1371,38 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1482 if (!elems.supp_rates) { 1371 if (!elems.supp_rates) {
1483 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1372 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1484 sdata->dev->name); 1373 sdata->dev->name);
1485 return; 1374 return RX_MGMT_NONE;
1486 } 1375 }
1487 1376
1488 printk(KERN_DEBUG "%s: associated\n", sdata->dev->name); 1377 printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
1489 ifmgd->aid = aid; 1378 ifmgd->aid = aid;
1490 1379
1491 kfree(ifmgd->assocresp_ies);
1492 ifmgd->assocresp_ies_len = len - (pos - (u8 *) mgmt);
1493 ifmgd->assocresp_ies = kmalloc(ifmgd->assocresp_ies_len, GFP_KERNEL);
1494 if (ifmgd->assocresp_ies)
1495 memcpy(ifmgd->assocresp_ies, pos, ifmgd->assocresp_ies_len);
1496
1497 rcu_read_lock(); 1380 rcu_read_lock();
1498 1381
1499 /* Add STA entry for the AP */ 1382 /* Add STA entry for the AP */
1500 sta = sta_info_get(local, ifmgd->bssid); 1383 sta = sta_info_get(local, wk->bss->cbss.bssid);
1501 if (!sta) { 1384 if (!sta) {
1502 newsta = true; 1385 newsta = true;
1503 1386
1504 sta = sta_info_alloc(sdata, ifmgd->bssid, GFP_ATOMIC); 1387 rcu_read_unlock();
1388
1389 sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL);
1505 if (!sta) { 1390 if (!sta) {
1506 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1391 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1507 " the AP\n", sdata->dev->name); 1392 " the AP\n", sdata->dev->name);
1508 rcu_read_unlock(); 1393 return RX_MGMT_NONE;
1509 return;
1510 } 1394 }
1511 1395
1512 /* update new sta with its last rx activity */ 1396 /* update new sta with its last rx activity */
1513 sta->last_rx = jiffies; 1397 sta->last_rx = jiffies;
1514 }
1515 1398
1516 /* 1399 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1517 * FIXME: Do we really need to update the sta_info's information here? 1400 WLAN_STA_ASSOC_AP);
1518 * We already know about the AP (we found it in our list) so it 1401 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1519 * should already be filled with the right info, no? 1402 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1520 * As is stands, all this is racy because typically we assume
1521 * the information that is filled in here (except flags) doesn't
1522 * change while a STA structure is alive. As such, it should move
1523 * to between the sta_info_alloc() and sta_info_insert() above.
1524 */
1525 1403
1526 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP); 1404 rcu_read_lock();
1527 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 1405 }
1528 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1529 1406
1530 rates = 0; 1407 rates = 0;
1531 basic_rates = 0; 1408 basic_rates = 0;
@@ -1595,7 +1472,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1595 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1472 printk(KERN_DEBUG "%s: failed to insert STA entry for"
1596 " the AP (error %d)\n", sdata->dev->name, err); 1473 " the AP (error %d)\n", sdata->dev->name, err);
1597 rcu_read_unlock(); 1474 rcu_read_unlock();
1598 return; 1475 return RX_MGMT_NONE;
1599 } 1476 }
1600 } 1477 }
1601 1478
@@ -1611,13 +1488,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1611 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && 1488 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
1612 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 1489 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
1613 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1490 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1491 wk->bss->cbss.bssid,
1614 ap_ht_cap_flags); 1492 ap_ht_cap_flags);
1615 1493
1616 /* set AID and assoc capability, 1494 /* set AID and assoc capability,
1617 * ieee80211_set_associated() will tell the driver */ 1495 * ieee80211_set_associated() will tell the driver */
1618 bss_conf->aid = aid; 1496 bss_conf->aid = aid;
1619 bss_conf->assoc_capability = capab_info; 1497 bss_conf->assoc_capability = capab_info;
1620 ieee80211_set_associated(sdata, changed); 1498 ieee80211_set_associated(sdata, wk->bss, changed);
1621 1499
1622 /* 1500 /*
1623 * initialise the time of last beacon to be the association time, 1501 * initialise the time of last beacon to be the association time,
@@ -1625,8 +1503,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1625 */ 1503 */
1626 ifmgd->last_beacon = jiffies; 1504 ifmgd->last_beacon = jiffies;
1627 1505
1628 ieee80211_associated(sdata); 1506 list_del(&wk->list);
1629 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len, GFP_KERNEL); 1507 kfree(wk);
1508 return RX_MGMT_CFG80211_ASSOC;
1630} 1509}
1631 1510
1632 1511
@@ -1654,23 +1533,25 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1654 1533
1655 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 1534 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1656 channel, beacon); 1535 channel, beacon);
1657 if (!bss) 1536 if (bss)
1537 ieee80211_rx_bss_put(local, bss);
1538
1539 if (!sdata->u.mgd.associated)
1658 return; 1540 return;
1659 1541
1660 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && 1542 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
1661 (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN) == 0)) { 1543 (memcmp(mgmt->bssid, sdata->u.mgd.associated->cbss.bssid,
1544 ETH_ALEN) == 0)) {
1662 struct ieee80211_channel_sw_ie *sw_elem = 1545 struct ieee80211_channel_sw_ie *sw_elem =
1663 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem; 1546 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
1664 ieee80211_sta_process_chanswitch(sdata, sw_elem, bss); 1547 ieee80211_sta_process_chanswitch(sdata, sw_elem, bss);
1665 } 1548 }
1666
1667 ieee80211_rx_bss_put(local, bss);
1668} 1549}
1669 1550
1670 1551
1671static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, 1552static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1672 struct ieee80211_mgmt *mgmt, 1553 struct ieee80211_mgd_work *wk,
1673 size_t len, 1554 struct ieee80211_mgmt *mgmt, size_t len,
1674 struct ieee80211_rx_status *rx_status) 1555 struct ieee80211_rx_status *rx_status)
1675{ 1556{
1676 struct ieee80211_if_managed *ifmgd; 1557 struct ieee80211_if_managed *ifmgd;
@@ -1679,6 +1560,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1679 1560
1680 ifmgd = &sdata->u.mgd; 1561 ifmgd = &sdata->u.mgd;
1681 1562
1563 ASSERT_MGD_MTX(ifmgd);
1564
1682 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 1565 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
1683 return; /* ignore ProbeResp to foreign address */ 1566 return; /* ignore ProbeResp to foreign address */
1684 1567
@@ -1692,13 +1575,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1692 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); 1575 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1693 1576
1694 /* direct probe may be part of the association flow */ 1577 /* direct probe may be part of the association flow */
1695 if (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE) { 1578 if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) {
1696 printk(KERN_DEBUG "%s direct probe responded\n", 1579 printk(KERN_DEBUG "%s direct probe responded\n",
1697 sdata->dev->name); 1580 sdata->dev->name);
1698 ieee80211_authenticate(sdata); 1581 wk->tries = 0;
1582 wk->state = IEEE80211_MGD_STATE_AUTH;
1583 WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE);
1699 } 1584 }
1700 1585
1701 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 1586 if (ifmgd->associated &&
1587 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 &&
1588 ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
1702 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1589 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1703 mutex_lock(&sdata->local->iflist_mtx); 1590 mutex_lock(&sdata->local->iflist_mtx);
1704 ieee80211_recalc_ps(sdata->local, -1); 1591 ieee80211_recalc_ps(sdata->local, -1);
@@ -1740,6 +1627,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1740 bool erp_valid, directed_tim = false; 1627 bool erp_valid, directed_tim = false;
1741 u8 erp_value = 0; 1628 u8 erp_value = 0;
1742 u32 ncrc; 1629 u32 ncrc;
1630 u8 *bssid;
1631
1632 ASSERT_MGD_MTX(ifmgd);
1743 1633
1744 /* Process beacon from the current BSS */ 1634 /* Process beacon from the current BSS */
1745 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 1635 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1749,8 +1639,12 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1749 if (rx_status->freq != local->hw.conf.channel->center_freq) 1639 if (rx_status->freq != local->hw.conf.channel->center_freq)
1750 return; 1640 return;
1751 1641
1752 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) || 1642 if (WARN_ON(!ifmgd->associated))
1753 memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0) 1643 return;
1644
1645 bssid = ifmgd->associated->cbss.bssid;
1646
1647 if (WARN_ON(memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0))
1754 return; 1648 return;
1755 1649
1756 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 1650 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
@@ -1829,8 +1723,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1829 1723
1830 rcu_read_lock(); 1724 rcu_read_lock();
1831 1725
1832 sta = sta_info_get(local, ifmgd->bssid); 1726 sta = sta_info_get(local, bssid);
1833 if (!sta) { 1727 if (WARN_ON(!sta)) {
1834 rcu_read_unlock(); 1728 rcu_read_unlock();
1835 return; 1729 return;
1836 } 1730 }
@@ -1845,7 +1739,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1845 rcu_read_unlock(); 1739 rcu_read_unlock();
1846 1740
1847 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1741 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1848 ap_ht_cap_flags); 1742 bssid, ap_ht_cap_flags);
1849 } 1743 }
1850 1744
1851 if (elems.country_elem) { 1745 if (elems.country_elem) {
@@ -1887,6 +1781,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1887 case IEEE80211_STYPE_REASSOC_RESP: 1781 case IEEE80211_STYPE_REASSOC_RESP:
1888 case IEEE80211_STYPE_DEAUTH: 1782 case IEEE80211_STYPE_DEAUTH:
1889 case IEEE80211_STYPE_DISASSOC: 1783 case IEEE80211_STYPE_DISASSOC:
1784 case IEEE80211_STYPE_ACTION:
1890 skb_queue_tail(&sdata->u.mgd.skb_queue, skb); 1785 skb_queue_tail(&sdata->u.mgd.skb_queue, skb);
1891 queue_work(local->hw.workqueue, &sdata->u.mgd.work); 1786 queue_work(local->hw.workqueue, &sdata->u.mgd.work);
1892 return RX_QUEUED; 1787 return RX_QUEUED;
@@ -1898,40 +1793,118 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1898static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1793static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1899 struct sk_buff *skb) 1794 struct sk_buff *skb)
1900{ 1795{
1796 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1901 struct ieee80211_rx_status *rx_status; 1797 struct ieee80211_rx_status *rx_status;
1902 struct ieee80211_mgmt *mgmt; 1798 struct ieee80211_mgmt *mgmt;
1799 struct ieee80211_mgd_work *wk;
1800 enum rx_mgmt_action rma = RX_MGMT_NONE;
1903 u16 fc; 1801 u16 fc;
1904 1802
1905 rx_status = (struct ieee80211_rx_status *) skb->cb; 1803 rx_status = (struct ieee80211_rx_status *) skb->cb;
1906 mgmt = (struct ieee80211_mgmt *) skb->data; 1804 mgmt = (struct ieee80211_mgmt *) skb->data;
1907 fc = le16_to_cpu(mgmt->frame_control); 1805 fc = le16_to_cpu(mgmt->frame_control);
1908 1806
1909 switch (fc & IEEE80211_FCTL_STYPE) { 1807 mutex_lock(&ifmgd->mtx);
1910 case IEEE80211_STYPE_PROBE_RESP: 1808
1911 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, 1809 if (ifmgd->associated &&
1912 rx_status); 1810 memcmp(ifmgd->associated->cbss.bssid, mgmt->bssid,
1913 break; 1811 ETH_ALEN) == 0) {
1914 case IEEE80211_STYPE_BEACON: 1812 switch (fc & IEEE80211_FCTL_STYPE) {
1915 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, 1813 case IEEE80211_STYPE_BEACON:
1916 rx_status); 1814 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
1917 break; 1815 rx_status);
1918 case IEEE80211_STYPE_AUTH: 1816 break;
1919 ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len); 1817 case IEEE80211_STYPE_PROBE_RESP:
1920 break; 1818 ieee80211_rx_mgmt_probe_resp(sdata, NULL, mgmt,
1921 case IEEE80211_STYPE_ASSOC_RESP: 1819 skb->len, rx_status);
1922 ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, 0); 1820 break;
1821 case IEEE80211_STYPE_DEAUTH:
1822 rma = ieee80211_rx_mgmt_deauth(sdata, NULL,
1823 mgmt, skb->len);
1824 break;
1825 case IEEE80211_STYPE_DISASSOC:
1826 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
1827 break;
1828 case IEEE80211_STYPE_ACTION:
1829 /* XXX: differentiate, can only happen for CSA now! */
1830 ieee80211_sta_process_chanswitch(sdata,
1831 &mgmt->u.action.u.chan_switch.sw_elem,
1832 ifmgd->associated);
1833 break;
1834 }
1835 mutex_unlock(&ifmgd->mtx);
1836
1837 switch (rma) {
1838 case RX_MGMT_NONE:
1839 /* no action */
1840 break;
1841 case RX_MGMT_CFG80211_DEAUTH:
1842 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt,
1843 skb->len, GFP_KERNEL);
1844 break;
1845 case RX_MGMT_CFG80211_DISASSOC:
1846 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt,
1847 skb->len, GFP_KERNEL);
1848 break;
1849 default:
1850 WARN(1, "unexpected: %d", rma);
1851 }
1852 goto out;
1853 }
1854
1855 list_for_each_entry(wk, &ifmgd->work_list, list) {
1856 if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0)
1857 continue;
1858
1859 switch (fc & IEEE80211_FCTL_STYPE) {
1860 case IEEE80211_STYPE_PROBE_RESP:
1861 ieee80211_rx_mgmt_probe_resp(sdata, wk, mgmt, skb->len,
1862 rx_status);
1863 break;
1864 case IEEE80211_STYPE_AUTH:
1865 rma = ieee80211_rx_mgmt_auth(sdata, wk, mgmt, skb->len);
1866 break;
1867 case IEEE80211_STYPE_ASSOC_RESP:
1868 rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
1869 skb->len, false);
1870 break;
1871 case IEEE80211_STYPE_REASSOC_RESP:
1872 rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
1873 skb->len, true);
1874 break;
1875 case IEEE80211_STYPE_DEAUTH:
1876 rma = ieee80211_rx_mgmt_deauth(sdata, wk, mgmt,
1877 skb->len);
1878 break;
1879 }
1880 /*
1881 * We've processed this frame for that work, so it can't
1882 * belong to another work struct.
1883 * NB: this is also required for correctness because the
1884 * called functions can free 'wk', and for 'rma'!
1885 */
1923 break; 1886 break;
1924 case IEEE80211_STYPE_REASSOC_RESP: 1887 }
1925 ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, 1); 1888
1889 mutex_unlock(&ifmgd->mtx);
1890
1891 switch (rma) {
1892 case RX_MGMT_NONE:
1893 /* no action */
1926 break; 1894 break;
1927 case IEEE80211_STYPE_DEAUTH: 1895 case RX_MGMT_CFG80211_AUTH:
1928 ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); 1896 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len,
1897 GFP_KERNEL);
1929 break; 1898 break;
1930 case IEEE80211_STYPE_DISASSOC: 1899 case RX_MGMT_CFG80211_ASSOC:
1931 ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); 1900 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len,
1901 GFP_KERNEL);
1932 break; 1902 break;
1903 default:
1904 WARN(1, "unexpected: %d", rma);
1933 } 1905 }
1934 1906
1907 out:
1935 kfree_skb(skb); 1908 kfree_skb(skb);
1936} 1909}
1937 1910
@@ -1947,89 +1920,9 @@ static void ieee80211_sta_timer(unsigned long data)
1947 return; 1920 return;
1948 } 1921 }
1949 1922
1950 set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
1951 queue_work(local->hw.workqueue, &ifmgd->work); 1923 queue_work(local->hw.workqueue, &ifmgd->work);
1952} 1924}
1953 1925
1954static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
1955{
1956 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1957 struct ieee80211_local *local = sdata->local;
1958
1959 /* Reset own TSF to allow time synchronization work. */
1960 drv_reset_tsf(local);
1961
1962 ifmgd->wmm_last_param_set = -1; /* allow any WMM update */
1963 ifmgd->auth_transaction = -1;
1964 ifmgd->flags &= ~IEEE80211_STA_ASSOCIATED;
1965 ifmgd->assoc_scan_tries = 0;
1966 ifmgd->direct_probe_tries = 0;
1967 ifmgd->auth_tries = 0;
1968 ifmgd->assoc_tries = 0;
1969 netif_tx_stop_all_queues(sdata->dev);
1970 netif_carrier_off(sdata->dev);
1971}
1972
1973static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
1974{
1975 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1976 struct ieee80211_local *local = sdata->local;
1977 struct ieee80211_bss *bss;
1978 u8 *bssid = ifmgd->bssid, *ssid = ifmgd->ssid;
1979 u8 ssid_len = ifmgd->ssid_len;
1980 u16 capa_mask = WLAN_CAPABILITY_ESS;
1981 u16 capa_val = WLAN_CAPABILITY_ESS;
1982 struct ieee80211_channel *chan = local->oper_channel;
1983
1984 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan,
1985 bssid, ssid, ssid_len,
1986 capa_mask, capa_val);
1987
1988 if (bss) {
1989 local->oper_channel = bss->cbss.channel;
1990 local->oper_channel_type = NL80211_CHAN_NO_HT;
1991 ieee80211_hw_config(local, 0);
1992
1993 ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len,
1994 bss->supp_rates);
1995 if (sdata->u.mgd.mfp == IEEE80211_MFP_REQUIRED)
1996 sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
1997 else
1998 sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
1999
2000 /* Send out direct probe if no probe resp was received or
2001 * the one we have is outdated
2002 */
2003 if (!bss->last_probe_resp ||
2004 time_after(jiffies, bss->last_probe_resp
2005 + IEEE80211_SCAN_RESULT_EXPIRE))
2006 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
2007 else
2008 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
2009
2010 ieee80211_rx_bss_put(local, bss);
2011 ieee80211_sta_reset_auth(sdata);
2012 return 0;
2013 } else {
2014 if (ifmgd->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
2015
2016 ifmgd->assoc_scan_tries++;
2017
2018 ieee80211_request_internal_scan(sdata, ifmgd->ssid,
2019 ssid_len);
2020
2021 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
2022 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
2023 } else {
2024 ifmgd->assoc_scan_tries = 0;
2025 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
2026 ieee80211_recalc_idle(local);
2027 }
2028 }
2029 return -1;
2030}
2031
2032
2033static void ieee80211_sta_work(struct work_struct *work) 1926static void ieee80211_sta_work(struct work_struct *work)
2034{ 1927{
2035 struct ieee80211_sub_if_data *sdata = 1928 struct ieee80211_sub_if_data *sdata =
@@ -2037,6 +1930,10 @@ static void ieee80211_sta_work(struct work_struct *work)
2037 struct ieee80211_local *local = sdata->local; 1930 struct ieee80211_local *local = sdata->local;
2038 struct ieee80211_if_managed *ifmgd; 1931 struct ieee80211_if_managed *ifmgd;
2039 struct sk_buff *skb; 1932 struct sk_buff *skb;
1933 struct ieee80211_mgd_work *wk, *tmp;
1934 LIST_HEAD(free_work);
1935 enum rx_mgmt_action rma;
1936 bool anybusy = false;
2040 1937
2041 if (!netif_running(sdata->dev)) 1938 if (!netif_running(sdata->dev))
2042 return; 1939 return;
@@ -2059,46 +1956,93 @@ static void ieee80211_sta_work(struct work_struct *work)
2059 1956
2060 ifmgd = &sdata->u.mgd; 1957 ifmgd = &sdata->u.mgd;
2061 1958
1959 /* first process frames to avoid timing out while a frame is pending */
2062 while ((skb = skb_dequeue(&ifmgd->skb_queue))) 1960 while ((skb = skb_dequeue(&ifmgd->skb_queue)))
2063 ieee80211_sta_rx_queued_mgmt(sdata, skb); 1961 ieee80211_sta_rx_queued_mgmt(sdata, skb);
2064 1962
2065 if (ifmgd->state != IEEE80211_STA_MLME_DIRECT_PROBE && 1963 /* then process the rest of the work */
2066 ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE && 1964 mutex_lock(&ifmgd->mtx);
2067 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE && 1965
2068 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) { 1966 list_for_each_entry(wk, &ifmgd->work_list, list) {
2069 queue_delayed_work(local->hw.workqueue, &local->scan_work, 1967 if (wk->state != IEEE80211_MGD_STATE_IDLE) {
2070 round_jiffies_relative(0)); 1968 anybusy = true;
2071 return; 1969 break;
1970 }
2072 } 1971 }
2073 1972
2074 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request)) { 1973 ieee80211_recalc_idle(local);
2075 if (ieee80211_sta_config_auth(sdata)) 1974
2076 return; 1975 if (!anybusy) {
2077 clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request); 1976 mutex_unlock(&ifmgd->mtx);
2078 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request)) 1977
1978 if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
1979 queue_delayed_work(local->hw.workqueue,
1980 &local->scan_work,
1981 round_jiffies_relative(0));
2079 return; 1982 return;
1983 }
2080 1984
2081 ieee80211_recalc_idle(local); 1985 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
1986 if (time_before(jiffies, wk->timeout))
1987 continue;
2082 1988
2083 switch (ifmgd->state) { 1989 switch (wk->state) {
2084 case IEEE80211_STA_MLME_DISABLED: 1990 default:
2085 break; 1991 WARN_ON(1);
2086 case IEEE80211_STA_MLME_DIRECT_PROBE: 1992 /* fall through */
2087 ieee80211_direct_probe(sdata); 1993 case IEEE80211_MGD_STATE_IDLE:
2088 break; 1994 /* nothing */
2089 case IEEE80211_STA_MLME_AUTHENTICATE: 1995 rma = RX_MGMT_NONE;
2090 ieee80211_authenticate(sdata); 1996 break;
2091 break; 1997 case IEEE80211_MGD_STATE_PROBE:
2092 case IEEE80211_STA_MLME_ASSOCIATE: 1998 rma = ieee80211_direct_probe(sdata, wk);
2093 ieee80211_associate(sdata); 1999 break;
2094 break; 2000 case IEEE80211_MGD_STATE_AUTH:
2095 case IEEE80211_STA_MLME_ASSOCIATED: 2001 rma = ieee80211_authenticate(sdata, wk);
2096 ieee80211_associated(sdata); 2002 break;
2097 break; 2003 case IEEE80211_MGD_STATE_ASSOC:
2098 default: 2004 rma = ieee80211_associate(sdata, wk);
2099 WARN_ON(1); 2005 break;
2100 break; 2006 }
2007
2008 switch (rma) {
2009 case RX_MGMT_NONE:
2010 /* no action required */
2011 break;
2012 case RX_MGMT_CFG80211_AUTH_TO:
2013 case RX_MGMT_CFG80211_ASSOC_TO:
2014 list_del(&wk->list);
2015 list_add(&wk->list, &free_work);
2016 wk->tries = rma; /* small abuse but only local */
2017 break;
2018 default:
2019 WARN(1, "unexpected: %d", rma);
2020 }
2021 }
2022
2023 mutex_unlock(&ifmgd->mtx);
2024
2025 list_for_each_entry_safe(wk, tmp, &free_work, list) {
2026 switch (wk->tries) {
2027 case RX_MGMT_CFG80211_AUTH_TO:
2028 cfg80211_send_auth_timeout(sdata->dev,
2029 wk->bss->cbss.bssid,
2030 GFP_KERNEL);
2031 break;
2032 case RX_MGMT_CFG80211_ASSOC_TO:
2033 cfg80211_send_auth_timeout(sdata->dev,
2034 wk->bss->cbss.bssid,
2035 GFP_KERNEL);
2036 break;
2037 default:
2038 WARN(1, "unexpected: %d", wk->tries);
2039 }
2040
2041 list_del(&wk->list);
2042 kfree(wk);
2101 } 2043 }
2044
2045 ieee80211_recalc_idle(local);
2102} 2046}
2103 2047
2104static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) 2048static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
@@ -2110,7 +2054,6 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
2110 */ 2054 */
2111 sdata->u.mgd.last_beacon = jiffies; 2055 sdata->u.mgd.last_beacon = jiffies;
2112 2056
2113
2114 queue_work(sdata->local->hw.workqueue, 2057 queue_work(sdata->local->hw.workqueue,
2115 &sdata->u.mgd.work); 2058 &sdata->u.mgd.work);
2116 } 2059 }
@@ -2152,7 +2095,6 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
2152void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) 2095void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2153{ 2096{
2154 struct ieee80211_if_managed *ifmgd; 2097 struct ieee80211_if_managed *ifmgd;
2155 u32 hw_flags;
2156 2098
2157 ifmgd = &sdata->u.mgd; 2099 ifmgd = &sdata->u.mgd;
2158 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 2100 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
@@ -2164,113 +2106,239 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2164 (unsigned long) sdata); 2106 (unsigned long) sdata);
2165 skb_queue_head_init(&ifmgd->skb_queue); 2107 skb_queue_head_init(&ifmgd->skb_queue);
2166 2108
2109 INIT_LIST_HEAD(&ifmgd->work_list);
2110
2167 ifmgd->capab = WLAN_CAPABILITY_ESS; 2111 ifmgd->capab = WLAN_CAPABILITY_ESS;
2168 ifmgd->flags = 0; 2112 ifmgd->flags = 0;
2169 if (sdata->local->hw.queues >= 4) 2113 if (sdata->local->hw.queues >= 4)
2170 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 2114 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2171 2115
2172 hw_flags = sdata->local->hw.flags; 2116 mutex_init(&ifmgd->mtx);
2173} 2117}
2174 2118
2175/* configuration hooks */ 2119/* scan finished notification */
2176void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata) 2120void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2177{ 2121{
2178 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2122 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
2179 struct ieee80211_local *local = sdata->local;
2180 2123
2181 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) 2124 /* Restart STA timers */
2182 return; 2125 rcu_read_lock();
2126 list_for_each_entry_rcu(sdata, &local->interfaces, list)
2127 ieee80211_restart_sta_timer(sdata);
2128 rcu_read_unlock();
2129}
2183 2130
2184 if (WARN_ON(ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)) 2131int ieee80211_max_network_latency(struct notifier_block *nb,
2185 ieee80211_set_disassoc(sdata, true, true, 2132 unsigned long data, void *dummy)
2186 WLAN_REASON_DEAUTH_LEAVING); 2133{
2134 s32 latency_usec = (s32) data;
2135 struct ieee80211_local *local =
2136 container_of(nb, struct ieee80211_local,
2137 network_latency_notifier);
2187 2138
2188 if (WARN_ON(ifmgd->ssid_len == 0)) { 2139 mutex_lock(&local->iflist_mtx);
2189 /* 2140 ieee80211_recalc_ps(local, latency_usec);
2190 * Only allow association to be started if a valid SSID 2141 mutex_unlock(&local->iflist_mtx);
2191 * is configured.
2192 */
2193 return;
2194 }
2195 2142
2196 set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request); 2143 return 0;
2197 queue_work(local->hw.workqueue, &ifmgd->work);
2198} 2144}
2199 2145
2200int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, 2146/* config hooks */
2201 const char *ie, size_t len) 2147int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2148 struct cfg80211_auth_request *req)
2202{ 2149{
2203 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2150 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2151 const u8 *ssid;
2152 struct ieee80211_mgd_work *wk;
2153 u16 auth_alg;
2204 2154
2205 if (len == 0 && ifmgd->extra_ie_len == 0) 2155 switch (req->auth_type) {
2206 return -EALREADY; 2156 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2207 2157 auth_alg = WLAN_AUTH_OPEN;
2208 if (len == ifmgd->extra_ie_len && ifmgd->extra_ie && 2158 break;
2209 memcmp(ifmgd->extra_ie, ie, len) == 0) 2159 case NL80211_AUTHTYPE_SHARED_KEY:
2210 return -EALREADY; 2160 auth_alg = WLAN_AUTH_SHARED_KEY;
2211 2161 break;
2212 kfree(ifmgd->extra_ie); 2162 case NL80211_AUTHTYPE_FT:
2213 if (len == 0) { 2163 auth_alg = WLAN_AUTH_FT;
2214 ifmgd->extra_ie = NULL; 2164 break;
2215 ifmgd->extra_ie_len = 0; 2165 case NL80211_AUTHTYPE_NETWORK_EAP:
2216 return 0; 2166 auth_alg = WLAN_AUTH_LEAP;
2167 break;
2168 default:
2169 return -EOPNOTSUPP;
2217 } 2170 }
2218 ifmgd->extra_ie = kmalloc(len, GFP_KERNEL); 2171
2219 if (!ifmgd->extra_ie) { 2172 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
2220 ifmgd->extra_ie_len = 0; 2173 if (!wk)
2221 return -ENOMEM; 2174 return -ENOMEM;
2175
2176 wk->bss = (void *)req->bss;
2177
2178 if (req->ie && req->ie_len) {
2179 memcpy(wk->ie, req->ie, req->ie_len);
2180 wk->ie_len = req->ie_len;
2222 } 2181 }
2223 memcpy(ifmgd->extra_ie, ie, len); 2182
2224 ifmgd->extra_ie_len = len; 2183 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
2184 memcpy(wk->ssid, ssid + 2, ssid[1]);
2185 wk->ssid_len = ssid[1];
2186
2187 wk->state = IEEE80211_MGD_STATE_PROBE;
2188 wk->auth_alg = auth_alg;
2189
2190 /*
2191 * XXX: if still associated need to tell AP that we're going
2192 * to sleep and then change channel etc.
2193 */
2194 sdata->local->oper_channel = req->bss->channel;
2195 ieee80211_hw_config(sdata->local, 0);
2196
2197 mutex_lock(&ifmgd->mtx);
2198 list_add(&wk->list, &sdata->u.mgd.work_list);
2199 mutex_unlock(&ifmgd->mtx);
2200
2201 queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work);
2225 return 0; 2202 return 0;
2226} 2203}
2227 2204
2228int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason) 2205int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2206 struct cfg80211_assoc_request *req)
2229{ 2207{
2230 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", 2208 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2231 sdata->dev->name, reason); 2209 struct ieee80211_mgd_work *wk, *found = NULL;
2210 int i, err;
2232 2211
2233 ieee80211_set_disassoc(sdata, true, true, reason); 2212 mutex_lock(&ifmgd->mtx);
2234 return 0; 2213
2214 list_for_each_entry(wk, &ifmgd->work_list, list) {
2215 if (&wk->bss->cbss == req->bss &&
2216 wk->state == IEEE80211_MGD_STATE_IDLE) {
2217 found = wk;
2218 break;
2219 }
2220 }
2221
2222 if (!found) {
2223 err = -ENOLINK;
2224 goto out;
2225 }
2226
2227 list_del(&found->list);
2228
2229 wk = krealloc(found, sizeof(*wk) + req->ie_len, GFP_KERNEL);
2230 if (!wk) {
2231 list_add(&found->list, &ifmgd->work_list);
2232 err = -ENOMEM;
2233 goto out;
2234 }
2235
2236 list_add(&wk->list, &ifmgd->work_list);
2237
2238 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2239
2240 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
2241 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
2242 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
2243 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
2244 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
2245
2246 sdata->local->oper_channel = req->bss->channel;
2247 ieee80211_hw_config(sdata->local, 0);
2248
2249 if (req->ie && req->ie_len) {
2250 memcpy(wk->ie, req->ie, req->ie_len);
2251 wk->ie_len = req->ie_len;
2252 } else
2253 wk->ie_len = 0;
2254
2255 if (req->prev_bssid)
2256 memcpy(wk->prev_bssid, req->prev_bssid, ETH_ALEN);
2257
2258 wk->state = IEEE80211_MGD_STATE_ASSOC;
2259 wk->tries = 0;
2260
2261 if (req->use_mfp) {
2262 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
2263 ifmgd->flags |= IEEE80211_STA_MFP_ENABLED;
2264 } else {
2265 ifmgd->mfp = IEEE80211_MFP_DISABLED;
2266 ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED;
2267 }
2268
2269 if (req->crypto.control_port)
2270 ifmgd->flags |= IEEE80211_STA_CONTROL_PORT;
2271 else
2272 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
2273
2274 queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work);
2275
2276 err = 0;
2277
2278 out:
2279 mutex_unlock(&ifmgd->mtx);
2280 return err;
2235} 2281}
2236 2282
2237int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason) 2283int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2284 struct cfg80211_deauth_request *req)
2238{ 2285{
2239 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2286 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2287 struct ieee80211_mgd_work *wk;
2288 const u8 *bssid = NULL;
2240 2289
2241 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", 2290 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
2242 sdata->dev->name, reason); 2291 sdata->dev->name, req->reason_code);
2292
2293 mutex_lock(&ifmgd->mtx);
2294
2295 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
2296 bssid = req->bss->bssid;
2297 ieee80211_set_disassoc(sdata, bssid, true);
2298 } else list_for_each_entry(wk, &ifmgd->work_list, list) {
2299 if (&wk->bss->cbss == req->bss) {
2300 bssid = req->bss->bssid;
2301 list_del(&wk->list);
2302 kfree(wk);
2303 break;
2304 }
2305 }
2243 2306
2244 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED)) 2307 /* cfg80211 should catch this... */
2308 if (WARN_ON(!bssid)) {
2309 mutex_unlock(&ifmgd->mtx);
2245 return -ENOLINK; 2310 return -ENOLINK;
2311 }
2312
2313 mutex_unlock(&ifmgd->mtx);
2314
2315 ieee80211_send_deauth_disassoc(sdata, bssid,
2316 IEEE80211_STYPE_DEAUTH, req->reason_code);
2246 2317
2247 ieee80211_set_disassoc(sdata, false, true, reason);
2248 return 0; 2318 return 0;
2249} 2319}
2250 2320
2251/* scan finished notification */ 2321int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2252void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) 2322 struct cfg80211_disassoc_request *req)
2253{ 2323{
2254 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 2324 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2255 2325
2256 /* Restart STA timers */ 2326 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
2257 rcu_read_lock(); 2327 sdata->dev->name, req->reason_code);
2258 list_for_each_entry_rcu(sdata, &local->interfaces, list)
2259 ieee80211_restart_sta_timer(sdata);
2260 rcu_read_unlock();
2261}
2262 2328
2263int ieee80211_max_network_latency(struct notifier_block *nb, 2329 mutex_lock(&ifmgd->mtx);
2264 unsigned long data, void *dummy)
2265{
2266 s32 latency_usec = (s32) data;
2267 struct ieee80211_local *local =
2268 container_of(nb, struct ieee80211_local,
2269 network_latency_notifier);
2270 2330
2271 mutex_lock(&local->iflist_mtx); 2331 /* cfg80211 should catch that */
2272 ieee80211_recalc_ps(local, latency_usec); 2332 if (WARN_ON(&ifmgd->associated->cbss != req->bss)) {
2273 mutex_unlock(&local->iflist_mtx); 2333 mutex_unlock(&ifmgd->mtx);
2334 return -ENOLINK;
2335 }
2336
2337 ieee80211_set_disassoc(sdata, req->bss->bssid, false);
2338
2339 mutex_unlock(&ifmgd->mtx);
2274 2340
2341 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2342 IEEE80211_STYPE_DISASSOC, req->reason_code);
2275 return 0; 2343 return 0;
2276} 2344}