aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 21:07:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 21:07:07 -0500
commit6be35c700f742e911ecedd07fcc43d4439922334 (patch)
treeca9f37214d204465fcc2d79c82efd291e357c53c /net/mac80211/mlme.c
parente37aa63e87bd581f9be5555ed0ba83f5295c92fc (diff)
parent520dfe3a3645257bf83660f672c47f8558f3d4c4 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller: 1) Allow to dump, monitor, and change the bridge multicast database using netlink. From Cong Wang. 2) RFC 5961 TCP blind data injection attack mitigation, from Eric Dumazet. 3) Networking user namespace support from Eric W. Biederman. 4) tuntap/virtio-net multiqueue support by Jason Wang. 5) Support for checksum offload of encapsulated packets (basically, tunneled traffic can still be checksummed by HW). From Joseph Gasparakis. 6) Allow BPF filter access to VLAN tags, from Eric Dumazet and Daniel Borkmann. 7) Bridge port parameters over netlink and BPDU blocking support from Stephen Hemminger. 8) Improve data access patterns during inet socket demux by rearranging socket layout, from Eric Dumazet. 9) TIPC protocol updates and cleanups from Ying Xue, Paul Gortmaker, and Jon Maloy. 10) Update TCP socket hash sizing to be more in line with current day realities. The existing heurstics were choosen a decade ago. From Eric Dumazet. 11) Fix races, queue bloat, and excessive wakeups in ATM and associated drivers, from Krzysztof Mazur and David Woodhouse. 12) Support DOVE (Distributed Overlay Virtual Ethernet) extensions in VXLAN driver, from David Stevens. 13) Add "oops_only" mode to netconsole, from Amerigo Wang. 14) Support set and query of VEB/VEPA bridge mode via PF_BRIDGE, also allow DCB netlink to work on namespaces other than the initial namespace. From John Fastabend. 15) Support PTP in the Tigon3 driver, from Matt Carlson. 16) tun/vhost zero copy fixes and improvements, plus turn it on by default, from Michael S. Tsirkin. 17) Support per-association statistics in SCTP, from Michele Baldessari. And many, many, driver updates, cleanups, and improvements. Too numerous to mention individually. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1722 commits) net/mlx4_en: Add support for destination MAC in steering rules net/mlx4_en: Use generic etherdevice.h functions. net: ethtool: Add destination MAC address to flow steering API bridge: add support of adding and deleting mdb entries bridge: notify mdb changes via netlink ndisc: Unexport ndisc_{build,send}_skb(). uapi: add missing netconf.h to export list pkt_sched: avoid requeues if possible solos-pci: fix double-free of TX skb in DMA mode bnx2: Fix accidental reversions. bna: Driver Version Updated to 3.1.2.1 bna: Firmware update bna: Add RX State bna: Rx Page Based Allocation bna: TX Intr Coalescing Fix bna: Tx and Rx Optimizations bna: Code Cleanup and Enhancements ath9k: check pdata variable before dereferencing it ath5k: RX timestamp is reported at end of frame ath9k_htc: RX timestamp is reported at end of frame ...
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c735
1 files changed, 565 insertions, 170 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1b7eed252fe9..7753a9ca98a6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -178,20 +178,32 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
178{ 178{
179 struct ieee80211_local *local = sdata->local; 179 struct ieee80211_local *local = sdata->local;
180 struct ieee80211_supported_band *sband; 180 struct ieee80211_supported_band *sband;
181 struct ieee80211_chanctx_conf *chanctx_conf;
182 struct ieee80211_channel *chan;
181 struct sta_info *sta; 183 struct sta_info *sta;
182 u32 changed = 0; 184 u32 changed = 0;
183 u16 ht_opmode; 185 u16 ht_opmode;
184 bool disable_40 = false; 186 bool disable_40 = false;
185 187
186 sband = local->hw.wiphy->bands[local->oper_channel->band]; 188 rcu_read_lock();
189 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
190 if (WARN_ON(!chanctx_conf)) {
191 rcu_read_unlock();
192 return 0;
193 }
194 chan = chanctx_conf->def.chan;
195 rcu_read_unlock();
196 sband = local->hw.wiphy->bands[chan->band];
187 197
188 switch (sdata->vif.bss_conf.channel_type) { 198 switch (sdata->vif.bss_conf.chandef.width) {
189 case NL80211_CHAN_HT40PLUS: 199 case NL80211_CHAN_WIDTH_40:
190 if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40PLUS) 200 if (sdata->vif.bss_conf.chandef.chan->center_freq >
201 sdata->vif.bss_conf.chandef.center_freq1 &&
202 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
191 disable_40 = true; 203 disable_40 = true;
192 break; 204 if (sdata->vif.bss_conf.chandef.chan->center_freq <
193 case NL80211_CHAN_HT40MINUS: 205 sdata->vif.bss_conf.chandef.center_freq1 &&
194 if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40MINUS) 206 chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
195 disable_40 = true; 207 disable_40 = true;
196 break; 208 break;
197 default: 209 default:
@@ -342,8 +354,18 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
342 /* determine capability flags */ 354 /* determine capability flags */
343 cap = vht_cap.cap; 355 cap = vht_cap.cap;
344 356
357 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) {
358 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
359 cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
360 }
361
362 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) {
363 cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
364 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
365 }
366
345 /* reserve and fill IE */ 367 /* reserve and fill IE */
346 pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2); 368 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
347 ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); 369 ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
348} 370}
349 371
@@ -359,11 +381,21 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
359 int i, count, rates_len, supp_rates_len; 381 int i, count, rates_len, supp_rates_len;
360 u16 capab; 382 u16 capab;
361 struct ieee80211_supported_band *sband; 383 struct ieee80211_supported_band *sband;
384 struct ieee80211_chanctx_conf *chanctx_conf;
385 struct ieee80211_channel *chan;
362 u32 rates = 0; 386 u32 rates = 0;
363 387
364 lockdep_assert_held(&ifmgd->mtx); 388 lockdep_assert_held(&ifmgd->mtx);
365 389
366 sband = local->hw.wiphy->bands[local->oper_channel->band]; 390 rcu_read_lock();
391 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
392 if (WARN_ON(!chanctx_conf)) {
393 rcu_read_unlock();
394 return;
395 }
396 chan = chanctx_conf->def.chan;
397 rcu_read_unlock();
398 sband = local->hw.wiphy->bands[chan->band];
367 399
368 if (assoc_data->supp_rates_len) { 400 if (assoc_data->supp_rates_len) {
369 /* 401 /*
@@ -392,7 +424,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
392 4 + /* power capability */ 424 4 + /* power capability */
393 2 + 2 * sband->n_channels + /* supported channels */ 425 2 + 2 * sband->n_channels + /* supported channels */
394 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ 426 2 + sizeof(struct ieee80211_ht_cap) + /* HT */
395 2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */ 427 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
396 assoc_data->ie_len + /* extra IEs */ 428 assoc_data->ie_len + /* extra IEs */
397 9, /* WMM */ 429 9, /* WMM */
398 GFP_KERNEL); 430 GFP_KERNEL);
@@ -485,7 +517,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
485 *pos++ = WLAN_EID_PWR_CAPABILITY; 517 *pos++ = WLAN_EID_PWR_CAPABILITY;
486 *pos++ = 2; 518 *pos++ = 2;
487 *pos++ = 0; /* min tx power */ 519 *pos++ = 0; /* min tx power */
488 *pos++ = local->oper_channel->max_power; /* max tx power */ 520 *pos++ = chan->max_power; /* max tx power */
489 521
490 /* 2. supported channels */ 522 /* 2. supported channels */
491 /* TODO: get this in reg domain format */ 523 /* TODO: get this in reg domain format */
@@ -521,9 +553,13 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
521 offset = noffset; 553 offset = noffset;
522 } 554 }
523 555
524 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 556 if (WARN_ON_ONCE((ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
557 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)))
558 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
559
560 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
525 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 561 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
526 sband, local->oper_channel, ifmgd->ap_smps); 562 sband, chan, sdata->smps_mode);
527 563
528 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) 564 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
529 ieee80211_add_vht_ie(sdata, skb, sband); 565 ieee80211_add_vht_ie(sdata, skb, sband);
@@ -657,18 +693,18 @@ static void ieee80211_chswitch_work(struct work_struct *work)
657 if (!ifmgd->associated) 693 if (!ifmgd->associated)
658 goto out; 694 goto out;
659 695
660 sdata->local->oper_channel = sdata->local->csa_channel; 696 sdata->local->_oper_channel = sdata->local->csa_channel;
661 if (!sdata->local->ops->channel_switch) { 697 if (!sdata->local->ops->channel_switch) {
662 /* call "hw_config" only if doing sw channel switch */ 698 /* call "hw_config" only if doing sw channel switch */
663 ieee80211_hw_config(sdata->local, 699 ieee80211_hw_config(sdata->local,
664 IEEE80211_CONF_CHANGE_CHANNEL); 700 IEEE80211_CONF_CHANGE_CHANNEL);
665 } else { 701 } else {
666 /* update the device channel directly */ 702 /* update the device channel directly */
667 sdata->local->hw.conf.channel = sdata->local->oper_channel; 703 sdata->local->hw.conf.channel = sdata->local->_oper_channel;
668 } 704 }
669 705
670 /* XXX: shouldn't really modify cfg80211-owned data! */ 706 /* XXX: shouldn't really modify cfg80211-owned data! */
671 ifmgd->associated->channel = sdata->local->oper_channel; 707 ifmgd->associated->channel = sdata->local->_oper_channel;
672 708
673 /* XXX: wait for a beacon first? */ 709 /* XXX: wait for a beacon first? */
674 ieee80211_wake_queues_by_reason(&sdata->local->hw, 710 ieee80211_wake_queues_by_reason(&sdata->local->hw,
@@ -680,11 +716,8 @@ static void ieee80211_chswitch_work(struct work_struct *work)
680 716
681void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) 717void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
682{ 718{
683 struct ieee80211_sub_if_data *sdata; 719 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
684 struct ieee80211_if_managed *ifmgd; 720 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
685
686 sdata = vif_to_sdata(vif);
687 ifmgd = &sdata->u.mgd;
688 721
689 trace_api_chswitch_done(sdata, success); 722 trace_api_chswitch_done(sdata, success);
690 if (!success) { 723 if (!success) {
@@ -723,6 +756,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
723 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 756 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
724 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num, 757 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
725 cbss->channel->band); 758 cbss->channel->band);
759 struct ieee80211_chanctx *chanctx;
726 760
727 ASSERT_MGD_MTX(ifmgd); 761 ASSERT_MGD_MTX(ifmgd);
728 762
@@ -748,10 +782,35 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
748 return; 782 return;
749 } 783 }
750 784
751 sdata->local->csa_channel = new_ch;
752
753 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; 785 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
754 786
787 if (sdata->local->use_chanctx) {
788 sdata_info(sdata,
789 "not handling channel switch with channel contexts\n");
790 ieee80211_queue_work(&sdata->local->hw,
791 &ifmgd->csa_connection_drop_work);
792 return;
793 }
794
795 mutex_lock(&sdata->local->chanctx_mtx);
796 if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) {
797 mutex_unlock(&sdata->local->chanctx_mtx);
798 return;
799 }
800 chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf),
801 struct ieee80211_chanctx, conf);
802 if (chanctx->refcount > 1) {
803 sdata_info(sdata,
804 "channel switch with multiple interfaces on the same channel, disconnecting\n");
805 ieee80211_queue_work(&sdata->local->hw,
806 &ifmgd->csa_connection_drop_work);
807 mutex_unlock(&sdata->local->chanctx_mtx);
808 return;
809 }
810 mutex_unlock(&sdata->local->chanctx_mtx);
811
812 sdata->local->csa_channel = new_ch;
813
755 if (sw_elem->mode) 814 if (sw_elem->mode)
756 ieee80211_stop_queues_by_reason(&sdata->local->hw, 815 ieee80211_stop_queues_by_reason(&sdata->local->hw,
757 IEEE80211_QUEUE_STOP_REASON_CSA); 816 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -778,10 +837,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
778 cbss->beacon_interval)); 837 cbss->beacon_interval));
779} 838}
780 839
781static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, 840static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
782 struct ieee80211_channel *channel, 841 struct ieee80211_channel *channel,
783 const u8 *country_ie, u8 country_ie_len, 842 const u8 *country_ie, u8 country_ie_len,
784 const u8 *pwr_constr_elem) 843 const u8 *pwr_constr_elem)
785{ 844{
786 struct ieee80211_country_ie_triplet *triplet; 845 struct ieee80211_country_ie_triplet *triplet;
787 int chan = ieee80211_frequency_to_channel(channel->center_freq); 846 int chan = ieee80211_frequency_to_channel(channel->center_freq);
@@ -790,7 +849,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
790 849
791 /* Invalid IE */ 850 /* Invalid IE */
792 if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 851 if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
793 return; 852 return 0;
794 853
795 triplet = (void *)(country_ie + 3); 854 triplet = (void *)(country_ie + 3);
796 country_ie_len -= 3; 855 country_ie_len -= 3;
@@ -831,19 +890,21 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
831 } 890 }
832 891
833 if (!have_chan_pwr) 892 if (!have_chan_pwr)
834 return; 893 return 0;
835 894
836 new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem); 895 new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem);
837 896
838 if (sdata->local->ap_power_level == new_ap_level) 897 if (sdata->ap_power_level == new_ap_level)
839 return; 898 return 0;
840 899
841 sdata_info(sdata, 900 sdata_info(sdata,
842 "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", 901 "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
843 new_ap_level, chan_pwr, *pwr_constr_elem, 902 new_ap_level, chan_pwr, *pwr_constr_elem,
844 sdata->u.mgd.bssid); 903 sdata->u.mgd.bssid);
845 sdata->local->ap_power_level = new_ap_level; 904 sdata->ap_power_level = new_ap_level;
846 ieee80211_hw_config(sdata->local, 0); 905 if (__ieee80211_recalc_txpower(sdata))
906 return BSS_CHANGED_TXPOWER;
907 return 0;
847} 908}
848 909
849void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif) 910void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
@@ -1280,7 +1341,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
1280 } 1341 }
1281 1342
1282 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); 1343 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
1283 if (sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) 1344 if (ieee80211_get_sdata_band(sdata) == IEEE80211_BAND_5GHZ)
1284 use_short_slot = true; 1345 use_short_slot = true;
1285 1346
1286 if (use_protection != bss_conf->use_cts_prot) { 1347 if (use_protection != bss_conf->use_cts_prot) {
@@ -1321,6 +1382,29 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1321 1382
1322 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; 1383 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
1323 1384
1385 if (sdata->vif.p2p) {
1386 const struct cfg80211_bss_ies *ies;
1387
1388 rcu_read_lock();
1389 ies = rcu_dereference(cbss->ies);
1390 if (ies) {
1391 u8 noa[2];
1392 int ret;
1393
1394 ret = cfg80211_get_p2p_attr(
1395 ies->data, ies->len,
1396 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
1397 noa, sizeof(noa));
1398 if (ret >= 2) {
1399 bss_conf->p2p_oppps = noa[1] & 0x80;
1400 bss_conf->p2p_ctwindow = noa[1] & 0x7f;
1401 bss_info_changed |= BSS_CHANGED_P2P_PS;
1402 sdata->u.mgd.p2p_noa_index = noa[0];
1403 }
1404 }
1405 rcu_read_unlock();
1406 }
1407
1324 /* just to be sure */ 1408 /* just to be sure */
1325 ieee80211_stop_poll(sdata); 1409 ieee80211_stop_poll(sdata);
1326 1410
@@ -1350,7 +1434,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1350 ieee80211_recalc_ps(local, -1); 1434 ieee80211_recalc_ps(local, -1);
1351 mutex_unlock(&local->iflist_mtx); 1435 mutex_unlock(&local->iflist_mtx);
1352 1436
1353 ieee80211_recalc_smps(local); 1437 ieee80211_recalc_smps(sdata);
1354 ieee80211_recalc_ps_vif(sdata); 1438 ieee80211_recalc_ps_vif(sdata);
1355 1439
1356 netif_tx_start_all_queues(sdata->dev); 1440 netif_tx_start_all_queues(sdata->dev);
@@ -1443,11 +1527,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1443 changed |= BSS_CHANGED_ASSOC; 1527 changed |= BSS_CHANGED_ASSOC;
1444 sdata->vif.bss_conf.assoc = false; 1528 sdata->vif.bss_conf.assoc = false;
1445 1529
1530 sdata->vif.bss_conf.p2p_ctwindow = 0;
1531 sdata->vif.bss_conf.p2p_oppps = false;
1532
1446 /* on the next assoc, re-program HT parameters */ 1533 /* on the next assoc, re-program HT parameters */
1447 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); 1534 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
1448 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask)); 1535 memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
1449 1536
1450 local->ap_power_level = 0; 1537 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
1451 1538
1452 del_timer_sync(&local->dynamic_ps_timer); 1539 del_timer_sync(&local->dynamic_ps_timer);
1453 cancel_work_sync(&local->dynamic_ps_enable_work); 1540 cancel_work_sync(&local->dynamic_ps_enable_work);
@@ -1465,10 +1552,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1465 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; 1552 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
1466 ieee80211_bss_info_change_notify(sdata, changed); 1553 ieee80211_bss_info_change_notify(sdata, changed);
1467 1554
1468 /* channel(_type) changes are handled by ieee80211_hw_config */
1469 WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
1470 ieee80211_hw_config(local, 0);
1471
1472 /* disassociated - set to defaults now */ 1555 /* disassociated - set to defaults now */
1473 ieee80211_set_wmm_default(sdata, false); 1556 ieee80211_set_wmm_default(sdata, false);
1474 1557
@@ -1478,6 +1561,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1478 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1561 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1479 1562
1480 sdata->u.mgd.timers_running = 0; 1563 sdata->u.mgd.timers_running = 0;
1564
1565 ifmgd->flags = 0;
1566 ieee80211_vif_release_channel(sdata);
1481} 1567}
1482 1568
1483void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1569void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1581,6 +1667,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1581 } else { 1667 } else {
1582 int ssid_len; 1668 int ssid_len;
1583 1669
1670 rcu_read_lock();
1584 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1671 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1585 if (WARN_ON_ONCE(ssid == NULL)) 1672 if (WARN_ON_ONCE(ssid == NULL))
1586 ssid_len = 0; 1673 ssid_len = 0;
@@ -1589,7 +1676,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1589 1676
1590 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, 1677 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL,
1591 0, (u32) -1, true, false, 1678 0, (u32) -1, true, false,
1592 ifmgd->associated->channel); 1679 ifmgd->associated->channel, false);
1680 rcu_read_unlock();
1593 } 1681 }
1594 1682
1595 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 1683 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
@@ -1685,6 +1773,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1685 else 1773 else
1686 return NULL; 1774 return NULL;
1687 1775
1776 rcu_read_lock();
1688 ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID); 1777 ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID);
1689 if (WARN_ON_ONCE(ssid == NULL)) 1778 if (WARN_ON_ONCE(ssid == NULL))
1690 ssid_len = 0; 1779 ssid_len = 0;
@@ -1692,10 +1781,10 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1692 ssid_len = ssid[1]; 1781 ssid_len = ssid[1];
1693 1782
1694 skb = ieee80211_build_probe_req(sdata, cbss->bssid, 1783 skb = ieee80211_build_probe_req(sdata, cbss->bssid,
1695 (u32) -1, 1784 (u32) -1, cbss->channel,
1696 sdata->local->oper_channel,
1697 ssid + 2, ssid_len, 1785 ssid + 2, ssid_len,
1698 NULL, 0, true); 1786 NULL, 0, true);
1787 rcu_read_unlock();
1699 1788
1700 return skb; 1789 return skb;
1701} 1790}
@@ -1804,6 +1893,8 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1804 1893
1805 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 1894 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
1806 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 1895 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
1896 sdata->u.mgd.flags = 0;
1897 ieee80211_vif_release_channel(sdata);
1807 } 1898 }
1808 1899
1809 cfg80211_put_bss(auth_data->bss); 1900 cfg80211_put_bss(auth_data->bss);
@@ -1824,7 +1915,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1824 return; 1915 return;
1825 auth_data->expected_transaction = 4; 1916 auth_data->expected_transaction = 4;
1826 drv_mgd_prepare_tx(sdata->local, sdata); 1917 drv_mgd_prepare_tx(sdata->local, sdata);
1827 ieee80211_send_auth(sdata, 3, auth_data->algorithm, 1918 ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0,
1828 elems.challenge - 2, elems.challenge_len + 2, 1919 elems.challenge - 2, elems.challenge_len + 2,
1829 auth_data->bss->bssid, auth_data->bss->bssid, 1920 auth_data->bss->bssid, auth_data->bss->bssid,
1830 auth_data->key, auth_data->key_len, 1921 auth_data->key, auth_data->key_len,
@@ -1858,8 +1949,13 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1858 status_code = le16_to_cpu(mgmt->u.auth.status_code); 1949 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1859 1950
1860 if (auth_alg != ifmgd->auth_data->algorithm || 1951 if (auth_alg != ifmgd->auth_data->algorithm ||
1861 auth_transaction != ifmgd->auth_data->expected_transaction) 1952 auth_transaction != ifmgd->auth_data->expected_transaction) {
1953 sdata_info(sdata, "%pM unexpected authentication state: alg %d (expected %d) transact %d (expected %d)\n",
1954 mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
1955 auth_transaction,
1956 ifmgd->auth_data->expected_transaction);
1862 return RX_MGMT_NONE; 1957 return RX_MGMT_NONE;
1958 }
1863 1959
1864 if (status_code != WLAN_STATUS_SUCCESS) { 1960 if (status_code != WLAN_STATUS_SUCCESS) {
1865 sdata_info(sdata, "%pM denied authentication (status %d)\n", 1961 sdata_info(sdata, "%pM denied authentication (status %d)\n",
@@ -1872,6 +1968,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1872 case WLAN_AUTH_OPEN: 1968 case WLAN_AUTH_OPEN:
1873 case WLAN_AUTH_LEAP: 1969 case WLAN_AUTH_LEAP:
1874 case WLAN_AUTH_FT: 1970 case WLAN_AUTH_FT:
1971 case WLAN_AUTH_SAE:
1875 break; 1972 break;
1876 case WLAN_AUTH_SHARED_KEY: 1973 case WLAN_AUTH_SHARED_KEY:
1877 if (ifmgd->auth_data->expected_transaction != 4) { 1974 if (ifmgd->auth_data->expected_transaction != 4) {
@@ -1891,6 +1988,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1891 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; 1988 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
1892 run_again(ifmgd, ifmgd->auth_data->timeout); 1989 run_again(ifmgd, ifmgd->auth_data->timeout);
1893 1990
1991 if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
1992 ifmgd->auth_data->expected_transaction != 2) {
1993 /*
1994 * Report auth frame to user space for processing since another
1995 * round of Authentication frames is still needed.
1996 */
1997 return RX_MGMT_CFG80211_RX_AUTH;
1998 }
1999
1894 /* move station state to auth */ 2000 /* move station state to auth */
1895 mutex_lock(&sdata->local->sta_mtx); 2001 mutex_lock(&sdata->local->sta_mtx);
1896 sta = sta_info_get(sdata, bssid); 2002 sta = sta_info_get(sdata, bssid);
@@ -2030,6 +2136,8 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
2030 2136
2031 memset(sdata->u.mgd.bssid, 0, ETH_ALEN); 2137 memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
2032 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 2138 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2139 sdata->u.mgd.flags = 0;
2140 ieee80211_vif_release_channel(sdata);
2033 } 2141 }
2034 2142
2035 kfree(assoc_data); 2143 kfree(assoc_data);
@@ -2091,15 +2199,20 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2091 return false; 2199 return false;
2092 } 2200 }
2093 2201
2094 sband = local->hw.wiphy->bands[local->oper_channel->band]; 2202 sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
2095 2203
2096 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2204 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2097 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 2205 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
2098 elems.ht_cap_elem, &sta->sta.ht_cap); 2206 elems.ht_cap_elem, &sta->sta.ht_cap);
2099 2207
2100 sta->supports_40mhz = 2208 sta->supports_40mhz =
2101 sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; 2209 sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
2102 2210
2211 if (elems.vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
2212 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
2213 elems.vht_cap_elem,
2214 &sta->sta.vht_cap);
2215
2103 rate_control_rate_init(sta); 2216 rate_control_rate_init(sta);
2104 2217
2105 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) 2218 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
@@ -2140,7 +2253,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2140 changed |= BSS_CHANGED_QOS; 2253 changed |= BSS_CHANGED_QOS;
2141 2254
2142 if (elems.ht_operation && elems.wmm_param && 2255 if (elems.ht_operation && elems.wmm_param &&
2143 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2256 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2144 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2257 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2145 cbss->bssid, false); 2258 cbss->bssid, false);
2146 2259
@@ -2247,9 +2360,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2247 2360
2248 return RX_MGMT_CFG80211_RX_ASSOC; 2361 return RX_MGMT_CFG80211_RX_ASSOC;
2249} 2362}
2363
2250static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2364static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2251 struct ieee80211_mgmt *mgmt, 2365 struct ieee80211_mgmt *mgmt, size_t len,
2252 size_t len,
2253 struct ieee80211_rx_status *rx_status, 2366 struct ieee80211_rx_status *rx_status,
2254 struct ieee802_11_elems *elems, 2367 struct ieee802_11_elems *elems,
2255 bool beacon) 2368 bool beacon)
@@ -2369,8 +2482,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2369 size_t baselen; 2482 size_t baselen;
2370 struct ieee802_11_elems elems; 2483 struct ieee802_11_elems elems;
2371 struct ieee80211_local *local = sdata->local; 2484 struct ieee80211_local *local = sdata->local;
2485 struct ieee80211_chanctx_conf *chanctx_conf;
2486 struct ieee80211_channel *chan;
2372 u32 changed = 0; 2487 u32 changed = 0;
2373 bool erp_valid, directed_tim = false; 2488 bool erp_valid;
2374 u8 erp_value = 0; 2489 u8 erp_value = 0;
2375 u32 ncrc; 2490 u32 ncrc;
2376 u8 *bssid; 2491 u8 *bssid;
@@ -2382,8 +2497,19 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2382 if (baselen > len) 2497 if (baselen > len)
2383 return; 2498 return;
2384 2499
2385 if (rx_status->freq != local->oper_channel->center_freq) 2500 rcu_read_lock();
2501 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2502 if (!chanctx_conf) {
2503 rcu_read_unlock();
2504 return;
2505 }
2506
2507 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
2508 rcu_read_unlock();
2386 return; 2509 return;
2510 }
2511 chan = chanctx_conf->def.chan;
2512 rcu_read_unlock();
2387 2513
2388 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && 2514 if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
2389 ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { 2515 ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
@@ -2490,11 +2616,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2490 len - baselen, &elems, 2616 len - baselen, &elems,
2491 care_about_ies, ncrc); 2617 care_about_ies, ncrc);
2492 2618
2493 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
2494 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
2495 ifmgd->aid);
2496
2497 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { 2619 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
2620 bool directed_tim = ieee80211_check_tim(elems.tim,
2621 elems.tim_len,
2622 ifmgd->aid);
2498 if (directed_tim) { 2623 if (directed_tim) {
2499 if (local->hw.conf.dynamic_ps_timeout > 0) { 2624 if (local->hw.conf.dynamic_ps_timeout > 0) {
2500 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 2625 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
@@ -2519,6 +2644,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2519 } 2644 }
2520 } 2645 }
2521 2646
2647 if (sdata->vif.p2p) {
2648 u8 noa[2];
2649 int ret;
2650
2651 ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
2652 len - baselen,
2653 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
2654 noa, sizeof(noa));
2655 if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) {
2656 bss_conf->p2p_oppps = noa[1] & 0x80;
2657 bss_conf->p2p_ctwindow = noa[1] & 0x7f;
2658 changed |= BSS_CHANGED_P2P_PS;
2659 sdata->u.mgd.p2p_noa_index = noa[0];
2660 /*
2661 * make sure we update all information, the CRC
2662 * mechanism doesn't look at P2P attributes.
2663 */
2664 ifmgd->beacon_crc_valid = false;
2665 }
2666 }
2667
2522 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 2668 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
2523 return; 2669 return;
2524 ifmgd->beacon_crc = ncrc; 2670 ifmgd->beacon_crc = ncrc;
@@ -2543,22 +2689,17 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2543 2689
2544 2690
2545 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && 2691 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
2546 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) { 2692 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2547 struct ieee80211_supported_band *sband;
2548
2549 sband = local->hw.wiphy->bands[local->oper_channel->band];
2550
2551 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2693 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2552 bssid, true); 2694 bssid, true);
2553 }
2554 2695
2555 if (elems.country_elem && elems.pwr_constr_elem && 2696 if (elems.country_elem && elems.pwr_constr_elem &&
2556 mgmt->u.probe_resp.capab_info & 2697 mgmt->u.probe_resp.capab_info &
2557 cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) 2698 cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT))
2558 ieee80211_handle_pwr_constr(sdata, local->oper_channel, 2699 changed |= ieee80211_handle_pwr_constr(sdata, chan,
2559 elems.country_elem, 2700 elems.country_elem,
2560 elems.country_elem_len, 2701 elems.country_elem_len,
2561 elems.pwr_constr_elem); 2702 elems.pwr_constr_elem);
2562 2703
2563 ieee80211_bss_info_change_notify(sdata, changed); 2704 ieee80211_bss_info_change_notify(sdata, changed);
2564} 2705}
@@ -2703,13 +2844,23 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2703 drv_mgd_prepare_tx(local, sdata); 2844 drv_mgd_prepare_tx(local, sdata);
2704 2845
2705 if (auth_data->bss->proberesp_ies) { 2846 if (auth_data->bss->proberesp_ies) {
2847 u16 trans = 1;
2848 u16 status = 0;
2849
2706 sdata_info(sdata, "send auth to %pM (try %d/%d)\n", 2850 sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
2707 auth_data->bss->bssid, auth_data->tries, 2851 auth_data->bss->bssid, auth_data->tries,
2708 IEEE80211_AUTH_MAX_TRIES); 2852 IEEE80211_AUTH_MAX_TRIES);
2709 2853
2710 auth_data->expected_transaction = 2; 2854 auth_data->expected_transaction = 2;
2711 ieee80211_send_auth(sdata, 1, auth_data->algorithm, 2855
2712 auth_data->ie, auth_data->ie_len, 2856 if (auth_data->algorithm == WLAN_AUTH_SAE) {
2857 trans = auth_data->sae_trans;
2858 status = auth_data->sae_status;
2859 auth_data->expected_transaction = trans;
2860 }
2861
2862 ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
2863 auth_data->data, auth_data->data_len,
2713 auth_data->bss->bssid, 2864 auth_data->bss->bssid,
2714 auth_data->bss->bssid, NULL, 0, 0); 2865 auth_data->bss->bssid, NULL, 0, 0);
2715 } else { 2866 } else {
@@ -2719,16 +2870,20 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2719 auth_data->bss->bssid, auth_data->tries, 2870 auth_data->bss->bssid, auth_data->tries,
2720 IEEE80211_AUTH_MAX_TRIES); 2871 IEEE80211_AUTH_MAX_TRIES);
2721 2872
2873 rcu_read_lock();
2722 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); 2874 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
2723 if (!ssidie) 2875 if (!ssidie) {
2876 rcu_read_unlock();
2724 return -EINVAL; 2877 return -EINVAL;
2878 }
2725 /* 2879 /*
2726 * Direct probe is sent to broadcast address as some APs 2880 * Direct probe is sent to broadcast address as some APs
2727 * will not answer to direct packet in unassociated state. 2881 * will not answer to direct packet in unassociated state.
2728 */ 2882 */
2729 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], 2883 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
2730 NULL, 0, (u32) -1, true, false, 2884 NULL, 0, (u32) -1, true, false,
2731 auth_data->bss->channel); 2885 auth_data->bss->channel, false);
2886 rcu_read_unlock();
2732 } 2887 }
2733 2888
2734 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 2889 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
@@ -3058,90 +3213,313 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
3058 return 0; 3213 return 0;
3059} 3214}
3060 3215
3216static u32 chandef_downgrade(struct cfg80211_chan_def *c)
3217{
3218 u32 ret;
3219 int tmp;
3220
3221 switch (c->width) {
3222 case NL80211_CHAN_WIDTH_20:
3223 c->width = NL80211_CHAN_WIDTH_20_NOHT;
3224 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3225 break;
3226 case NL80211_CHAN_WIDTH_40:
3227 c->width = NL80211_CHAN_WIDTH_20;
3228 c->center_freq1 = c->chan->center_freq;
3229 ret = IEEE80211_STA_DISABLE_40MHZ |
3230 IEEE80211_STA_DISABLE_VHT;
3231 break;
3232 case NL80211_CHAN_WIDTH_80:
3233 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
3234 /* n_P40 */
3235 tmp /= 2;
3236 /* freq_P40 */
3237 c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
3238 c->width = NL80211_CHAN_WIDTH_40;
3239 ret = IEEE80211_STA_DISABLE_VHT;
3240 break;
3241 case NL80211_CHAN_WIDTH_80P80:
3242 c->center_freq2 = 0;
3243 c->width = NL80211_CHAN_WIDTH_80;
3244 ret = IEEE80211_STA_DISABLE_80P80MHZ |
3245 IEEE80211_STA_DISABLE_160MHZ;
3246 break;
3247 case NL80211_CHAN_WIDTH_160:
3248 /* n_P20 */
3249 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
3250 /* n_P80 */
3251 tmp /= 4;
3252 c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
3253 c->width = NL80211_CHAN_WIDTH_80;
3254 ret = IEEE80211_STA_DISABLE_80P80MHZ |
3255 IEEE80211_STA_DISABLE_160MHZ;
3256 break;
3257 default:
3258 case NL80211_CHAN_WIDTH_20_NOHT:
3259 WARN_ON_ONCE(1);
3260 c->width = NL80211_CHAN_WIDTH_20_NOHT;
3261 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3262 break;
3263 }
3264
3265 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
3266
3267 return ret;
3268}
3269
3270static u32
3271ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
3272 struct ieee80211_supported_band *sband,
3273 struct ieee80211_channel *channel,
3274 const struct ieee80211_ht_operation *ht_oper,
3275 const struct ieee80211_vht_operation *vht_oper,
3276 struct cfg80211_chan_def *chandef)
3277{
3278 struct cfg80211_chan_def vht_chandef;
3279 u32 ht_cfreq, ret;
3280
3281 chandef->chan = channel;
3282 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
3283 chandef->center_freq1 = channel->center_freq;
3284 chandef->center_freq2 = 0;
3285
3286 if (!ht_oper || !sband->ht_cap.ht_supported) {
3287 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3288 goto out;
3289 }
3290
3291 chandef->width = NL80211_CHAN_WIDTH_20;
3292
3293 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
3294 channel->band);
3295 /* check that channel matches the right operating channel */
3296 if (channel->center_freq != ht_cfreq) {
3297 /*
3298 * It's possible that some APs are confused here;
3299 * Netgear WNDR3700 sometimes reports 4 higher than
3300 * the actual channel in association responses, but
3301 * since we look at probe response/beacon data here
3302 * it should be OK.
3303 */
3304 sdata_info(sdata,
3305 "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
3306 channel->center_freq, ht_cfreq,
3307 ht_oper->primary_chan, channel->band);
3308 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3309 goto out;
3310 }
3311
3312 /* check 40 MHz support, if we have it */
3313 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
3314 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3315 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3316 chandef->width = NL80211_CHAN_WIDTH_40;
3317 chandef->center_freq1 += 10;
3318 break;
3319 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3320 chandef->width = NL80211_CHAN_WIDTH_40;
3321 chandef->center_freq1 -= 10;
3322 break;
3323 }
3324 } else {
3325 /* 40 MHz (and 80 MHz) must be supported for VHT */
3326 ret = IEEE80211_STA_DISABLE_VHT;
3327 goto out;
3328 }
3329
3330 if (!vht_oper || !sband->vht_cap.vht_supported) {
3331 ret = IEEE80211_STA_DISABLE_VHT;
3332 goto out;
3333 }
3334
3335 vht_chandef.chan = channel;
3336 vht_chandef.center_freq1 =
3337 ieee80211_channel_to_frequency(vht_oper->center_freq_seg1_idx,
3338 channel->band);
3339 vht_chandef.center_freq2 = 0;
3340
3341 if (vht_oper->center_freq_seg2_idx)
3342 vht_chandef.center_freq2 =
3343 ieee80211_channel_to_frequency(
3344 vht_oper->center_freq_seg2_idx,
3345 channel->band);
3346
3347 switch (vht_oper->chan_width) {
3348 case IEEE80211_VHT_CHANWIDTH_USE_HT:
3349 vht_chandef.width = chandef->width;
3350 break;
3351 case IEEE80211_VHT_CHANWIDTH_80MHZ:
3352 vht_chandef.width = NL80211_CHAN_WIDTH_80;
3353 break;
3354 case IEEE80211_VHT_CHANWIDTH_160MHZ:
3355 vht_chandef.width = NL80211_CHAN_WIDTH_160;
3356 break;
3357 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
3358 vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
3359 break;
3360 default:
3361 sdata_info(sdata,
3362 "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
3363 vht_oper->chan_width);
3364 ret = IEEE80211_STA_DISABLE_VHT;
3365 goto out;
3366 }
3367
3368 if (!cfg80211_chandef_valid(&vht_chandef)) {
3369 sdata_info(sdata,
3370 "AP VHT information is invalid, disable VHT\n");
3371 ret = IEEE80211_STA_DISABLE_VHT;
3372 goto out;
3373 }
3374
3375 if (cfg80211_chandef_identical(chandef, &vht_chandef)) {
3376 ret = 0;
3377 goto out;
3378 }
3379
3380 if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
3381 sdata_info(sdata,
3382 "AP VHT information doesn't match HT, disable VHT\n");
3383 ret = IEEE80211_STA_DISABLE_VHT;
3384 goto out;
3385 }
3386
3387 *chandef = vht_chandef;
3388
3389 ret = 0;
3390
3391 while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
3392 IEEE80211_CHAN_DISABLED)) {
3393 if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
3394 ret = IEEE80211_STA_DISABLE_HT |
3395 IEEE80211_STA_DISABLE_VHT;
3396 goto out;
3397 }
3398
3399 ret = chandef_downgrade(chandef);
3400 }
3401
3402 if (chandef->width != vht_chandef.width)
3403 sdata_info(sdata,
3404 "local regulatory prevented using AP HT/VHT configuration, downgraded\n");
3405
3406out:
3407 WARN_ON_ONCE(!cfg80211_chandef_valid(chandef));
3408 return ret;
3409}
3410
3411static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata,
3412 struct cfg80211_bss *cbss)
3413{
3414 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3415 const u8 *ht_cap_ie, *vht_cap_ie;
3416 const struct ieee80211_ht_cap *ht_cap;
3417 const struct ieee80211_vht_cap *vht_cap;
3418 u8 chains = 1;
3419
3420 if (ifmgd->flags & IEEE80211_STA_DISABLE_HT)
3421 return chains;
3422
3423 ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
3424 if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) {
3425 ht_cap = (void *)(ht_cap_ie + 2);
3426 chains = ieee80211_mcs_to_chains(&ht_cap->mcs);
3427 /*
3428 * TODO: use "Tx Maximum Number Spatial Streams Supported" and
3429 * "Tx Unequal Modulation Supported" fields.
3430 */
3431 }
3432
3433 if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
3434 return chains;
3435
3436 vht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_VHT_CAPABILITY);
3437 if (vht_cap_ie && vht_cap_ie[1] >= sizeof(*vht_cap)) {
3438 u8 nss;
3439 u16 tx_mcs_map;
3440
3441 vht_cap = (void *)(vht_cap_ie + 2);
3442 tx_mcs_map = le16_to_cpu(vht_cap->supp_mcs.tx_mcs_map);
3443 for (nss = 8; nss > 0; nss--) {
3444 if (((tx_mcs_map >> (2 * (nss - 1))) & 3) !=
3445 IEEE80211_VHT_MCS_NOT_SUPPORTED)
3446 break;
3447 }
3448 /* TODO: use "Tx Highest Supported Long GI Data Rate" field? */
3449 chains = max(chains, nss);
3450 }
3451
3452 return chains;
3453}
3454
3061static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, 3455static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3062 struct cfg80211_bss *cbss) 3456 struct cfg80211_bss *cbss)
3063{ 3457{
3064 struct ieee80211_local *local = sdata->local; 3458 struct ieee80211_local *local = sdata->local;
3065 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3459 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3066 int ht_cfreq;
3067 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
3068 const u8 *ht_oper_ie;
3069 const struct ieee80211_ht_operation *ht_oper = NULL; 3460 const struct ieee80211_ht_operation *ht_oper = NULL;
3461 const struct ieee80211_vht_operation *vht_oper = NULL;
3070 struct ieee80211_supported_band *sband; 3462 struct ieee80211_supported_band *sband;
3463 struct cfg80211_chan_def chandef;
3464 int ret;
3071 3465
3072 sband = local->hw.wiphy->bands[cbss->channel->band]; 3466 sband = local->hw.wiphy->bands[cbss->channel->band];
3073 3467
3074 ifmgd->flags &= ~IEEE80211_STA_DISABLE_40MHZ; 3468 ifmgd->flags &= ~(IEEE80211_STA_DISABLE_40MHZ |
3469 IEEE80211_STA_DISABLE_80P80MHZ |
3470 IEEE80211_STA_DISABLE_160MHZ);
3471
3472 rcu_read_lock();
3473
3474 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3475 sband->ht_cap.ht_supported) {
3476 const u8 *ht_oper_ie;
3075 3477
3076 if (sband->ht_cap.ht_supported) { 3478 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
3077 ht_oper_ie = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
3078 cbss->information_elements,
3079 cbss->len_information_elements);
3080 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) 3479 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
3081 ht_oper = (void *)(ht_oper_ie + 2); 3480 ht_oper = (void *)(ht_oper_ie + 2);
3082 } 3481 }
3083 3482
3084 if (ht_oper) { 3483 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3085 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, 3484 sband->vht_cap.vht_supported) {
3086 cbss->channel->band); 3485 const u8 *vht_oper_ie;
3087 /* check that channel matches the right operating channel */ 3486
3088 if (cbss->channel->center_freq != ht_cfreq) { 3487 vht_oper_ie = ieee80211_bss_get_ie(cbss,
3089 /* 3488 WLAN_EID_VHT_OPERATION);
3090 * It's possible that some APs are confused here; 3489 if (vht_oper_ie && vht_oper_ie[1] >= sizeof(*vht_oper))
3091 * Netgear WNDR3700 sometimes reports 4 higher than 3490 vht_oper = (void *)(vht_oper_ie + 2);
3092 * the actual channel in association responses, but 3491 if (vht_oper && !ht_oper) {
3093 * since we look at probe response/beacon data here 3492 vht_oper = NULL;
3094 * it should be OK.
3095 */
3096 sdata_info(sdata, 3493 sdata_info(sdata,
3097 "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", 3494 "AP advertised VHT without HT, disabling both\n");
3098 cbss->channel->center_freq, 3495 sdata->flags |= IEEE80211_STA_DISABLE_HT;
3099 ht_cfreq, ht_oper->primary_chan, 3496 sdata->flags |= IEEE80211_STA_DISABLE_VHT;
3100 cbss->channel->band);
3101 ht_oper = NULL;
3102 } else {
3103 channel_type = NL80211_CHAN_HT20;
3104 } 3497 }
3105 } 3498 }
3106 3499
3107 if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { 3500 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
3108 /* 3501 cbss->channel,
3109 * cfg80211 already verified that the channel itself can 3502 ht_oper, vht_oper,
3110 * be used, but it didn't check that we can do the right 3503 &chandef);
3111 * HT type, so do that here as well. If HT40 isn't allowed
3112 * on this channel, disable 40 MHz operation.
3113 */
3114 3504
3115 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 3505 sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
3116 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 3506 local->rx_chains);
3117 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
3118 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
3119 else
3120 channel_type = NL80211_CHAN_HT40PLUS;
3121 break;
3122 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3123 if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
3124 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
3125 else
3126 channel_type = NL80211_CHAN_HT40MINUS;
3127 break;
3128 }
3129 }
3130 3507
3131 if (!ieee80211_set_channel_type(local, sdata, channel_type)) { 3508 rcu_read_unlock();
3132 /* can only fail due to HT40+/- mismatch */
3133 channel_type = NL80211_CHAN_HT20;
3134 sdata_info(sdata,
3135 "disabling 40 MHz due to multi-vif mismatch\n");
3136 ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
3137 WARN_ON(!ieee80211_set_channel_type(local, sdata,
3138 channel_type));
3139 }
3140 3509
3141 local->oper_channel = cbss->channel; 3510 /* will change later if needed */
3142 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 3511 sdata->smps_mode = IEEE80211_SMPS_OFF;
3143 3512
3144 return 0; 3513 /*
3514 * If this fails (possibly due to channel context sharing
3515 * on incompatible channels, e.g. 80+80 and 160 sharing the
3516 * same control channel) try to use a smaller bandwidth.
3517 */
3518 ret = ieee80211_vif_use_channel(sdata, &chandef,
3519 IEEE80211_CHANCTX_SHARED);
3520 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
3521 ifmgd->flags |= chandef_downgrade(&chandef);
3522 return ret;
3145} 3523}
3146 3524
3147static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, 3525static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
@@ -3211,7 +3589,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3211 sdata->vif.bss_conf.basic_rates = basic_rates; 3589 sdata->vif.bss_conf.basic_rates = basic_rates;
3212 3590
3213 /* cf. IEEE 802.11 9.2.12 */ 3591 /* cf. IEEE 802.11 9.2.12 */
3214 if (local->oper_channel->band == IEEE80211_BAND_2GHZ && 3592 if (cbss->channel->band == IEEE80211_BAND_2GHZ &&
3215 have_higher_than_11mbit) 3593 have_higher_than_11mbit)
3216 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 3594 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
3217 else 3595 else
@@ -3273,19 +3651,33 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3273 case NL80211_AUTHTYPE_NETWORK_EAP: 3651 case NL80211_AUTHTYPE_NETWORK_EAP:
3274 auth_alg = WLAN_AUTH_LEAP; 3652 auth_alg = WLAN_AUTH_LEAP;
3275 break; 3653 break;
3654 case NL80211_AUTHTYPE_SAE:
3655 auth_alg = WLAN_AUTH_SAE;
3656 break;
3276 default: 3657 default:
3277 return -EOPNOTSUPP; 3658 return -EOPNOTSUPP;
3278 } 3659 }
3279 3660
3280 auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL); 3661 auth_data = kzalloc(sizeof(*auth_data) + req->sae_data_len +
3662 req->ie_len, GFP_KERNEL);
3281 if (!auth_data) 3663 if (!auth_data)
3282 return -ENOMEM; 3664 return -ENOMEM;
3283 3665
3284 auth_data->bss = req->bss; 3666 auth_data->bss = req->bss;
3285 3667
3668 if (req->sae_data_len >= 4) {
3669 __le16 *pos = (__le16 *) req->sae_data;
3670 auth_data->sae_trans = le16_to_cpu(pos[0]);
3671 auth_data->sae_status = le16_to_cpu(pos[1]);
3672 memcpy(auth_data->data, req->sae_data + 4,
3673 req->sae_data_len - 4);
3674 auth_data->data_len += req->sae_data_len - 4;
3675 }
3676
3286 if (req->ie && req->ie_len) { 3677 if (req->ie && req->ie_len) {
3287 memcpy(auth_data->ie, req->ie, req->ie_len); 3678 memcpy(&auth_data->data[auth_data->data_len],
3288 auth_data->ie_len = req->ie_len; 3679 req->ie, req->ie_len);
3680 auth_data->data_len += req->ie_len;
3289 } 3681 }
3290 3682
3291 if (req->key && req->key_len) { 3683 if (req->key && req->key_len) {
@@ -3355,14 +3747,21 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3355 const u8 *ssidie, *ht_ie; 3747 const u8 *ssidie, *ht_ie;
3356 int i, err; 3748 int i, err;
3357 3749
3358 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
3359 if (!ssidie)
3360 return -EINVAL;
3361
3362 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL); 3750 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
3363 if (!assoc_data) 3751 if (!assoc_data)
3364 return -ENOMEM; 3752 return -ENOMEM;
3365 3753
3754 rcu_read_lock();
3755 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
3756 if (!ssidie) {
3757 rcu_read_unlock();
3758 kfree(assoc_data);
3759 return -EINVAL;
3760 }
3761 memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
3762 assoc_data->ssid_len = ssidie[1];
3763 rcu_read_unlock();
3764
3366 mutex_lock(&ifmgd->mtx); 3765 mutex_lock(&ifmgd->mtx);
3367 3766
3368 if (ifmgd->associated) 3767 if (ifmgd->associated)
@@ -3388,13 +3787,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3388 3787
3389 /* prepare assoc data */ 3788 /* prepare assoc data */
3390 3789
3391 /*
3392 * keep only the 40 MHz disable bit set as it might have
3393 * been set during authentication already, all other bits
3394 * should be reset for a new connection
3395 */
3396 ifmgd->flags &= IEEE80211_STA_DISABLE_40MHZ;
3397
3398 ifmgd->beacon_crc_valid = false; 3790 ifmgd->beacon_crc_valid = false;
3399 3791
3400 /* 3792 /*
@@ -3408,7 +3800,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3408 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 3800 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
3409 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 3801 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
3410 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { 3802 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
3411 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3803 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3412 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3804 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3413 netdev_info(sdata->dev, 3805 netdev_info(sdata->dev,
3414 "disabling HT/VHT due to WEP/TKIP use\n"); 3806 "disabling HT/VHT due to WEP/TKIP use\n");
@@ -3416,7 +3808,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3416 } 3808 }
3417 3809
3418 if (req->flags & ASSOC_REQ_DISABLE_HT) { 3810 if (req->flags & ASSOC_REQ_DISABLE_HT) {
3419 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3811 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3420 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 3812 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
3421 } 3813 }
3422 3814
@@ -3424,7 +3816,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3424 sband = local->hw.wiphy->bands[req->bss->channel->band]; 3816 sband = local->hw.wiphy->bands[req->bss->channel->band];
3425 if (!sband->ht_cap.ht_supported || 3817 if (!sband->ht_cap.ht_supported ||
3426 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { 3818 local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
3427 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3819 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3428 if (!bss->wmm_used) 3820 if (!bss->wmm_used)
3429 netdev_info(sdata->dev, 3821 netdev_info(sdata->dev,
3430 "disabling HT as WMM/QoS is not supported by the AP\n"); 3822 "disabling HT as WMM/QoS is not supported by the AP\n");
@@ -3452,11 +3844,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3452 3844
3453 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { 3845 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
3454 if (ifmgd->powersave) 3846 if (ifmgd->powersave)
3455 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC; 3847 sdata->smps_mode = IEEE80211_SMPS_DYNAMIC;
3456 else 3848 else
3457 ifmgd->ap_smps = IEEE80211_SMPS_OFF; 3849 sdata->smps_mode = IEEE80211_SMPS_OFF;
3458 } else 3850 } else
3459 ifmgd->ap_smps = ifmgd->req_smps; 3851 sdata->smps_mode = ifmgd->req_smps;
3460 3852
3461 assoc_data->capability = req->bss->capability; 3853 assoc_data->capability = req->bss->capability;
3462 assoc_data->wmm = bss->wmm_used && 3854 assoc_data->wmm = bss->wmm_used &&
@@ -3464,12 +3856,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3464 assoc_data->supp_rates = bss->supp_rates; 3856 assoc_data->supp_rates = bss->supp_rates;
3465 assoc_data->supp_rates_len = bss->supp_rates_len; 3857 assoc_data->supp_rates_len = bss->supp_rates_len;
3466 3858
3859 rcu_read_lock();
3467 ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); 3860 ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION);
3468 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation)) 3861 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation))
3469 assoc_data->ap_ht_param = 3862 assoc_data->ap_ht_param =
3470 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; 3863 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
3471 else 3864 else
3472 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3865 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3866 rcu_read_unlock();
3473 3867
3474 if (bss->wmm_used && bss->uapsd_supported && 3868 if (bss->wmm_used && bss->uapsd_supported &&
3475 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3869 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
@@ -3480,9 +3874,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3480 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; 3874 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
3481 } 3875 }
3482 3876
3483 memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
3484 assoc_data->ssid_len = ssidie[1];
3485
3486 if (req->prev_bssid) 3877 if (req->prev_bssid)
3487 memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN); 3878 memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN);
3488 3879
@@ -3560,40 +3951,44 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
3560 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3951 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3561 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 3952 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3562 bool tx = !req->local_state_change; 3953 bool tx = !req->local_state_change;
3954 bool sent_frame = false;
3563 3955
3564 mutex_lock(&ifmgd->mtx); 3956 mutex_lock(&ifmgd->mtx);
3565 3957
3566 if (ifmgd->auth_data) {
3567 ieee80211_destroy_auth_data(sdata, false);
3568 mutex_unlock(&ifmgd->mtx);
3569 return 0;
3570 }
3571
3572 sdata_info(sdata, 3958 sdata_info(sdata,
3573 "deauthenticating from %pM by local choice (reason=%d)\n", 3959 "deauthenticating from %pM by local choice (reason=%d)\n",
3574 req->bssid, req->reason_code); 3960 req->bssid, req->reason_code);
3575 3961
3576 if (ifmgd->associated && 3962 if (ifmgd->auth_data) {
3577 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
3578 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3579 req->reason_code, tx, frame_buf);
3580 } else {
3581 drv_mgd_prepare_tx(sdata->local, sdata); 3963 drv_mgd_prepare_tx(sdata->local, sdata);
3582 ieee80211_send_deauth_disassoc(sdata, req->bssid, 3964 ieee80211_send_deauth_disassoc(sdata, req->bssid,
3583 IEEE80211_STYPE_DEAUTH, 3965 IEEE80211_STYPE_DEAUTH,
3584 req->reason_code, tx, 3966 req->reason_code, tx,
3585 frame_buf); 3967 frame_buf);
3968 ieee80211_destroy_auth_data(sdata, false);
3969 mutex_unlock(&ifmgd->mtx);
3970
3971 sent_frame = tx;
3972 goto out;
3586 } 3973 }
3587 3974
3975 if (ifmgd->associated &&
3976 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
3977 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3978 req->reason_code, tx, frame_buf);
3979 sent_frame = tx;
3980 }
3588 mutex_unlock(&ifmgd->mtx); 3981 mutex_unlock(&ifmgd->mtx);
3589 3982
3590 __cfg80211_send_deauth(sdata->dev, frame_buf, 3983 out:
3591 IEEE80211_DEAUTH_FRAME_LEN);
3592
3593 mutex_lock(&sdata->local->mtx); 3984 mutex_lock(&sdata->local->mtx);
3594 ieee80211_recalc_idle(sdata->local); 3985 ieee80211_recalc_idle(sdata->local);
3595 mutex_unlock(&sdata->local->mtx); 3986 mutex_unlock(&sdata->local->mtx);
3596 3987
3988 if (sent_frame)
3989 __cfg80211_send_deauth(sdata->dev, frame_buf,
3990 IEEE80211_DEAUTH_FRAME_LEN);
3991
3597 return 0; 3992 return 0;
3598} 3993}
3599 3994