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.c1390
1 files changed, 1002 insertions, 388 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 49fd1acd5d15..52133dab9297 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -30,6 +30,12 @@
30#include "rate.h" 30#include "rate.h"
31#include "led.h" 31#include "led.h"
32 32
33#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
34#define IEEE80211_AUTH_MAX_TRIES 3
35#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
36#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
37#define IEEE80211_ASSOC_MAX_TRIES 3
38
33static int max_nullfunc_tries = 2; 39static int max_nullfunc_tries = 2;
34module_param(max_nullfunc_tries, int, 0644); 40module_param(max_nullfunc_tries, int, 0644);
35MODULE_PARM_DESC(max_nullfunc_tries, 41MODULE_PARM_DESC(max_nullfunc_tries,
@@ -97,6 +103,15 @@ enum rx_mgmt_action {
97 103
98 /* caller must call cfg80211_send_disassoc() */ 104 /* caller must call cfg80211_send_disassoc() */
99 RX_MGMT_CFG80211_DISASSOC, 105 RX_MGMT_CFG80211_DISASSOC,
106
107 /* caller must call cfg80211_send_rx_auth() */
108 RX_MGMT_CFG80211_RX_AUTH,
109
110 /* caller must call cfg80211_send_rx_assoc() */
111 RX_MGMT_CFG80211_RX_ASSOC,
112
113 /* caller must call cfg80211_send_assoc_timeout() */
114 RX_MGMT_CFG80211_ASSOC_TIMEOUT,
100}; 115};
101 116
102/* utils */ 117/* utils */
@@ -115,8 +130,7 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
115 * has happened -- the work that runs from this timer will 130 * has happened -- the work that runs from this timer will
116 * do that. 131 * do that.
117 */ 132 */
118static void run_again(struct ieee80211_if_managed *ifmgd, 133static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout)
119 unsigned long timeout)
120{ 134{
121 ASSERT_MGD_MTX(ifmgd); 135 ASSERT_MGD_MTX(ifmgd);
122 136
@@ -284,6 +298,319 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
284 298
285/* frame sending functions */ 299/* frame sending functions */
286 300
301static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
302 struct ieee80211_supported_band *sband,
303 u32 *rates)
304{
305 int i, j, count;
306 *rates = 0;
307 count = 0;
308 for (i = 0; i < supp_rates_len; i++) {
309 int rate = (supp_rates[i] & 0x7F) * 5;
310
311 for (j = 0; j < sband->n_bitrates; j++)
312 if (sband->bitrates[j].bitrate == rate) {
313 *rates |= BIT(j);
314 count++;
315 break;
316 }
317 }
318
319 return count;
320}
321
322static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
323 struct sk_buff *skb, const u8 *ht_info_ie,
324 struct ieee80211_supported_band *sband,
325 struct ieee80211_channel *channel,
326 enum ieee80211_smps_mode smps)
327{
328 struct ieee80211_ht_info *ht_info;
329 u8 *pos;
330 u32 flags = channel->flags;
331 u16 cap;
332 struct ieee80211_sta_ht_cap ht_cap;
333
334 BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
335
336 if (!sband->ht_cap.ht_supported)
337 return;
338
339 if (!ht_info_ie)
340 return;
341
342 if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
343 return;
344
345 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
346 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
347
348 ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
349
350 /* determine capability flags */
351 cap = ht_cap.cap;
352
353 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
354 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
355 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
356 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
357 cap &= ~IEEE80211_HT_CAP_SGI_40;
358 }
359 break;
360 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
361 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
362 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
363 cap &= ~IEEE80211_HT_CAP_SGI_40;
364 }
365 break;
366 }
367
368 /* set SM PS mode properly */
369 cap &= ~IEEE80211_HT_CAP_SM_PS;
370 switch (smps) {
371 case IEEE80211_SMPS_AUTOMATIC:
372 case IEEE80211_SMPS_NUM_MODES:
373 WARN_ON(1);
374 case IEEE80211_SMPS_OFF:
375 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
376 IEEE80211_HT_CAP_SM_PS_SHIFT;
377 break;
378 case IEEE80211_SMPS_STATIC:
379 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
380 IEEE80211_HT_CAP_SM_PS_SHIFT;
381 break;
382 case IEEE80211_SMPS_DYNAMIC:
383 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
384 IEEE80211_HT_CAP_SM_PS_SHIFT;
385 break;
386 }
387
388 /* reserve and fill IE */
389 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
390 ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
391}
392
393static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
394{
395 struct ieee80211_local *local = sdata->local;
396 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
397 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
398 struct sk_buff *skb;
399 struct ieee80211_mgmt *mgmt;
400 u8 *pos, qos_info;
401 size_t offset = 0, noffset;
402 int i, count, rates_len, supp_rates_len;
403 u16 capab;
404 struct ieee80211_supported_band *sband;
405 u32 rates = 0;
406 struct ieee80211_bss *bss = (void *)assoc_data->bss->priv;
407
408 lockdep_assert_held(&ifmgd->mtx);
409
410 sband = local->hw.wiphy->bands[local->oper_channel->band];
411
412 if (assoc_data->supp_rates_len) {
413 /*
414 * Get all rates supported by the device and the AP as
415 * some APs don't like getting a superset of their rates
416 * in the association request (e.g. D-Link DAP 1353 in
417 * b-only mode)...
418 */
419 rates_len = ieee80211_compatible_rates(assoc_data->supp_rates,
420 assoc_data->supp_rates_len,
421 sband, &rates);
422 } else {
423 /*
424 * In case AP not provide any supported rates information
425 * before association, we send information element(s) with
426 * all rates that we support.
427 */
428 rates = ~0;
429 rates_len = sband->n_bitrates;
430 }
431
432 skb = alloc_skb(local->hw.extra_tx_headroom +
433 sizeof(*mgmt) + /* bit too much but doesn't matter */
434 2 + assoc_data->ssid_len + /* SSID */
435 4 + rates_len + /* (extended) rates */
436 4 + /* power capability */
437 2 + 2 * sband->n_channels + /* supported channels */
438 2 + sizeof(struct ieee80211_ht_cap) + /* HT */
439 assoc_data->ie_len + /* extra IEs */
440 9, /* WMM */
441 GFP_KERNEL);
442 if (!skb)
443 return;
444
445 skb_reserve(skb, local->hw.extra_tx_headroom);
446
447 capab = WLAN_CAPABILITY_ESS;
448
449 if (sband->band == IEEE80211_BAND_2GHZ) {
450 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
451 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
452 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
453 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
454 }
455
456 if (assoc_data->capability & WLAN_CAPABILITY_PRIVACY)
457 capab |= WLAN_CAPABILITY_PRIVACY;
458
459 if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
460 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
461 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
462
463 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
464 memset(mgmt, 0, 24);
465 memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN);
466 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
467 memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);
468
469 if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
470 skb_put(skb, 10);
471 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
472 IEEE80211_STYPE_REASSOC_REQ);
473 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
474 mgmt->u.reassoc_req.listen_interval =
475 cpu_to_le16(local->hw.conf.listen_interval);
476 memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
477 ETH_ALEN);
478 } else {
479 skb_put(skb, 4);
480 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
481 IEEE80211_STYPE_ASSOC_REQ);
482 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
483 mgmt->u.assoc_req.listen_interval =
484 cpu_to_le16(local->hw.conf.listen_interval);
485 }
486
487 /* SSID */
488 pos = skb_put(skb, 2 + assoc_data->ssid_len);
489 *pos++ = WLAN_EID_SSID;
490 *pos++ = assoc_data->ssid_len;
491 memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
492
493 /* add all rates which were marked to be used above */
494 supp_rates_len = rates_len;
495 if (supp_rates_len > 8)
496 supp_rates_len = 8;
497
498 pos = skb_put(skb, supp_rates_len + 2);
499 *pos++ = WLAN_EID_SUPP_RATES;
500 *pos++ = supp_rates_len;
501
502 count = 0;
503 for (i = 0; i < sband->n_bitrates; i++) {
504 if (BIT(i) & rates) {
505 int rate = sband->bitrates[i].bitrate;
506 *pos++ = (u8) (rate / 5);
507 if (++count == 8)
508 break;
509 }
510 }
511
512 if (rates_len > count) {
513 pos = skb_put(skb, rates_len - count + 2);
514 *pos++ = WLAN_EID_EXT_SUPP_RATES;
515 *pos++ = rates_len - count;
516
517 for (i++; i < sband->n_bitrates; i++) {
518 if (BIT(i) & rates) {
519 int rate = sband->bitrates[i].bitrate;
520 *pos++ = (u8) (rate / 5);
521 }
522 }
523 }
524
525 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
526 /* 1. power capabilities */
527 pos = skb_put(skb, 4);
528 *pos++ = WLAN_EID_PWR_CAPABILITY;
529 *pos++ = 2;
530 *pos++ = 0; /* min tx power */
531 *pos++ = local->oper_channel->max_power; /* max tx power */
532
533 /* 2. supported channels */
534 /* TODO: get this in reg domain format */
535 pos = skb_put(skb, 2 * sband->n_channels + 2);
536 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
537 *pos++ = 2 * sband->n_channels;
538 for (i = 0; i < sband->n_channels; i++) {
539 *pos++ = ieee80211_frequency_to_channel(
540 sband->channels[i].center_freq);
541 *pos++ = 1; /* one channel in the subband*/
542 }
543 }
544
545 /* if present, add any custom IEs that go before HT */
546 if (assoc_data->ie_len && assoc_data->ie) {
547 static const u8 before_ht[] = {
548 WLAN_EID_SSID,
549 WLAN_EID_SUPP_RATES,
550 WLAN_EID_EXT_SUPP_RATES,
551 WLAN_EID_PWR_CAPABILITY,
552 WLAN_EID_SUPPORTED_CHANNELS,
553 WLAN_EID_RSN,
554 WLAN_EID_QOS_CAPA,
555 WLAN_EID_RRM_ENABLED_CAPABILITIES,
556 WLAN_EID_MOBILITY_DOMAIN,
557 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
558 };
559 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
560 before_ht, ARRAY_SIZE(before_ht),
561 offset);
562 pos = skb_put(skb, noffset - offset);
563 memcpy(pos, assoc_data->ie + offset, noffset - offset);
564 offset = noffset;
565 }
566
567 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) &&
568 bss->wmm_used && local->hw.queues >= 4)
569 ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
570 sband, local->oper_channel, ifmgd->ap_smps);
571
572 /* if present, add any custom non-vendor IEs that go after HT */
573 if (assoc_data->ie_len && assoc_data->ie) {
574 noffset = ieee80211_ie_split_vendor(assoc_data->ie,
575 assoc_data->ie_len,
576 offset);
577 pos = skb_put(skb, noffset - offset);
578 memcpy(pos, assoc_data->ie + offset, noffset - offset);
579 offset = noffset;
580 }
581
582 if (assoc_data->wmm_used && local->hw.queues >= 4) {
583 if (assoc_data->uapsd_used) {
584 qos_info = local->uapsd_queues;
585 qos_info |= (local->uapsd_max_sp_len <<
586 IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
587 } else {
588 qos_info = 0;
589 }
590
591 pos = skb_put(skb, 9);
592 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
593 *pos++ = 7; /* len */
594 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
595 *pos++ = 0x50;
596 *pos++ = 0xf2;
597 *pos++ = 2; /* WME */
598 *pos++ = 0; /* WME info */
599 *pos++ = 1; /* WME ver */
600 *pos++ = qos_info;
601 }
602
603 /* add any remaining custom (i.e. vendor specific here) IEs */
604 if (assoc_data->ie_len && assoc_data->ie) {
605 noffset = assoc_data->ie_len;
606 pos = skb_put(skb, noffset - offset);
607 memcpy(pos, assoc_data->ie + offset, noffset - offset);
608 }
609
610 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
611 ieee80211_tx_skb(sdata, skb);
612}
613
287static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 614static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
288 const u8 *bssid, u16 stype, u16 reason, 615 const u8 *bssid, u16 stype, u16 reason,
289 void *cookie, bool send_frame) 616 void *cookie, bool send_frame)
@@ -1423,6 +1750,135 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
1423EXPORT_SYMBOL(ieee80211_connection_loss); 1750EXPORT_SYMBOL(ieee80211_connection_loss);
1424 1751
1425 1752
1753static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1754 bool assoc)
1755{
1756 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
1757
1758 lockdep_assert_held(&sdata->u.mgd.mtx);
1759
1760 if (auth_data->synced)
1761 drv_finish_tx_sync(sdata->local, sdata,
1762 auth_data->bss->bssid,
1763 IEEE80211_TX_SYNC_AUTH);
1764
1765 if (!assoc) {
1766 sta_info_destroy_addr(sdata, auth_data->bss->bssid);
1767
1768 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
1769 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
1770 }
1771
1772 cfg80211_put_bss(auth_data->bss);
1773 kfree(auth_data);
1774 sdata->u.mgd.auth_data = NULL;
1775}
1776
1777static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1778 struct ieee80211_mgmt *mgmt, size_t len)
1779{
1780 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
1781 u8 *pos;
1782 struct ieee802_11_elems elems;
1783
1784 pos = mgmt->u.auth.variable;
1785 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1786 if (!elems.challenge)
1787 return;
1788 auth_data->expected_transaction = 4;
1789 ieee80211_send_auth(sdata, 3, auth_data->algorithm,
1790 elems.challenge - 2, elems.challenge_len + 2,
1791 auth_data->bss->bssid, auth_data->bss->bssid,
1792 auth_data->key, auth_data->key_len,
1793 auth_data->key_idx);
1794}
1795
1796static enum rx_mgmt_action __must_check
1797ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1798 struct ieee80211_mgmt *mgmt, size_t len)
1799{
1800 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1801 u8 bssid[ETH_ALEN];
1802 u16 auth_alg, auth_transaction, status_code;
1803 struct sta_info *sta;
1804
1805 lockdep_assert_held(&ifmgd->mtx);
1806
1807 if (len < 24 + 6)
1808 return RX_MGMT_NONE;
1809
1810 if (!ifmgd->auth_data || ifmgd->auth_data->done)
1811 return RX_MGMT_NONE;
1812
1813 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
1814
1815 if (memcmp(bssid, mgmt->bssid, ETH_ALEN))
1816 return RX_MGMT_NONE;
1817
1818 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
1819 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1820 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1821
1822 if (auth_alg != ifmgd->auth_data->algorithm ||
1823 auth_transaction != ifmgd->auth_data->expected_transaction)
1824 return RX_MGMT_NONE;
1825
1826 if (status_code != WLAN_STATUS_SUCCESS) {
1827 printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
1828 sdata->name, mgmt->sa, status_code);
1829 goto out;
1830 }
1831
1832 switch (ifmgd->auth_data->algorithm) {
1833 case WLAN_AUTH_OPEN:
1834 case WLAN_AUTH_LEAP:
1835 case WLAN_AUTH_FT:
1836 break;
1837 case WLAN_AUTH_SHARED_KEY:
1838 if (ifmgd->auth_data->expected_transaction != 4) {
1839 ieee80211_auth_challenge(sdata, mgmt, len);
1840 /* need another frame */
1841 return RX_MGMT_NONE;
1842 }
1843 break;
1844 default:
1845 WARN_ONCE(1, "invalid auth alg %d",
1846 ifmgd->auth_data->algorithm);
1847 return RX_MGMT_NONE;
1848 }
1849
1850 printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
1851 out:
1852 if (ifmgd->auth_data->synced)
1853 drv_finish_tx_sync(sdata->local, sdata, bssid,
1854 IEEE80211_TX_SYNC_AUTH);
1855 ifmgd->auth_data->synced = false;
1856 ifmgd->auth_data->done = true;
1857 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
1858 run_again(ifmgd, ifmgd->auth_data->timeout);
1859
1860 /* move station state to auth */
1861 mutex_lock(&sdata->local->sta_mtx);
1862 sta = sta_info_get(sdata, bssid);
1863 if (!sta) {
1864 WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
1865 goto out_err;
1866 }
1867 if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
1868 printk(KERN_DEBUG "%s: failed moving %pM to auth\n",
1869 sdata->name, bssid);
1870 goto out_err;
1871 }
1872 mutex_unlock(&sdata->local->sta_mtx);
1873
1874 return RX_MGMT_CFG80211_RX_AUTH;
1875 out_err:
1876 mutex_unlock(&sdata->local->sta_mtx);
1877 /* ignore frame -- wait for timeout */
1878 return RX_MGMT_NONE;
1879}
1880
1881
1426static enum rx_mgmt_action __must_check 1882static enum rx_mgmt_action __must_check
1427ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 1883ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1428 struct ieee80211_mgmt *mgmt, size_t len) 1884 struct ieee80211_mgmt *mgmt, size_t len)
@@ -1431,10 +1887,14 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1431 const u8 *bssid = NULL; 1887 const u8 *bssid = NULL;
1432 u16 reason_code; 1888 u16 reason_code;
1433 1889
1890 lockdep_assert_held(&ifmgd->mtx);
1891
1434 if (len < 24 + 2) 1892 if (len < 24 + 2)
1435 return RX_MGMT_NONE; 1893 return RX_MGMT_NONE;
1436 1894
1437 ASSERT_MGD_MTX(ifmgd); 1895 if (!ifmgd->associated ||
1896 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
1897 return RX_MGMT_NONE;
1438 1898
1439 bssid = ifmgd->associated->bssid; 1899 bssid = ifmgd->associated->bssid;
1440 1900
@@ -1459,15 +1919,13 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1459 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1919 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1460 u16 reason_code; 1920 u16 reason_code;
1461 1921
1462 if (len < 24 + 2) 1922 lockdep_assert_held(&ifmgd->mtx);
1463 return RX_MGMT_NONE;
1464
1465 ASSERT_MGD_MTX(ifmgd);
1466 1923
1467 if (WARN_ON(!ifmgd->associated)) 1924 if (len < 24 + 2)
1468 return RX_MGMT_NONE; 1925 return RX_MGMT_NONE;
1469 1926
1470 if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN))) 1927 if (!ifmgd->associated ||
1928 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
1471 return RX_MGMT_NONE; 1929 return RX_MGMT_NONE;
1472 1930
1473 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 1931 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
@@ -1524,15 +1982,37 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
1524 } 1982 }
1525} 1983}
1526 1984
1527static bool ieee80211_assoc_success(struct ieee80211_work *wk, 1985static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
1986 bool assoc)
1987{
1988 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
1989
1990 lockdep_assert_held(&sdata->u.mgd.mtx);
1991
1992 if (assoc_data->synced)
1993 drv_finish_tx_sync(sdata->local, sdata,
1994 assoc_data->bss->bssid,
1995 IEEE80211_TX_SYNC_ASSOC);
1996
1997 if (!assoc) {
1998 sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
1999
2000 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
2001 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2002 }
2003
2004 kfree(assoc_data);
2005 sdata->u.mgd.assoc_data = NULL;
2006}
2007
2008static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2009 struct cfg80211_bss *cbss,
1528 struct ieee80211_mgmt *mgmt, size_t len) 2010 struct ieee80211_mgmt *mgmt, size_t len)
1529{ 2011{
1530 struct ieee80211_sub_if_data *sdata = wk->sdata;
1531 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2012 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1532 struct ieee80211_local *local = sdata->local; 2013 struct ieee80211_local *local = sdata->local;
1533 struct ieee80211_supported_band *sband; 2014 struct ieee80211_supported_band *sband;
1534 struct sta_info *sta; 2015 struct sta_info *sta;
1535 struct cfg80211_bss *cbss = wk->assoc.bss;
1536 u8 *pos; 2016 u8 *pos;
1537 u32 rates, basic_rates; 2017 u32 rates, basic_rates;
1538 u16 capab_info, aid; 2018 u16 capab_info, aid;
@@ -1581,29 +2061,15 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1581 * station info was already allocated and inserted before 2061 * station info was already allocated and inserted before
1582 * the association and should be available to us 2062 * the association and should be available to us
1583 */ 2063 */
1584 sta = sta_info_get_rx(sdata, cbss->bssid); 2064 sta = sta_info_get(sdata, cbss->bssid);
1585 if (WARN_ON(!sta)) { 2065 if (WARN_ON(!sta)) {
1586 mutex_unlock(&sdata->local->sta_mtx); 2066 mutex_unlock(&sdata->local->sta_mtx);
1587 return false; 2067 return false;
1588 } 2068 }
1589 2069
1590 err = sta_info_move_state(sta, IEEE80211_STA_AUTH);
1591 if (!err)
1592 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
1593 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1594 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
1595 if (err) {
1596 printk(KERN_DEBUG
1597 "%s: failed to move station %pM to desired state\n",
1598 sdata->name, sta->sta.addr);
1599 WARN_ON(__sta_info_destroy(sta));
1600 mutex_unlock(&sdata->local->sta_mtx);
1601 return false;
1602 }
1603
1604 rates = 0; 2070 rates = 0;
1605 basic_rates = 0; 2071 basic_rates = 0;
1606 sband = local->hw.wiphy->bands[wk->chan->band]; 2072 sband = local->hw.wiphy->bands[local->oper_channel->band];
1607 2073
1608 ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, 2074 ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
1609 &rates, &basic_rates, &have_higher_than_11mbit, 2075 &rates, &basic_rates, &have_higher_than_11mbit,
@@ -1624,11 +2090,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1624 basic_rates = BIT(min_rate_index); 2090 basic_rates = BIT(min_rate_index);
1625 } 2091 }
1626 2092
1627 sta->sta.supp_rates[wk->chan->band] = rates; 2093 sta->sta.supp_rates[local->oper_channel->band] = rates;
1628 sdata->vif.bss_conf.basic_rates = basic_rates; 2094 sdata->vif.bss_conf.basic_rates = basic_rates;
1629 2095
1630 /* cf. IEEE 802.11 9.2.12 */ 2096 /* cf. IEEE 802.11 9.2.12 */
1631 if (wk->chan->band == IEEE80211_BAND_2GHZ && 2097 if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
1632 have_higher_than_11mbit) 2098 have_higher_than_11mbit)
1633 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 2099 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1634 else 2100 else
@@ -1648,15 +2114,22 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1648 if (elems.wmm_param) 2114 if (elems.wmm_param)
1649 set_sta_flag(sta, WLAN_STA_WME); 2115 set_sta_flag(sta, WLAN_STA_WME);
1650 2116
1651 /* sta_info_reinsert will also unlock the mutex lock */ 2117 err = sta_info_move_state(sta, IEEE80211_STA_AUTH);
1652 err = sta_info_reinsert(sta); 2118 if (!err)
1653 sta = NULL; 2119 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
2120 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
2121 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
1654 if (err) { 2122 if (err) {
1655 printk(KERN_DEBUG "%s: failed to insert STA entry for" 2123 printk(KERN_DEBUG
1656 " the AP (error %d)\n", sdata->name, err); 2124 "%s: failed to move station %pM to desired state\n",
2125 sdata->name, sta->sta.addr);
2126 WARN_ON(__sta_info_destroy(sta));
2127 mutex_unlock(&sdata->local->sta_mtx);
1657 return false; 2128 return false;
1658 } 2129 }
1659 2130
2131 mutex_unlock(&sdata->local->sta_mtx);
2132
1660 /* 2133 /*
1661 * Always handle WMM once after association regardless 2134 * Always handle WMM once after association regardless
1662 * of the first value the AP uses. Setting -1 here has 2135 * of the first value the AP uses. Setting -1 here has
@@ -1671,8 +2144,6 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1671 else 2144 else
1672 ieee80211_set_wmm_default(sdata); 2145 ieee80211_set_wmm_default(sdata);
1673 2146
1674 local->oper_channel = wk->chan;
1675
1676 if (elems.ht_info_elem && elems.wmm_param && 2147 if (elems.ht_info_elem && elems.wmm_param &&
1677 (sdata->local->hw.queues >= 4) && 2148 (sdata->local->hw.queues >= 4) &&
1678 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2149 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
@@ -1703,7 +2174,82 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1703 return true; 2174 return true;
1704} 2175}
1705 2176
2177static enum rx_mgmt_action __must_check
2178ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2179 struct ieee80211_mgmt *mgmt, size_t len,
2180 struct cfg80211_bss **bss)
2181{
2182 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2183 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
2184 u16 capab_info, status_code, aid;
2185 struct ieee802_11_elems elems;
2186 u8 *pos;
2187 bool reassoc;
2188
2189 lockdep_assert_held(&ifmgd->mtx);
2190
2191 if (!assoc_data)
2192 return RX_MGMT_NONE;
2193 if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN))
2194 return RX_MGMT_NONE;
1706 2195
2196 /*
2197 * AssocResp and ReassocResp have identical structure, so process both
2198 * of them in this function.
2199 */
2200
2201 if (len < 24 + 6)
2202 return RX_MGMT_NONE;
2203
2204 reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
2205 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
2206 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
2207 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
2208
2209 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
2210 "status=%d aid=%d)\n",
2211 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
2212 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
2213
2214 pos = mgmt->u.assoc_resp.variable;
2215 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
2216
2217 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
2218 elems.timeout_int && elems.timeout_int_len == 5 &&
2219 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
2220 u32 tu, ms;
2221 tu = get_unaligned_le32(elems.timeout_int + 1);
2222 ms = tu * 1024 / 1000;
2223 printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
2224 "comeback duration %u TU (%u ms)\n",
2225 sdata->name, mgmt->sa, tu, ms);
2226 assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
2227 if (ms > IEEE80211_ASSOC_TIMEOUT)
2228 run_again(ifmgd, assoc_data->timeout);
2229 return RX_MGMT_NONE;
2230 }
2231
2232 *bss = assoc_data->bss;
2233
2234 if (status_code != WLAN_STATUS_SUCCESS) {
2235 printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
2236 sdata->name, mgmt->sa, status_code);
2237 ieee80211_destroy_assoc_data(sdata, false);
2238 } else {
2239 printk(KERN_DEBUG "%s: associated\n", sdata->name);
2240
2241 ieee80211_destroy_assoc_data(sdata, true);
2242
2243 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
2244 /* oops -- internal error -- send timeout for now */
2245 sta_info_destroy_addr(sdata, mgmt->bssid);
2246 cfg80211_put_bss(*bss);
2247 return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
2248 }
2249 }
2250
2251 return RX_MGMT_CFG80211_RX_ASSOC;
2252}
1707static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2253static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1708 struct ieee80211_mgmt *mgmt, 2254 struct ieee80211_mgmt *mgmt,
1709 size_t len, 2255 size_t len,
@@ -1717,7 +2263,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1717 struct ieee80211_channel *channel; 2263 struct ieee80211_channel *channel;
1718 bool need_ps = false; 2264 bool need_ps = false;
1719 2265
1720 if (sdata->u.mgd.associated) { 2266 if (sdata->u.mgd.associated &&
2267 memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
2268 ETH_ALEN) == 0) {
1721 bss = (void *)sdata->u.mgd.associated->priv; 2269 bss = (void *)sdata->u.mgd.associated->priv;
1722 /* not previously set so we may need to recalc */ 2270 /* not previously set so we may need to recalc */
1723 need_ps = !bss->dtim_period; 2271 need_ps = !bss->dtim_period;
@@ -1787,6 +2335,15 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1787 if (ifmgd->associated && 2335 if (ifmgd->associated &&
1788 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) 2336 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
1789 ieee80211_reset_ap_probe(sdata); 2337 ieee80211_reset_ap_probe(sdata);
2338
2339 if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
2340 memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) {
2341 /* got probe response, continue with auth */
2342 printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
2343 ifmgd->auth_data->tries = 0;
2344 ifmgd->auth_data->timeout = jiffies;
2345 run_again(ifmgd, ifmgd->auth_data->timeout);
2346 }
1790} 2347}
1791 2348
1792/* 2349/*
@@ -1826,7 +2383,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1826 u32 ncrc; 2383 u32 ncrc;
1827 u8 *bssid; 2384 u8 *bssid;
1828 2385
1829 ASSERT_MGD_MTX(ifmgd); 2386 lockdep_assert_held(&ifmgd->mtx);
1830 2387
1831 /* Process beacon from the current BSS */ 2388 /* Process beacon from the current BSS */
1832 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 2389 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1836,21 +2393,25 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1836 if (rx_status->freq != local->hw.conf.channel->center_freq) 2393 if (rx_status->freq != local->hw.conf.channel->center_freq)
1837 return; 2394 return;
1838 2395
1839 /* 2396 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
1840 * We might have received a number of frames, among them a 2397 memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) {
1841 * disassoc frame and a beacon... 2398 ieee802_11_parse_elems(mgmt->u.beacon.variable,
1842 */ 2399 len - baselen, &elems);
1843 if (!ifmgd->associated)
1844 return;
1845 2400
1846 bssid = ifmgd->associated->bssid; 2401 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
2402 false);
2403 ifmgd->assoc_data->have_beacon = true;
2404 ifmgd->assoc_data->sent_assoc = false;
2405 /* continue assoc process */
2406 ifmgd->assoc_data->timeout = jiffies;
2407 run_again(ifmgd, ifmgd->assoc_data->timeout);
2408 return;
2409 }
1847 2410
1848 /* 2411 if (!ifmgd->associated ||
1849 * And in theory even frames from a different AP we were just 2412 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
1850 * associated to a split-second ago!
1851 */
1852 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1853 return; 2413 return;
2414 bssid = ifmgd->associated->bssid;
1854 2415
1855 /* Track average RSSI from the Beacon frames of the current AP */ 2416 /* Track average RSSI from the Beacon frames of the current AP */
1856 ifmgd->last_beacon_signal = rx_status->signal; 2417 ifmgd->last_beacon_signal = rx_status->signal;
@@ -2034,6 +2595,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2034 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2595 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2035 struct ieee80211_rx_status *rx_status; 2596 struct ieee80211_rx_status *rx_status;
2036 struct ieee80211_mgmt *mgmt; 2597 struct ieee80211_mgmt *mgmt;
2598 struct cfg80211_bss *bss = NULL;
2037 enum rx_mgmt_action rma = RX_MGMT_NONE; 2599 enum rx_mgmt_action rma = RX_MGMT_NONE;
2038 u16 fc; 2600 u16 fc;
2039 2601
@@ -2043,92 +2605,59 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2043 2605
2044 mutex_lock(&ifmgd->mtx); 2606 mutex_lock(&ifmgd->mtx);
2045 2607
2046 if (ifmgd->associated && 2608 switch (fc & IEEE80211_FCTL_STYPE) {
2047 memcmp(ifmgd->associated->bssid, mgmt->bssid, ETH_ALEN) == 0) { 2609 case IEEE80211_STYPE_BEACON:
2048 switch (fc & IEEE80211_FCTL_STYPE) { 2610 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
2049 case IEEE80211_STYPE_BEACON: 2611 break;
2050 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, 2612 case IEEE80211_STYPE_PROBE_RESP:
2051 rx_status); 2613 ieee80211_rx_mgmt_probe_resp(sdata, skb);
2052 break; 2614 break;
2053 case IEEE80211_STYPE_PROBE_RESP: 2615 case IEEE80211_STYPE_AUTH:
2054 ieee80211_rx_mgmt_probe_resp(sdata, skb); 2616 rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
2055 break; 2617 break;
2056 case IEEE80211_STYPE_DEAUTH: 2618 case IEEE80211_STYPE_DEAUTH:
2057 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); 2619 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
2058 break; 2620 break;
2059 case IEEE80211_STYPE_DISASSOC: 2621 case IEEE80211_STYPE_DISASSOC:
2060 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); 2622 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
2061 break; 2623 break;
2062 case IEEE80211_STYPE_ACTION: 2624 case IEEE80211_STYPE_ASSOC_RESP:
2063 switch (mgmt->u.action.category) { 2625 case IEEE80211_STYPE_REASSOC_RESP:
2064 case WLAN_CATEGORY_SPECTRUM_MGMT: 2626 rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss);
2065 ieee80211_sta_process_chanswitch(sdata, 2627 break;
2066 &mgmt->u.action.u.chan_switch.sw_elem, 2628 case IEEE80211_STYPE_ACTION:
2067 (void *)ifmgd->associated->priv, 2629 switch (mgmt->u.action.category) {
2068 rx_status->mactime); 2630 case WLAN_CATEGORY_SPECTRUM_MGMT:
2069 break; 2631 ieee80211_sta_process_chanswitch(sdata,
2070 } 2632 &mgmt->u.action.u.chan_switch.sw_elem,
2071 } 2633 (void *)ifmgd->associated->priv,
2072 mutex_unlock(&ifmgd->mtx); 2634 rx_status->mactime);
2073
2074 switch (rma) {
2075 case RX_MGMT_NONE:
2076 /* no action */
2077 break;
2078 case RX_MGMT_CFG80211_DEAUTH:
2079 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
2080 break;
2081 case RX_MGMT_CFG80211_DISASSOC:
2082 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
2083 break; 2635 break;
2084 default:
2085 WARN(1, "unexpected: %d", rma);
2086 } 2636 }
2087 return;
2088 } 2637 }
2089
2090 mutex_unlock(&ifmgd->mtx); 2638 mutex_unlock(&ifmgd->mtx);
2091 2639
2092 if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && 2640 switch (rma) {
2093 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) { 2641 case RX_MGMT_NONE:
2094 struct ieee80211_local *local = sdata->local; 2642 /* no action */
2095 struct ieee80211_work *wk; 2643 break;
2096 2644 case RX_MGMT_CFG80211_DEAUTH:
2097 mutex_lock(&local->mtx);
2098 list_for_each_entry(wk, &local->work_list, list) {
2099 if (wk->sdata != sdata)
2100 continue;
2101
2102 if (wk->type != IEEE80211_WORK_ASSOC &&
2103 wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
2104 continue;
2105
2106 if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
2107 continue;
2108 if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN))
2109 continue;
2110
2111 /*
2112 * Printing the message only here means we can't
2113 * spuriously print it, but it also means that it
2114 * won't be printed when the frame comes in before
2115 * we even tried to associate or in similar cases.
2116 *
2117 * Ultimately, I suspect cfg80211 should print the
2118 * messages instead.
2119 */
2120 printk(KERN_DEBUG
2121 "%s: deauthenticated from %pM (Reason: %u)\n",
2122 sdata->name, mgmt->bssid,
2123 le16_to_cpu(mgmt->u.deauth.reason_code));
2124
2125 list_del_rcu(&wk->list);
2126 free_work(wk);
2127 break;
2128 }
2129 mutex_unlock(&local->mtx);
2130
2131 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 2645 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
2646 break;
2647 case RX_MGMT_CFG80211_DISASSOC:
2648 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
2649 break;
2650 case RX_MGMT_CFG80211_RX_AUTH:
2651 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
2652 break;
2653 case RX_MGMT_CFG80211_RX_ASSOC:
2654 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
2655 break;
2656 case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
2657 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2658 break;
2659 default:
2660 WARN(1, "unexpected: %d", rma);
2132 } 2661 }
2133} 2662}
2134 2663
@@ -2173,14 +2702,160 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2173 mutex_lock(&ifmgd->mtx); 2702 mutex_lock(&ifmgd->mtx);
2174} 2703}
2175 2704
2705static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2706{
2707 struct ieee80211_local *local = sdata->local;
2708 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2709 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
2710
2711 lockdep_assert_held(&ifmgd->mtx);
2712
2713 if (WARN_ON_ONCE(!auth_data))
2714 return -EINVAL;
2715
2716 if (!auth_data->synced) {
2717 int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid,
2718 IEEE80211_TX_SYNC_AUTH);
2719 if (ret)
2720 return ret;
2721 }
2722 auth_data->synced = true;
2723
2724 auth_data->tries++;
2725
2726 if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
2727 printk(KERN_DEBUG "%s: authentication with %pM timed out\n",
2728 sdata->name, auth_data->bss->bssid);
2729
2730 /*
2731 * Most likely AP is not in the range so remove the
2732 * bss struct for that AP.
2733 */
2734 cfg80211_unlink_bss(local->hw.wiphy, auth_data->bss);
2735
2736 return -ETIMEDOUT;
2737 }
2738
2739 if (auth_data->bss->proberesp_ies) {
2740 printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n",
2741 sdata->name, auth_data->bss->bssid, auth_data->tries,
2742 IEEE80211_AUTH_MAX_TRIES);
2743
2744 auth_data->expected_transaction = 2;
2745 ieee80211_send_auth(sdata, 1, auth_data->algorithm,
2746 auth_data->ie, auth_data->ie_len,
2747 auth_data->bss->bssid,
2748 auth_data->bss->bssid, NULL, 0, 0);
2749 } else {
2750 const u8 *ssidie;
2751
2752 printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
2753 sdata->name, auth_data->bss->bssid, auth_data->tries,
2754 IEEE80211_AUTH_MAX_TRIES);
2755
2756 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
2757 if (!ssidie)
2758 return -EINVAL;
2759 /*
2760 * Direct probe is sent to broadcast address as some APs
2761 * will not answer to direct packet in unassociated state.
2762 */
2763 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
2764 NULL, 0, (u32) -1, true, false);
2765 }
2766
2767 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
2768 run_again(ifmgd, auth_data->timeout);
2769
2770 return 0;
2771}
2772
2773static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
2774{
2775 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
2776 struct ieee80211_local *local = sdata->local;
2777
2778 lockdep_assert_held(&sdata->u.mgd.mtx);
2779
2780 if (!assoc_data->synced) {
2781 int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid,
2782 IEEE80211_TX_SYNC_ASSOC);
2783 if (ret)
2784 return ret;
2785 }
2786 assoc_data->synced = true;
2787
2788 assoc_data->tries++;
2789 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
2790 printk(KERN_DEBUG "%s: association with %pM timed out\n",
2791 sdata->name, assoc_data->bss->bssid);
2792
2793 /*
2794 * Most likely AP is not in the range so remove the
2795 * bss struct for that AP.
2796 */
2797 cfg80211_unlink_bss(local->hw.wiphy, assoc_data->bss);
2798
2799 return -ETIMEDOUT;
2800 }
2801
2802 printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n",
2803 sdata->name, assoc_data->bss->bssid, assoc_data->tries,
2804 IEEE80211_ASSOC_MAX_TRIES);
2805 ieee80211_send_assoc(sdata);
2806
2807 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
2808 run_again(&sdata->u.mgd, assoc_data->timeout);
2809
2810 return 0;
2811}
2812
2176void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) 2813void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2177{ 2814{
2178 struct ieee80211_local *local = sdata->local; 2815 struct ieee80211_local *local = sdata->local;
2179 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2816 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2180 2817
2181 /* then process the rest of the work */
2182 mutex_lock(&ifmgd->mtx); 2818 mutex_lock(&ifmgd->mtx);
2183 2819
2820 if (ifmgd->auth_data &&
2821 time_after(jiffies, ifmgd->auth_data->timeout)) {
2822 if (ifmgd->auth_data->done) {
2823 /*
2824 * ok ... we waited for assoc but userspace didn't,
2825 * so let's just kill the auth data
2826 */
2827 ieee80211_destroy_auth_data(sdata, false);
2828 } else if (ieee80211_probe_auth(sdata)) {
2829 u8 bssid[ETH_ALEN];
2830
2831 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
2832
2833 ieee80211_destroy_auth_data(sdata, false);
2834
2835 mutex_unlock(&ifmgd->mtx);
2836 cfg80211_send_auth_timeout(sdata->dev, bssid);
2837 mutex_lock(&ifmgd->mtx);
2838 }
2839 } else if (ifmgd->auth_data)
2840 run_again(ifmgd, ifmgd->auth_data->timeout);
2841
2842 if (ifmgd->assoc_data &&
2843 time_after(jiffies, ifmgd->assoc_data->timeout)) {
2844 if (!ifmgd->assoc_data->have_beacon ||
2845 ieee80211_do_assoc(sdata)) {
2846 u8 bssid[ETH_ALEN];
2847
2848 memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
2849
2850 ieee80211_destroy_assoc_data(sdata, false);
2851
2852 mutex_unlock(&ifmgd->mtx);
2853 cfg80211_send_assoc_timeout(sdata->dev, bssid);
2854 mutex_lock(&ifmgd->mtx);
2855 }
2856 } else if (ifmgd->assoc_data)
2857 run_again(ifmgd, ifmgd->assoc_data->timeout);
2858
2184 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 2859 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
2185 IEEE80211_STA_CONNECTION_POLL) && 2860 IEEE80211_STA_CONNECTION_POLL) &&
2186 ifmgd->associated) { 2861 ifmgd->associated) {
@@ -2256,6 +2931,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2256 } 2931 }
2257 2932
2258 mutex_unlock(&ifmgd->mtx); 2933 mutex_unlock(&ifmgd->mtx);
2934
2935 mutex_lock(&local->mtx);
2936 ieee80211_recalc_idle(local);
2937 mutex_unlock(&local->mtx);
2259} 2938}
2260 2939
2261static void ieee80211_sta_bcn_mon_timer(unsigned long data) 2940static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -2428,53 +3107,24 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
2428} 3107}
2429 3108
2430/* config hooks */ 3109/* config hooks */
2431static enum work_done_result
2432ieee80211_probe_auth_done(struct ieee80211_work *wk,
2433 struct sk_buff *skb)
2434{
2435 struct ieee80211_local *local = wk->sdata->local;
2436
2437 if (!skb) {
2438 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
2439 goto destroy;
2440 }
2441
2442 if (wk->type == IEEE80211_WORK_AUTH) {
2443 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
2444 goto destroy;
2445 }
2446
2447 mutex_lock(&wk->sdata->u.mgd.mtx);
2448 ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
2449 mutex_unlock(&wk->sdata->u.mgd.mtx);
2450
2451 wk->type = IEEE80211_WORK_AUTH;
2452 wk->probe_auth.tries = 0;
2453 return WORK_DONE_REQUEUE;
2454 destroy:
2455 if (wk->probe_auth.synced)
2456 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2457 IEEE80211_TX_SYNC_AUTH);
2458
2459 return WORK_DONE_DESTROY;
2460}
2461
2462int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 3110int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2463 struct cfg80211_auth_request *req) 3111 struct cfg80211_auth_request *req)
2464{ 3112{
2465 const u8 *ssid; 3113 struct ieee80211_local *local = sdata->local;
2466 struct ieee80211_work *wk; 3114 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3115 struct ieee80211_mgd_auth_data *auth_data;
3116 struct sta_info *sta;
2467 u16 auth_alg; 3117 u16 auth_alg;
3118 int err;
2468 3119
2469 if (req->local_state_change) 3120 /* prepare auth data structure */
2470 return 0; /* no need to update mac80211 state */
2471 3121
2472 switch (req->auth_type) { 3122 switch (req->auth_type) {
2473 case NL80211_AUTHTYPE_OPEN_SYSTEM: 3123 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2474 auth_alg = WLAN_AUTH_OPEN; 3124 auth_alg = WLAN_AUTH_OPEN;
2475 break; 3125 break;
2476 case NL80211_AUTHTYPE_SHARED_KEY: 3126 case NL80211_AUTHTYPE_SHARED_KEY:
2477 if (IS_ERR(sdata->local->wep_tx_tfm)) 3127 if (IS_ERR(local->wep_tx_tfm))
2478 return -EOPNOTSUPP; 3128 return -EOPNOTSUPP;
2479 auth_alg = WLAN_AUTH_SHARED_KEY; 3129 auth_alg = WLAN_AUTH_SHARED_KEY;
2480 break; 3130 break;
@@ -2488,171 +3138,142 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2488 return -EOPNOTSUPP; 3138 return -EOPNOTSUPP;
2489 } 3139 }
2490 3140
2491 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL); 3141 auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL);
2492 if (!wk) 3142 if (!auth_data)
2493 return -ENOMEM; 3143 return -ENOMEM;
2494 3144
2495 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN); 3145 auth_data->bss = req->bss;
2496 3146
2497 if (req->ie && req->ie_len) { 3147 if (req->ie && req->ie_len) {
2498 memcpy(wk->ie, req->ie, req->ie_len); 3148 memcpy(auth_data->ie, req->ie, req->ie_len);
2499 wk->ie_len = req->ie_len; 3149 auth_data->ie_len = req->ie_len;
2500 } 3150 }
2501 3151
2502 if (req->key && req->key_len) { 3152 if (req->key && req->key_len) {
2503 wk->probe_auth.key_len = req->key_len; 3153 auth_data->key_len = req->key_len;
2504 wk->probe_auth.key_idx = req->key_idx; 3154 auth_data->key_idx = req->key_idx;
2505 memcpy(wk->probe_auth.key, req->key, req->key_len); 3155 memcpy(auth_data->key, req->key, req->key_len);
2506 } 3156 }
2507 3157
2508 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 3158 auth_data->algorithm = auth_alg;
2509 memcpy(wk->probe_auth.ssid, ssid + 2, ssid[1]);
2510 wk->probe_auth.ssid_len = ssid[1];
2511
2512 wk->probe_auth.algorithm = auth_alg;
2513 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
2514
2515 /* if we already have a probe, don't probe again */
2516 if (req->bss->proberesp_ies)
2517 wk->type = IEEE80211_WORK_AUTH;
2518 else
2519 wk->type = IEEE80211_WORK_DIRECT_PROBE;
2520 wk->chan = req->bss->channel;
2521 wk->chan_type = NL80211_CHAN_NO_HT;
2522 wk->sdata = sdata;
2523 wk->done = ieee80211_probe_auth_done;
2524
2525 ieee80211_add_work(wk);
2526 return 0;
2527}
2528
2529/* create and insert a dummy station entry */
2530static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata,
2531 u8 *bssid) {
2532 struct sta_info *sta;
2533 int err;
2534 3159
2535 sta = sta_info_alloc(sdata, bssid, GFP_KERNEL); 3160 /* try to authenticate/probe */
2536 if (!sta)
2537 return -ENOMEM;
2538 3161
2539 sta->dummy = true; 3162 mutex_lock(&ifmgd->mtx);
2540 3163
2541 err = sta_info_insert(sta); 3164 if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
2542 sta = NULL; 3165 ifmgd->assoc_data) {
2543 if (err) { 3166 err = -EBUSY;
2544 printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for" 3167 goto err_free;
2545 " the AP (error %d)\n", sdata->name, err);
2546 return err;
2547 } 3168 }
2548 3169
2549 return 0; 3170 if (ifmgd->auth_data)
2550} 3171 ieee80211_destroy_auth_data(sdata, false);
2551 3172
2552static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, 3173 /* prep auth_data so we don't go into idle on disassoc */
2553 struct sk_buff *skb) 3174 ifmgd->auth_data = auth_data;
2554{
2555 struct ieee80211_local *local = wk->sdata->local;
2556 struct ieee80211_mgmt *mgmt;
2557 struct ieee80211_rx_status *rx_status;
2558 struct ieee802_11_elems elems;
2559 struct cfg80211_bss *cbss = wk->assoc.bss;
2560 u16 status;
2561 3175
2562 if (!skb) { 3176 if (ifmgd->associated)
2563 sta_info_destroy_addr(wk->sdata, cbss->bssid); 3177 ieee80211_set_disassoc(sdata, true, false);
2564 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
2565 goto destroy;
2566 }
2567 3178
2568 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { 3179 printk(KERN_DEBUG "%s: authenticate with %pM\n",
2569 mutex_lock(&wk->sdata->u.mgd.mtx); 3180 sdata->name, req->bss->bssid);
2570 rx_status = (void *) skb->cb;
2571 ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
2572 ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
2573 &elems, true);
2574 mutex_unlock(&wk->sdata->u.mgd.mtx);
2575 3181
2576 wk->type = IEEE80211_WORK_ASSOC; 3182 mutex_lock(&local->mtx);
2577 /* not really done yet */ 3183 ieee80211_recalc_idle(sdata->local);
2578 return WORK_DONE_REQUEUE; 3184 mutex_unlock(&local->mtx);
2579 }
2580 3185
2581 mgmt = (void *)skb->data; 3186 /* switch to the right channel */
2582 status = le16_to_cpu(mgmt->u.assoc_resp.status_code); 3187 local->oper_channel = req->bss->channel;
3188 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
2583 3189
2584 if (status == WLAN_STATUS_SUCCESS) { 3190 /* set BSSID */
2585 if (wk->assoc.synced) 3191 memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
2586 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta, 3192 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2587 IEEE80211_TX_SYNC_ASSOC);
2588 3193
2589 mutex_lock(&wk->sdata->u.mgd.mtx); 3194 /* add station entry */
2590 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { 3195 sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
2591 mutex_unlock(&wk->sdata->u.mgd.mtx); 3196 if (!sta) {
2592 /* oops -- internal error -- send timeout for now */ 3197 err = -ENOMEM;
2593 sta_info_destroy_addr(wk->sdata, cbss->bssid); 3198 goto err_clear;
2594 cfg80211_send_assoc_timeout(wk->sdata->dev, 3199 }
2595 wk->filter_ta);
2596 return WORK_DONE_DESTROY;
2597 }
2598 3200
2599 mutex_unlock(&wk->sdata->u.mgd.mtx); 3201 err = sta_info_insert(sta);
2600 } else { 3202 if (err) {
2601 /* assoc failed - destroy the dummy station entry */ 3203 printk(KERN_DEBUG
2602 sta_info_destroy_addr(wk->sdata, cbss->bssid); 3204 "%s: failed to insert STA entry for the AP %pM (error %d)\n",
3205 sdata->name, req->bss->bssid, err);
3206 goto err_clear;
2603 } 3207 }
2604 3208
2605 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); 3209 err = ieee80211_probe_auth(sdata);
2606 destroy: 3210 if (err) {
2607 if (wk->assoc.synced) 3211 if (auth_data->synced)
2608 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta, 3212 drv_finish_tx_sync(local, sdata, req->bss->bssid,
2609 IEEE80211_TX_SYNC_ASSOC); 3213 IEEE80211_TX_SYNC_AUTH);
3214 sta_info_destroy_addr(sdata, req->bss->bssid);
3215 goto err_clear;
3216 }
3217
3218 /* hold our own reference */
3219 cfg80211_ref_bss(auth_data->bss);
3220 err = 0;
3221 goto out_unlock;
3222
3223 err_clear:
3224 ifmgd->auth_data = NULL;
3225 err_free:
3226 kfree(auth_data);
3227 out_unlock:
3228 mutex_unlock(&ifmgd->mtx);
2610 3229
2611 return WORK_DONE_DESTROY; 3230 return err;
2612} 3231}
2613 3232
2614int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, 3233int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2615 struct cfg80211_assoc_request *req) 3234 struct cfg80211_assoc_request *req)
2616{ 3235{
3236 struct ieee80211_local *local = sdata->local;
2617 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3237 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2618 struct ieee80211_bss *bss = (void *)req->bss->priv; 3238 struct ieee80211_bss *bss = (void *)req->bss->priv;
2619 struct ieee80211_work *wk; 3239 struct ieee80211_mgd_assoc_data *assoc_data;
2620 const u8 *ssid; 3240 struct sta_info *sta;
3241 const u8 *ssidie;
2621 int i, err; 3242 int i, err;
2622 3243
3244 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
3245 if (!ssidie)
3246 return -EINVAL;
3247
3248 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
3249 if (!assoc_data)
3250 return -ENOMEM;
3251
2623 mutex_lock(&ifmgd->mtx); 3252 mutex_lock(&ifmgd->mtx);
2624 if (ifmgd->associated) {
2625 if (!req->prev_bssid ||
2626 memcmp(req->prev_bssid, ifmgd->associated->bssid,
2627 ETH_ALEN)) {
2628 /*
2629 * We are already associated and the request was not a
2630 * reassociation request from the current BSS, so
2631 * reject it.
2632 */
2633 mutex_unlock(&ifmgd->mtx);
2634 return -EALREADY;
2635 }
2636 3253
2637 /* Trying to reassociate - clear previous association state */ 3254 if (ifmgd->associated)
2638 ieee80211_set_disassoc(sdata, true, false); 3255 ieee80211_set_disassoc(sdata, true, false);
3256
3257 if (ifmgd->auth_data && !ifmgd->auth_data->done) {
3258 err = -EBUSY;
3259 goto err_free;
2639 } 3260 }
2640 mutex_unlock(&ifmgd->mtx);
2641 3261
2642 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL); 3262 if (ifmgd->assoc_data) {
2643 if (!wk) 3263 err = -EBUSY;
2644 return -ENOMEM; 3264 goto err_free;
3265 }
2645 3266
2646 /* 3267 if (ifmgd->auth_data) {
2647 * create a dummy station info entry in order 3268 bool match;
2648 * to start accepting incoming EAPOL packets from the station 3269
2649 */ 3270 /* keep sta info, bssid if matching */
2650 err = ieee80211_pre_assoc(sdata, req->bss->bssid); 3271 match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0;
2651 if (err) { 3272 ieee80211_destroy_auth_data(sdata, match);
2652 kfree(wk);
2653 return err;
2654 } 3273 }
2655 3274
3275 /* prepare assoc data */
3276
2656 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 3277 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2657 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 3278 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2658 3279
@@ -2664,7 +3285,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2664 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) 3285 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
2665 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3286 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
2666 3287
2667
2668 if (req->flags & ASSOC_REQ_DISABLE_HT) 3288 if (req->flags & ASSOC_REQ_DISABLE_HT)
2669 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3289 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
2670 3290
@@ -2673,16 +3293,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2673 sizeof(ifmgd->ht_capa_mask)); 3293 sizeof(ifmgd->ht_capa_mask));
2674 3294
2675 if (req->ie && req->ie_len) { 3295 if (req->ie && req->ie_len) {
2676 memcpy(wk->ie, req->ie, req->ie_len); 3296 memcpy(assoc_data->ie, req->ie, req->ie_len);
2677 wk->ie_len = req->ie_len; 3297 assoc_data->ie_len = req->ie_len;
2678 } else 3298 }
2679 wk->ie_len = 0;
2680
2681 wk->assoc.bss = req->bss;
2682 3299
2683 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN); 3300 assoc_data->bss = req->bss;
2684 3301
2685 /* new association always uses requested smps mode */
2686 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { 3302 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
2687 if (ifmgd->powersave) 3303 if (ifmgd->powersave)
2688 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC; 3304 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
@@ -2691,7 +3307,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2691 } else 3307 } else
2692 ifmgd->ap_smps = ifmgd->req_smps; 3308 ifmgd->ap_smps = ifmgd->req_smps;
2693 3309
2694 wk->assoc.smps = ifmgd->ap_smps;
2695 /* 3310 /*
2696 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. 3311 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
2697 * We still associate in non-HT mode (11a/b/g) if any one of these 3312 * We still associate in non-HT mode (11a/b/g) if any one of these
@@ -2699,39 +3314,27 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2699 * We can set this to true for non-11n hardware, that'll be checked 3314 * We can set this to true for non-11n hardware, that'll be checked
2700 * separately along with the peer capabilities. 3315 * separately along with the peer capabilities.
2701 */ 3316 */
2702 wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N); 3317 assoc_data->capability = req->bss->capability;
2703 wk->assoc.capability = req->bss->capability; 3318 assoc_data->wmm_used = bss->wmm_used;
2704 wk->assoc.wmm_used = bss->wmm_used; 3319 assoc_data->supp_rates = bss->supp_rates;
2705 wk->assoc.supp_rates = bss->supp_rates; 3320 assoc_data->supp_rates_len = bss->supp_rates_len;
2706 wk->assoc.supp_rates_len = bss->supp_rates_len; 3321 assoc_data->ht_information_ie =
2707 wk->assoc.ht_information_ie =
2708 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION); 3322 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
2709 3323
2710 if (bss->wmm_used && bss->uapsd_supported && 3324 if (bss->wmm_used && bss->uapsd_supported &&
2711 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3325 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
2712 wk->assoc.uapsd_used = true; 3326 assoc_data->uapsd_used = true;
2713 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; 3327 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
2714 } else { 3328 } else {
2715 wk->assoc.uapsd_used = false; 3329 assoc_data->uapsd_used = false;
2716 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; 3330 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
2717 } 3331 }
2718 3332
2719 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 3333 memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
2720 memcpy(wk->assoc.ssid, ssid + 2, ssid[1]); 3334 assoc_data->ssid_len = ssidie[1];
2721 wk->assoc.ssid_len = ssid[1];
2722 3335
2723 if (req->prev_bssid) 3336 if (req->prev_bssid)
2724 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); 3337 memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN);
2725
2726 wk->chan = req->bss->channel;
2727 wk->chan_type = NL80211_CHAN_NO_HT;
2728 wk->sdata = sdata;
2729 wk->done = ieee80211_assoc_done;
2730 if (!bss->dtim_period &&
2731 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
2732 wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
2733 else
2734 wk->type = IEEE80211_WORK_ASSOC;
2735 3338
2736 if (req->use_mfp) { 3339 if (req->use_mfp) {
2737 ifmgd->mfp = IEEE80211_MFP_REQUIRED; 3340 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2749,89 +3352,100 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2749 sdata->control_port_protocol = req->crypto.control_port_ethertype; 3352 sdata->control_port_protocol = req->crypto.control_port_ethertype;
2750 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; 3353 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
2751 3354
2752 ieee80211_add_work(wk); 3355 /* kick off associate process */
2753 return 0; 3356
3357 ifmgd->assoc_data = assoc_data;
3358
3359 mutex_lock(&local->mtx);
3360 ieee80211_recalc_idle(sdata->local);
3361 mutex_unlock(&local->mtx);
3362
3363 /* switch to the right channel */
3364 local->oper_channel = req->bss->channel;
3365 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3366
3367 rcu_read_lock();
3368 sta = sta_info_get(sdata, req->bss->bssid);
3369 rcu_read_unlock();
3370
3371 if (!sta) {
3372 /* set BSSID */
3373 memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
3374 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
3375
3376 sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
3377 if (!sta) {
3378 err = -ENOMEM;
3379 goto err_clear;
3380 }
3381
3382 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
3383
3384 err = sta_info_insert(sta);
3385 sta = NULL;
3386 if (err) {
3387 printk(KERN_DEBUG
3388 "%s: failed to insert STA entry for the AP (error %d)\n",
3389 sdata->name, err);
3390 goto err_clear;
3391 }
3392 } else
3393 WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN));
3394
3395 if (!bss->dtim_period &&
3396 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
3397 /*
3398 * Wait up to one beacon interval ...
3399 * should this be more if we miss one?
3400 */
3401 printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
3402 sdata->name, ifmgd->bssid);
3403 assoc_data->timeout = jiffies +
3404 TU_TO_EXP_TIME(req->bss->beacon_interval);
3405 } else {
3406 assoc_data->have_beacon = true;
3407 assoc_data->sent_assoc = false;
3408 assoc_data->timeout = jiffies;
3409 }
3410 run_again(ifmgd, assoc_data->timeout);
3411
3412 err = 0;
3413 goto out;
3414 err_clear:
3415 ifmgd->assoc_data = NULL;
3416 err_free:
3417 kfree(assoc_data);
3418 out:
3419 mutex_unlock(&ifmgd->mtx);
3420
3421 return err;
2754} 3422}
2755 3423
2756int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, 3424int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2757 struct cfg80211_deauth_request *req, 3425 struct cfg80211_deauth_request *req,
2758 void *cookie) 3426 void *cookie)
2759{ 3427{
2760 struct ieee80211_local *local = sdata->local;
2761 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3428 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2762 u8 bssid[ETH_ALEN];
2763 bool assoc_bss = false; 3429 bool assoc_bss = false;
2764 3430
2765 mutex_lock(&ifmgd->mtx); 3431 mutex_lock(&ifmgd->mtx);
2766 3432
2767 memcpy(bssid, req->bss->bssid, ETH_ALEN); 3433 if (ifmgd->associated &&
2768 if (ifmgd->associated == req->bss) { 3434 memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) {
2769 ieee80211_set_disassoc(sdata, false, true); 3435 ieee80211_set_disassoc(sdata, false, true);
2770 mutex_unlock(&ifmgd->mtx);
2771 assoc_bss = true; 3436 assoc_bss = true;
2772 } else { 3437 } else if (ifmgd->auth_data) {
2773 bool not_auth_yet = false; 3438 ieee80211_destroy_auth_data(sdata, false);
2774 struct ieee80211_work *tmp, *wk = NULL;
2775
2776 mutex_unlock(&ifmgd->mtx); 3439 mutex_unlock(&ifmgd->mtx);
2777 3440 return 0;
2778 mutex_lock(&local->mtx);
2779 list_for_each_entry(tmp, &local->work_list, list) {
2780 if (tmp->sdata != sdata)
2781 continue;
2782
2783 if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
2784 tmp->type != IEEE80211_WORK_AUTH &&
2785 tmp->type != IEEE80211_WORK_ASSOC &&
2786 tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
2787 continue;
2788
2789 if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
2790 continue;
2791
2792 not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
2793 list_del_rcu(&tmp->list);
2794 synchronize_rcu();
2795 wk = tmp;
2796 break;
2797 }
2798 mutex_unlock(&local->mtx);
2799
2800 if (wk && wk->type == IEEE80211_WORK_ASSOC) {
2801 /* clean up dummy sta & TX sync */
2802 sta_info_destroy_addr(wk->sdata, wk->filter_ta);
2803 if (wk->assoc.synced)
2804 drv_finish_tx_sync(local, wk->sdata,
2805 wk->filter_ta,
2806 IEEE80211_TX_SYNC_ASSOC);
2807 } else if (wk && wk->type == IEEE80211_WORK_AUTH) {
2808 if (wk->probe_auth.synced)
2809 drv_finish_tx_sync(local, wk->sdata,
2810 wk->filter_ta,
2811 IEEE80211_TX_SYNC_AUTH);
2812 }
2813 kfree(wk);
2814
2815 /*
2816 * If somebody requests authentication and we haven't
2817 * sent out an auth frame yet there's no need to send
2818 * out a deauth frame either. If the state was PROBE,
2819 * then this is the case. If it's AUTH we have sent a
2820 * frame, and if it's IDLE we have completed the auth
2821 * process already.
2822 */
2823 if (not_auth_yet) {
2824 __cfg80211_auth_canceled(sdata->dev, bssid);
2825 return 0;
2826 }
2827 } 3441 }
3442 mutex_unlock(&ifmgd->mtx);
2828 3443
2829 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 3444 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2830 sdata->name, bssid, req->reason_code); 3445 sdata->name, req->bssid, req->reason_code);
2831 3446
2832 ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH, 3447 ieee80211_send_deauth_disassoc(sdata, req->bssid, IEEE80211_STYPE_DEAUTH,
2833 req->reason_code, cookie, 3448 req->reason_code, cookie, true);
2834 !req->local_state_change);
2835 if (assoc_bss) 3449 if (assoc_bss)
2836 sta_info_flush(sdata->local, sdata); 3450 sta_info_flush(sdata->local, sdata);
2837 3451