hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/mac80211/mlme.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * BSS client mode implementation
34 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
....@@ -7,14 +8,11 @@
78 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
89 * Copyright 2013-2014 Intel Mobile Communications GmbH
910 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
10
- * Copyright (C) 2018 Intel Corporation
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License version 2 as
14
- * published by the Free Software Foundation.
11
+ * Copyright (C) 2018 - 2020 Intel Corporation
1512 */
1613
1714 #include <linux/delay.h>
15
+#include <linux/fips.h>
1816 #include <linux/if_ether.h>
1917 #include <linux/skbuff.h>
2018 #include <linux/if_arp.h>
....@@ -39,6 +37,7 @@
3937 #define IEEE80211_AUTH_TIMEOUT_SAE (HZ * 2)
4038 #define IEEE80211_AUTH_MAX_TRIES 3
4139 #define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
40
+#define IEEE80211_AUTH_WAIT_SAE_RETRY (HZ * 2)
4241 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
4342 #define IEEE80211_ASSOC_TIMEOUT_LONG (HZ / 2)
4443 #define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
....@@ -147,9 +146,11 @@
147146 ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
148147 struct ieee80211_supported_band *sband,
149148 struct ieee80211_channel *channel,
149
+ u32 vht_cap_info,
150150 const struct ieee80211_ht_operation *ht_oper,
151151 const struct ieee80211_vht_operation *vht_oper,
152152 const struct ieee80211_he_operation *he_oper,
153
+ const struct ieee80211_s1g_oper_ie *s1g_oper,
153154 struct cfg80211_chan_def *chandef, bool tracking)
154155 {
155156 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
....@@ -157,16 +158,42 @@
157158 struct ieee80211_sta_ht_cap sta_ht_cap;
158159 u32 ht_cfreq, ret;
159160
160
- memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
161
- ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
162
-
163161 memset(chandef, 0, sizeof(struct cfg80211_chan_def));
164162 chandef->chan = channel;
165163 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
166164 chandef->center_freq1 = channel->center_freq;
165
+ chandef->freq1_offset = channel->freq_offset;
166
+
167
+ if (channel->band == NL80211_BAND_6GHZ) {
168
+ if (!ieee80211_chandef_he_6ghz_oper(sdata, he_oper, chandef))
169
+ ret = IEEE80211_STA_DISABLE_HT |
170
+ IEEE80211_STA_DISABLE_VHT |
171
+ IEEE80211_STA_DISABLE_HE;
172
+ else
173
+ ret = 0;
174
+ vht_chandef = *chandef;
175
+ goto out;
176
+ } else if (sband->band == NL80211_BAND_S1GHZ) {
177
+ if (!ieee80211_chandef_s1g_oper(s1g_oper, chandef)) {
178
+ sdata_info(sdata,
179
+ "Missing S1G Operation Element? Trying operating == primary\n");
180
+ chandef->width = ieee80211_s1g_channel_width(channel);
181
+ }
182
+
183
+ ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_40MHZ |
184
+ IEEE80211_STA_DISABLE_VHT |
185
+ IEEE80211_STA_DISABLE_80P80MHZ |
186
+ IEEE80211_STA_DISABLE_160MHZ;
187
+ goto out;
188
+ }
189
+
190
+ memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
191
+ ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
167192
168193 if (!ht_oper || !sta_ht_cap.ht_supported) {
169
- ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
194
+ ret = IEEE80211_STA_DISABLE_HT |
195
+ IEEE80211_STA_DISABLE_VHT |
196
+ IEEE80211_STA_DISABLE_HE;
170197 goto out;
171198 }
172199
....@@ -187,7 +214,9 @@
187214 "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
188215 channel->center_freq, ht_cfreq,
189216 ht_oper->primary_chan, channel->band);
190
- ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
217
+ ret = IEEE80211_STA_DISABLE_HT |
218
+ IEEE80211_STA_DISABLE_VHT |
219
+ IEEE80211_STA_DISABLE_HE;
191220 goto out;
192221 }
193222
....@@ -220,7 +249,8 @@
220249 memcpy(&he_oper_vht_cap, he_oper->optional, 3);
221250 he_oper_vht_cap.basic_mcs_set = cpu_to_le16(0);
222251
223
- if (!ieee80211_chandef_vht_oper(&he_oper_vht_cap,
252
+ if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
253
+ &he_oper_vht_cap, ht_oper,
224254 &vht_chandef)) {
225255 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE))
226256 sdata_info(sdata,
....@@ -228,7 +258,10 @@
228258 ret = IEEE80211_STA_DISABLE_HE;
229259 goto out;
230260 }
231
- } else if (!ieee80211_chandef_vht_oper(vht_oper, &vht_chandef)) {
261
+ } else if (!ieee80211_chandef_vht_oper(&sdata->local->hw,
262
+ vht_cap_info,
263
+ vht_oper, ht_oper,
264
+ &vht_chandef)) {
232265 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
233266 sdata_info(sdata,
234267 "AP VHT information is invalid, disable VHT\n");
....@@ -301,12 +334,17 @@
301334 IEEE80211_CHAN_DISABLED)) {
302335 if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
303336 ret = IEEE80211_STA_DISABLE_HT |
304
- IEEE80211_STA_DISABLE_VHT;
337
+ IEEE80211_STA_DISABLE_VHT |
338
+ IEEE80211_STA_DISABLE_HE;
305339 break;
306340 }
307341
308342 ret |= ieee80211_chandef_downgrade(chandef);
309343 }
344
+
345
+ if (!he_oper || !cfg80211_chandef_usable(sdata->wdev.wiphy, chandef,
346
+ IEEE80211_CHAN_NO_HE))
347
+ ret |= IEEE80211_STA_DISABLE_HE;
310348
311349 if (chandef->width != vht_chandef.width && !tracking)
312350 sdata_info(sdata,
....@@ -319,9 +357,11 @@
319357 static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
320358 struct sta_info *sta,
321359 const struct ieee80211_ht_cap *ht_cap,
360
+ const struct ieee80211_vht_cap *vht_cap,
322361 const struct ieee80211_ht_operation *ht_oper,
323362 const struct ieee80211_vht_operation *vht_oper,
324363 const struct ieee80211_he_operation *he_oper,
364
+ const struct ieee80211_s1g_oper_ie *s1g_oper,
325365 const u8 *bssid, u32 *changed)
326366 {
327367 struct ieee80211_local *local = sdata->local;
....@@ -333,6 +373,7 @@
333373 u16 ht_opmode;
334374 u32 flags;
335375 enum ieee80211_sta_rx_bandwidth new_sta_bw;
376
+ u32 vht_cap_info = 0;
336377 int ret;
337378
338379 /* if HT was/is disabled, don't track any bandwidth changes */
....@@ -361,10 +402,13 @@
361402 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
362403 }
363404
405
+ if (vht_cap)
406
+ vht_cap_info = le32_to_cpu(vht_cap->vht_cap_info);
407
+
364408 /* calculate new channel (type) based on HT/VHT/HE operation IEs */
365
- flags = ieee80211_determine_chantype(sdata, sband, chan,
409
+ flags = ieee80211_determine_chantype(sdata, sband, chan, vht_cap_info,
366410 ht_oper, vht_oper, he_oper,
367
- &chandef, true);
411
+ s1g_oper, &chandef, true);
368412
369413 /*
370414 * Downgrade the new channel if we associated with restricted
....@@ -387,12 +431,16 @@
387431 return 0;
388432
389433 sdata_info(sdata,
390
- "AP %pM changed bandwidth, new config is %d MHz, width %d (%d/%d MHz)\n",
391
- ifmgd->bssid, chandef.chan->center_freq, chandef.width,
392
- chandef.center_freq1, chandef.center_freq2);
434
+ "AP %pM changed bandwidth, new config is %d.%03d MHz, "
435
+ "width %d (%d.%03d/%d MHz)\n",
436
+ ifmgd->bssid, chandef.chan->center_freq,
437
+ chandef.chan->freq_offset, chandef.width,
438
+ chandef.center_freq1, chandef.freq1_offset,
439
+ chandef.center_freq2);
393440
394441 if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
395442 IEEE80211_STA_DISABLE_VHT |
443
+ IEEE80211_STA_DISABLE_HE |
396444 IEEE80211_STA_DISABLE_40MHZ |
397445 IEEE80211_STA_DISABLE_80P80MHZ |
398446 IEEE80211_STA_DISABLE_160MHZ)) ||
....@@ -500,7 +548,7 @@
500548 case IEEE80211_SMPS_AUTOMATIC:
501549 case IEEE80211_SMPS_NUM_MODES:
502550 WARN_ON(1);
503
- /* fall through */
551
+ fallthrough;
504552 case IEEE80211_SMPS_OFF:
505553 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
506554 IEEE80211_HT_CAP_SM_PS_SHIFT;
....@@ -616,10 +664,21 @@
616664 {
617665 u8 *pos;
618666 const struct ieee80211_sta_he_cap *he_cap = NULL;
667
+ struct ieee80211_chanctx_conf *chanctx_conf;
619668 u8 he_cap_size;
669
+ bool reg_cap = false;
670
+
671
+ rcu_read_lock();
672
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
673
+ if (!WARN_ON_ONCE(!chanctx_conf))
674
+ reg_cap = cfg80211_chandef_usable(sdata->wdev.wiphy,
675
+ &chanctx_conf->def,
676
+ IEEE80211_CHAN_NO_HE);
677
+
678
+ rcu_read_unlock();
620679
621680 he_cap = ieee80211_get_he_sta_cap(sband);
622
- if (!he_cap)
681
+ if (!he_cap || !reg_cap)
623682 return;
624683
625684 /*
....@@ -633,6 +692,8 @@
633692 he_cap->he_cap_elem.phy_cap_info);
634693 pos = skb_put(skb, he_cap_size);
635694 ieee80211_ie_build_he_cap(pos, he_cap, pos + he_cap_size);
695
+
696
+ ieee80211_ie_build_he_6ghz_cap(sdata, skb);
636697 }
637698
638699 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
....@@ -642,7 +703,7 @@
642703 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
643704 struct sk_buff *skb;
644705 struct ieee80211_mgmt *mgmt;
645
- u8 *pos, qos_info;
706
+ u8 *pos, qos_info, *ie_start;
646707 size_t offset = 0, noffset;
647708 int i, count, rates_len, supp_rates_len, shift;
648709 u16 capab;
....@@ -650,6 +711,14 @@
650711 struct ieee80211_chanctx_conf *chanctx_conf;
651712 struct ieee80211_channel *chan;
652713 u32 rates = 0;
714
+ __le16 listen_int;
715
+ struct element *ext_capa = NULL;
716
+
717
+ /* we know it's writable, cast away the const */
718
+ if (assoc_data->ie_len)
719
+ ext_capa = (void *)cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
720
+ assoc_data->ie,
721
+ assoc_data->ie_len);
653722
654723 sdata_assert_lock(sdata);
655724
....@@ -699,6 +768,7 @@
699768 2 + 1 + sizeof(struct ieee80211_he_cap_elem) + /* HE */
700769 sizeof(struct ieee80211_he_mcs_nss_supp) +
701770 IEEE80211_HE_PPE_THRES_MAX_LEN +
771
+ 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
702772 assoc_data->ie_len + /* extra IEs */
703773 (assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) +
704774 9, /* WMM */
....@@ -730,13 +800,15 @@
730800 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
731801 memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);
732802
803
+ listen_int = cpu_to_le16(sband->band == NL80211_BAND_S1GHZ ?
804
+ ieee80211_encode_usf(local->hw.conf.listen_interval) :
805
+ local->hw.conf.listen_interval);
733806 if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
734807 skb_put(skb, 10);
735808 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
736809 IEEE80211_STYPE_REASSOC_REQ);
737810 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
738
- mgmt->u.reassoc_req.listen_interval =
739
- cpu_to_le16(local->hw.conf.listen_interval);
811
+ mgmt->u.reassoc_req.listen_interval = listen_int;
740812 memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
741813 ETH_ALEN);
742814 } else {
....@@ -744,15 +816,18 @@
744816 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
745817 IEEE80211_STYPE_ASSOC_REQ);
746818 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
747
- mgmt->u.assoc_req.listen_interval =
748
- cpu_to_le16(local->hw.conf.listen_interval);
819
+ mgmt->u.assoc_req.listen_interval = listen_int;
749820 }
750821
751822 /* SSID */
752823 pos = skb_put(skb, 2 + assoc_data->ssid_len);
824
+ ie_start = pos;
753825 *pos++ = WLAN_EID_SSID;
754826 *pos++ = assoc_data->ssid_len;
755827 memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
828
+
829
+ if (sband->band == NL80211_BAND_S1GHZ)
830
+ goto skip_rates;
756831
757832 /* add all rates which were marked to be used above */
758833 supp_rates_len = rates_len;
....@@ -789,6 +864,7 @@
789864 }
790865 }
791866
867
+skip_rates:
792868 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT ||
793869 capab & WLAN_CAPABILITY_RADIO_MEASURE) {
794870 pos = skb_put(skb, 4);
....@@ -799,7 +875,15 @@
799875 *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def);
800876 }
801877
802
- if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
878
+ /*
879
+ * Per spec, we shouldn't include the list of channels if we advertise
880
+ * support for extended channel switching, but we've always done that;
881
+ * (for now?) apply this restriction only on the (new) 6 GHz band.
882
+ */
883
+ if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT &&
884
+ (sband->band != NL80211_BAND_6GHZ ||
885
+ !ext_capa || ext_capa->datalen < 1 ||
886
+ !(ext_capa->data[0] & WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING))) {
803887 /* TODO: get this in reg domain format */
804888 pos = skb_put(skb, 2 * sband->n_channels + 2);
805889 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
....@@ -810,6 +894,12 @@
810894 *pos++ = 1; /* one channel in the subband*/
811895 }
812896 }
897
+
898
+ /* Set MBSSID support for HE AP if needed */
899
+ if (ieee80211_hw_check(&local->hw, SUPPORTS_ONLY_HE_MULTI_BSSID) &&
900
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) && assoc_data->ie_len &&
901
+ ext_capa && ext_capa->datalen >= 3)
902
+ ext_capa->data[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT;
813903
814904 /* if present, add any custom IEs that go before HT */
815905 if (assoc_data->ie_len) {
....@@ -856,7 +946,8 @@
856946 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)))
857947 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
858948
859
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
949
+ if (sband->band != NL80211_BAND_6GHZ &&
950
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
860951 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
861952 sband, chan, sdata->smps_mode);
862953
....@@ -910,9 +1001,19 @@
9101001 offset = noffset;
9111002 }
9121003
913
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
1004
+ if (sband->band != NL80211_BAND_6GHZ &&
1005
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
9141006 ieee80211_add_vht_ie(sdata, skb, sband,
9151007 &assoc_data->ap_vht_cap);
1008
+
1009
+ /*
1010
+ * If AP doesn't support HT, mark HE as disabled.
1011
+ * If on the 5GHz band, make sure it supports VHT.
1012
+ */
1013
+ if (ifmgd->flags & IEEE80211_STA_DISABLE_HT ||
1014
+ (sband->band == NL80211_BAND_5GHZ &&
1015
+ ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
1016
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
9161017
9171018 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE))
9181019 ieee80211_add_he_ie(sdata, skb, sband);
....@@ -938,6 +1039,11 @@
9381039 pos = ieee80211_add_wmm_info_ie(skb_put(skb, 9), qos_info);
9391040 }
9401041
1042
+ if (sband->band == NL80211_BAND_S1GHZ) {
1043
+ ieee80211_add_aid_request_ie(sdata, skb);
1044
+ ieee80211_add_s1g_capab_ie(sdata, &sband->s1g_cap, skb);
1045
+ }
1046
+
9411047 /* add any remaining custom (i.e. vendor specific here) IEs */
9421048 if (assoc_data->ie_len) {
9431049 noffset = assoc_data->ie_len;
....@@ -949,6 +1055,11 @@
9491055 dev_kfree_skb(skb);
9501056 return;
9511057 }
1058
+
1059
+ pos = skb_tail_pointer(skb);
1060
+ kfree(ifmgd->assoc_req_ies);
1061
+ ifmgd->assoc_req_ies = kmemdup(ie_start, pos - ie_start, GFP_ATOMIC);
1062
+ ifmgd->assoc_req_ies_len = pos - ie_start;
9521063
9531064 drv_mgd_prepare_tx(local, sdata, 0);
9541065
....@@ -984,11 +1095,6 @@
9841095 struct ieee80211_hdr_3addr *nullfunc;
9851096 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
9861097
987
- /* Don't send NDPs when STA is connected HE */
988
- if (sdata->vif.type == NL80211_IFTYPE_STATION &&
989
- !(ifmgd->flags & IEEE80211_STA_DISABLE_HE))
990
- return;
991
-
9921098 skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif,
9931099 !ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP));
9941100 if (!skb)
....@@ -1010,18 +1116,14 @@
10101116 ieee80211_tx_skb(sdata, skb);
10111117 }
10121118
1013
-static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
1014
- struct ieee80211_sub_if_data *sdata)
1119
+void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
1120
+ struct ieee80211_sub_if_data *sdata)
10151121 {
10161122 struct sk_buff *skb;
10171123 struct ieee80211_hdr *nullfunc;
10181124 __le16 fc;
10191125
10201126 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1021
- return;
1022
-
1023
- /* Don't send NDPs when connected HE */
1024
- if (!(sdata->u.mgd.flags & IEEE80211_STA_DISABLE_HE))
10251127 return;
10261128
10271129 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 30);
....@@ -1229,6 +1331,32 @@
12291331 }
12301332
12311333 static void
1334
+ieee80211_sta_abort_chanswitch(struct ieee80211_sub_if_data *sdata)
1335
+{
1336
+ struct ieee80211_local *local = sdata->local;
1337
+
1338
+ if (!local->ops->abort_channel_switch)
1339
+ return;
1340
+
1341
+ mutex_lock(&local->mtx);
1342
+
1343
+ mutex_lock(&local->chanctx_mtx);
1344
+ ieee80211_vif_unreserve_chanctx(sdata);
1345
+ mutex_unlock(&local->chanctx_mtx);
1346
+
1347
+ if (sdata->csa_block_tx)
1348
+ ieee80211_wake_vif_queues(local, sdata,
1349
+ IEEE80211_QUEUE_STOP_REASON_CSA);
1350
+
1351
+ sdata->csa_block_tx = false;
1352
+ sdata->vif.csa_active = false;
1353
+
1354
+ mutex_unlock(&local->mtx);
1355
+
1356
+ drv_abort_channel_switch(sdata);
1357
+}
1358
+
1359
+static void
12321360 ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
12331361 u64 timestamp, u32 device_timestamp,
12341362 struct ieee802_11_elems *elems,
....@@ -1242,6 +1370,7 @@
12421370 enum nl80211_band current_band;
12431371 struct ieee80211_csa_ie csa_ie;
12441372 struct ieee80211_channel_switch ch_switch;
1373
+ struct ieee80211_bss *bss;
12451374 int res;
12461375
12471376 sdata_assert_lock(sdata);
....@@ -1252,27 +1381,50 @@
12521381 if (local->scanning)
12531382 return;
12541383
1255
- /* disregard subsequent announcements if we are already processing */
1256
- if (sdata->vif.csa_active)
1257
- return;
1258
-
12591384 current_band = cbss->channel->band;
1385
+ bss = (void *)cbss->priv;
12601386 res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
1387
+ bss->vht_cap_info,
12611388 ifmgd->flags,
12621389 ifmgd->associated->bssid, &csa_ie);
1263
- if (res < 0)
1390
+
1391
+ if (!res) {
1392
+ ch_switch.timestamp = timestamp;
1393
+ ch_switch.device_timestamp = device_timestamp;
1394
+ ch_switch.block_tx = csa_ie.mode;
1395
+ ch_switch.chandef = csa_ie.chandef;
1396
+ ch_switch.count = csa_ie.count;
1397
+ ch_switch.delay = csa_ie.max_switch_time;
1398
+ }
1399
+
1400
+ if (res < 0) {
12641401 ieee80211_queue_work(&local->hw,
12651402 &ifmgd->csa_connection_drop_work);
1266
- if (res)
12671403 return;
1404
+ }
1405
+
1406
+ if (beacon && sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) {
1407
+ if (res)
1408
+ ieee80211_sta_abort_chanswitch(sdata);
1409
+ else
1410
+ drv_channel_switch_rx_beacon(sdata, &ch_switch);
1411
+ return;
1412
+ } else if (sdata->vif.csa_active || res) {
1413
+ /* disregard subsequent announcements if already processing */
1414
+ return;
1415
+ }
12681416
12691417 if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
12701418 IEEE80211_CHAN_DISABLED)) {
12711419 sdata_info(sdata,
1272
- "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
1420
+ "AP %pM switches to unsupported channel "
1421
+ "(%d.%03d MHz, width:%d, CF1/2: %d.%03d/%d MHz), "
1422
+ "disconnecting\n",
12731423 ifmgd->associated->bssid,
12741424 csa_ie.chandef.chan->center_freq,
1425
+ csa_ie.chandef.chan->freq_offset,
12751426 csa_ie.chandef.width, csa_ie.chandef.center_freq1,
1427
+ csa_ie.chandef.freq1_offset,
12761428 csa_ie.chandef.center_freq2);
12771429 ieee80211_queue_work(&local->hw,
12781430 &ifmgd->csa_connection_drop_work);
....@@ -1280,7 +1432,8 @@
12801432 }
12811433
12821434 if (cfg80211_chandef_identical(&csa_ie.chandef,
1283
- &sdata->vif.bss_conf.chandef)) {
1435
+ &sdata->vif.bss_conf.chandef) &&
1436
+ (!csa_ie.mode || !beacon)) {
12841437 if (ifmgd->csa_ignored_same_chan)
12851438 return;
12861439 sdata_info(sdata,
....@@ -1316,12 +1469,6 @@
13161469 "driver doesn't support chan-switch with channel contexts\n");
13171470 goto drop_connection;
13181471 }
1319
-
1320
- ch_switch.timestamp = timestamp;
1321
- ch_switch.device_timestamp = device_timestamp;
1322
- ch_switch.block_tx = csa_ie.mode;
1323
- ch_switch.chandef = csa_ie.chandef;
1324
- ch_switch.count = csa_ie.count;
13251472
13261473 if (drv_pre_channel_switch(sdata, &ch_switch)) {
13271474 sdata_info(sdata,
....@@ -1404,12 +1551,13 @@
14041551 switch (channel->band) {
14051552 default:
14061553 WARN_ON_ONCE(1);
1407
- /* fall through */
1554
+ fallthrough;
14081555 case NL80211_BAND_2GHZ:
14091556 case NL80211_BAND_60GHZ:
14101557 chan_increment = 1;
14111558 break;
14121559 case NL80211_BAND_5GHZ:
1560
+ case NL80211_BAND_6GHZ:
14131561 chan_increment = 4;
14141562 break;
14151563 }
....@@ -1470,6 +1618,9 @@
14701618 int pwr_level_cisco, pwr_level_80211h;
14711619 int new_ap_level;
14721620 __le16 capab = mgmt->u.probe_resp.capab_info;
1621
+
1622
+ if (ieee80211_is_s1g_beacon(mgmt->frame_control))
1623
+ return 0; /* TODO */
14731624
14741625 if (country_ie &&
14751626 (capab & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) ||
....@@ -1869,7 +2020,7 @@
18692020 struct ieee80211_tx_queue_params params[IEEE80211_NUM_ACS];
18702021 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
18712022 size_t left;
1872
- int count, ac;
2023
+ int count, mu_edca_count, ac;
18732024 const u8 *pos;
18742025 u8 uapsd_queues = 0;
18752026
....@@ -1889,9 +2040,16 @@
18892040 uapsd_queues = ifmgd->uapsd_queues;
18902041
18912042 count = wmm_param[6] & 0x0f;
1892
- if (count == ifmgd->wmm_last_param_set)
2043
+ /* -1 is the initial value of ifmgd->mu_edca_last_param_set.
2044
+ * if mu_edca was preset before and now it disappeared tell
2045
+ * the driver about it.
2046
+ */
2047
+ mu_edca_count = mu_edca ? mu_edca->mu_qos_info & 0x0f : -1;
2048
+ if (count == ifmgd->wmm_last_param_set &&
2049
+ mu_edca_count == ifmgd->mu_edca_last_param_set)
18932050 return false;
18942051 ifmgd->wmm_last_param_set = count;
2052
+ ifmgd->mu_edca_last_param_set = mu_edca_count;
18952053
18962054 pos = wmm_param + 8;
18972055 left = wmm_param_len - 8;
....@@ -2040,7 +2198,8 @@
20402198 }
20412199
20422200 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
2043
- if (sband->band == NL80211_BAND_5GHZ)
2201
+ if (sband->band == NL80211_BAND_5GHZ ||
2202
+ sband->band == NL80211_BAND_6GHZ)
20442203 use_short_slot = true;
20452204
20462205 if (use_protection != bss_conf->use_cts_prot) {
....@@ -2208,8 +2367,9 @@
22082367 !ifmgd->have_beacon)
22092368 drv_mgd_prepare_tx(sdata->local, sdata, 0);
22102369
2211
- ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
2212
- reason, tx, frame_buf);
2370
+ ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid,
2371
+ ifmgd->bssid, stype, reason,
2372
+ tx, frame_buf);
22132373 }
22142374
22152375 /* flush out frame - make sure the deauth was actually sent */
....@@ -2297,23 +2457,6 @@
22972457 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
22982458 }
22992459
2300
-void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
2301
- struct ieee80211_hdr *hdr)
2302
-{
2303
- /*
2304
- * We can postpone the mgd.timer whenever receiving unicast frames
2305
- * from AP because we know that the connection is working both ways
2306
- * at that time. But multicast frames (and hence also beacons) must
2307
- * be ignored here, because we need to trigger the timer during
2308
- * data idle periods for sending the periodic probe request to the
2309
- * AP we're connected to.
2310
- */
2311
- if (is_multicast_ether_addr(hdr->addr1))
2312
- return;
2313
-
2314
- ieee80211_sta_reset_conn_monitor(sdata);
2315
-}
2316
-
23172460 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
23182461 {
23192462 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
....@@ -2393,21 +2536,15 @@
23932536 {
23942537 ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time);
23952538
2396
- if (!ieee80211_is_data(hdr->frame_control))
2397
- return;
2398
-
2399
- if (ieee80211_is_any_nullfunc(hdr->frame_control) &&
2400
- sdata->u.mgd.probe_send_count > 0) {
2401
- if (ack)
2402
- ieee80211_sta_reset_conn_monitor(sdata);
2403
- else
2404
- sdata->u.mgd.nullfunc_failed = true;
2405
- ieee80211_queue_work(&sdata->local->hw, &sdata->work);
2539
+ if (!ieee80211_is_any_nullfunc(hdr->frame_control) ||
2540
+ !sdata->u.mgd.probe_send_count)
24062541 return;
2407
- }
24082542
24092543 if (ack)
2410
- ieee80211_sta_reset_conn_monitor(sdata);
2544
+ sdata->u.mgd.probe_send_count = 0;
2545
+ else
2546
+ sdata->u.mgd.nullfunc_failed = true;
2547
+ ieee80211_queue_work(&sdata->local->hw, &sdata->work);
24112548 }
24122549
24132550 static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata,
....@@ -2459,7 +2596,10 @@
24592596
24602597 if (ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) {
24612598 ifmgd->nullfunc_failed = false;
2462
- ieee80211_send_nullfunc(sdata->local, sdata, false);
2599
+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE))
2600
+ ifmgd->probe_send_count--;
2601
+ else
2602
+ ieee80211_send_nullfunc(sdata->local, sdata, false);
24632603 } else {
24642604 int ssid_len;
24652605
....@@ -2759,13 +2899,14 @@
27592899 {
27602900 struct ieee80211_local *local = sdata->local;
27612901 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
2902
+ const struct element *challenge;
27622903 u8 *pos;
2763
- struct ieee802_11_elems elems;
27642904 u32 tx_flags = 0;
27652905
27662906 pos = mgmt->u.auth.variable;
2767
- ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems);
2768
- if (!elems.challenge)
2907
+ challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos,
2908
+ len - (pos - (u8 *)mgmt));
2909
+ if (!challenge)
27692910 return;
27702911 auth_data->expected_transaction = 4;
27712912 drv_mgd_prepare_tx(sdata->local, sdata, 0);
....@@ -2773,10 +2914,43 @@
27732914 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
27742915 IEEE80211_TX_INTFL_MLME_CONN_TX;
27752916 ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0,
2776
- elems.challenge - 2, elems.challenge_len + 2,
2917
+ (void *)challenge,
2918
+ challenge->datalen + sizeof(*challenge),
27772919 auth_data->bss->bssid, auth_data->bss->bssid,
27782920 auth_data->key, auth_data->key_len,
27792921 auth_data->key_idx, tx_flags);
2922
+}
2923
+
2924
+static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata,
2925
+ const u8 *bssid)
2926
+{
2927
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2928
+ struct sta_info *sta;
2929
+ bool result = true;
2930
+
2931
+ sdata_info(sdata, "authenticated\n");
2932
+ ifmgd->auth_data->done = true;
2933
+ ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
2934
+ ifmgd->auth_data->timeout_started = true;
2935
+ run_again(sdata, ifmgd->auth_data->timeout);
2936
+
2937
+ /* move station state to auth */
2938
+ mutex_lock(&sdata->local->sta_mtx);
2939
+ sta = sta_info_get(sdata, bssid);
2940
+ if (!sta) {
2941
+ WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
2942
+ result = false;
2943
+ goto out;
2944
+ }
2945
+ if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
2946
+ sdata_info(sdata, "failed moving %pM to auth\n", bssid);
2947
+ result = false;
2948
+ goto out;
2949
+ }
2950
+
2951
+out:
2952
+ mutex_unlock(&sdata->local->sta_mtx);
2953
+ return result;
27802954 }
27812955
27822956 static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
....@@ -2785,7 +2959,6 @@
27852959 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
27862960 u8 bssid[ETH_ALEN];
27872961 u16 auth_alg, auth_transaction, status_code;
2788
- struct sta_info *sta;
27892962 struct ieee80211_event event = {
27902963 .type = MLME_EVENT,
27912964 .u.mlme.data = AUTH_EVENT,
....@@ -2809,7 +2982,11 @@
28092982 status_code = le16_to_cpu(mgmt->u.auth.status_code);
28102983
28112984 if (auth_alg != ifmgd->auth_data->algorithm ||
2812
- auth_transaction != ifmgd->auth_data->expected_transaction) {
2985
+ (auth_alg != WLAN_AUTH_SAE &&
2986
+ auth_transaction != ifmgd->auth_data->expected_transaction) ||
2987
+ (auth_alg == WLAN_AUTH_SAE &&
2988
+ (auth_transaction < ifmgd->auth_data->expected_transaction ||
2989
+ auth_transaction > 2))) {
28132990 sdata_info(sdata, "%pM unexpected authentication state: alg %d (expected %d) transact %d (expected %d)\n",
28142991 mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
28152992 auth_transaction,
....@@ -2818,10 +2995,25 @@
28182995 }
28192996
28202997 if (status_code != WLAN_STATUS_SUCCESS) {
2998
+ cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2999
+
3000
+ if (auth_alg == WLAN_AUTH_SAE &&
3001
+ (status_code == WLAN_STATUS_ANTI_CLOG_REQUIRED ||
3002
+ (auth_transaction == 1 &&
3003
+ (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
3004
+ status_code == WLAN_STATUS_SAE_PK)))) {
3005
+ /* waiting for userspace now */
3006
+ ifmgd->auth_data->waiting = true;
3007
+ ifmgd->auth_data->timeout =
3008
+ jiffies + IEEE80211_AUTH_WAIT_SAE_RETRY;
3009
+ ifmgd->auth_data->timeout_started = true;
3010
+ run_again(sdata, ifmgd->auth_data->timeout);
3011
+ return;
3012
+ }
3013
+
28213014 sdata_info(sdata, "%pM denied authentication (status %d)\n",
28223015 mgmt->sa, status_code);
28233016 ieee80211_destroy_auth_data(sdata, false);
2824
- cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
28253017 event.u.mlme.status = MLME_DENIED;
28263018 event.u.mlme.reason = status_code;
28273019 drv_event_callback(sdata->local, sdata, &event);
....@@ -2852,40 +3044,18 @@
28523044
28533045 event.u.mlme.status = MLME_SUCCESS;
28543046 drv_event_callback(sdata->local, sdata, &event);
2855
- sdata_info(sdata, "authenticated\n");
2856
- ifmgd->auth_data->done = true;
2857
- ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
2858
- ifmgd->auth_data->timeout_started = true;
2859
- run_again(sdata, ifmgd->auth_data->timeout);
2860
-
2861
- if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
2862
- ifmgd->auth_data->expected_transaction != 2) {
2863
- /*
2864
- * Report auth frame to user space for processing since another
2865
- * round of Authentication frames is still needed.
2866
- */
2867
- cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2868
- return;
3047
+ if (ifmgd->auth_data->algorithm != WLAN_AUTH_SAE ||
3048
+ (auth_transaction == 2 &&
3049
+ ifmgd->auth_data->expected_transaction == 2)) {
3050
+ if (!ieee80211_mark_sta_auth(sdata, bssid))
3051
+ return; /* ignore frame -- wait for timeout */
3052
+ } else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
3053
+ auth_transaction == 2) {
3054
+ sdata_info(sdata, "SAE peer confirmed\n");
3055
+ ifmgd->auth_data->peer_confirmed = true;
28693056 }
2870
-
2871
- /* move station state to auth */
2872
- mutex_lock(&sdata->local->sta_mtx);
2873
- sta = sta_info_get(sdata, bssid);
2874
- if (!sta) {
2875
- WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
2876
- goto out_err;
2877
- }
2878
- if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
2879
- sdata_info(sdata, "failed moving %pM to auth\n", bssid);
2880
- goto out_err;
2881
- }
2882
- mutex_unlock(&sdata->local->sta_mtx);
28833057
28843058 cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2885
- return;
2886
- out_err:
2887
- mutex_unlock(&sdata->local->sta_mtx);
2888
- /* ignore frame -- wait for timeout */
28893059 }
28903060
28913061 #define case_WLAN(type) \
....@@ -3041,15 +3211,16 @@
30413211 *have_higher_than_11mbit = true;
30423212
30433213 /*
3044
- * Skip HT and VHT BSS membership selectors since they're not
3045
- * rates.
3214
+ * Skip HT, VHT and HE BSS membership selectors since they're
3215
+ * not rates.
30463216 *
30473217 * Note: Even though the membership selector and the basic
30483218 * rate flag share the same bit, they are not exactly
30493219 * the same.
30503220 */
30513221 if (supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY) ||
3052
- supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY))
3222
+ supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY) ||
3223
+ supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY))
30533224 continue;
30543225
30553226 for (j = 0; j < sband->n_bitrates; j++) {
....@@ -3073,28 +3244,66 @@
30733244 }
30743245 }
30753246
3247
+static bool ieee80211_twt_req_supported(const struct sta_info *sta,
3248
+ const struct ieee802_11_elems *elems)
3249
+{
3250
+ if (elems->ext_capab_len < 10)
3251
+ return false;
3252
+
3253
+ if (!(elems->ext_capab[9] & WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT))
3254
+ return false;
3255
+
3256
+ return sta->sta.he_cap.he_cap_elem.mac_cap_info[0] &
3257
+ IEEE80211_HE_MAC_CAP0_TWT_RES;
3258
+}
3259
+
3260
+static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
3261
+ struct sta_info *sta,
3262
+ struct ieee802_11_elems *elems)
3263
+{
3264
+ bool twt = ieee80211_twt_req_supported(sta, elems);
3265
+
3266
+ if (sdata->vif.bss_conf.twt_requester != twt) {
3267
+ sdata->vif.bss_conf.twt_requester = twt;
3268
+ return BSS_CHANGED_TWT;
3269
+ }
3270
+ return 0;
3271
+}
3272
+
30763273 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
30773274 struct cfg80211_bss *cbss,
3078
- struct ieee80211_mgmt *mgmt, size_t len)
3275
+ struct ieee80211_mgmt *mgmt, size_t len,
3276
+ struct ieee802_11_elems *elems)
30793277 {
30803278 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
30813279 struct ieee80211_local *local = sdata->local;
30823280 struct ieee80211_supported_band *sband;
30833281 struct sta_info *sta;
3084
- u8 *pos;
30853282 u16 capab_info, aid;
3086
- struct ieee802_11_elems elems;
30873283 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
30883284 const struct cfg80211_bss_ies *bss_ies = NULL;
30893285 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
3286
+ bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
3287
+ bool is_s1g = cbss->channel->band == NL80211_BAND_S1GHZ;
30903288 u32 changed = 0;
3289
+ u8 *pos;
30913290 int err;
30923291 bool ret;
30933292
30943293 /* AssocResp and ReassocResp have identical structure */
30953294
3295
+ pos = mgmt->u.assoc_resp.variable;
30963296 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
3297
+ if (is_s1g) {
3298
+ pos = (u8 *) mgmt->u.s1g_assoc_resp.variable;
3299
+ aid = 0; /* TODO */
3300
+ }
30973301 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
3302
+ ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, elems,
3303
+ mgmt->bssid, NULL);
3304
+
3305
+ if (elems->aid_resp)
3306
+ aid = le16_to_cpu(elems->aid_resp->aid);
30983307
30993308 /*
31003309 * The 5 MSB of the AID field are reserved
....@@ -3111,18 +3320,15 @@
31113320 ifmgd->broken_ap = true;
31123321 }
31133322
3114
- pos = mgmt->u.assoc_resp.variable;
3115
- ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems);
3116
-
3117
- if (!elems.supp_rates) {
3323
+ if (!is_s1g && !elems->supp_rates) {
31183324 sdata_info(sdata, "no SuppRates element in AssocResp\n");
31193325 return false;
31203326 }
31213327
3122
- ifmgd->aid = aid;
3328
+ sdata->vif.bss_conf.aid = aid;
31233329 ifmgd->tdls_chan_switch_prohibited =
3124
- elems.ext_capab && elems.ext_capab_len >= 5 &&
3125
- (elems.ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED);
3330
+ elems->ext_capab && elems->ext_capab_len >= 5 &&
3331
+ (elems->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED);
31263332
31273333 /*
31283334 * Some APs are erroneously not including some information in their
....@@ -3131,11 +3337,12 @@
31313337 * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
31323338 * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
31333339 */
3134
- if ((assoc_data->wmm && !elems.wmm_param) ||
3135
- (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3136
- (!elems.ht_cap_elem || !elems.ht_operation)) ||
3137
- (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3138
- (!elems.vht_cap_elem || !elems.vht_operation))) {
3340
+ if (!is_6ghz &&
3341
+ ((assoc_data->wmm && !elems->wmm_param) ||
3342
+ (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3343
+ (!elems->ht_cap_elem || !elems->ht_operation)) ||
3344
+ (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3345
+ (!elems->vht_cap_elem || !elems->vht_operation)))) {
31393346 const struct cfg80211_bss_ies *ies;
31403347 struct ieee802_11_elems bss_elems;
31413348
....@@ -3149,10 +3356,12 @@
31493356 return false;
31503357
31513358 ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
3152
- false, &bss_elems);
3359
+ false, &bss_elems,
3360
+ mgmt->bssid,
3361
+ assoc_data->bss->bssid);
31533362 if (assoc_data->wmm &&
3154
- !elems.wmm_param && bss_elems.wmm_param) {
3155
- elems.wmm_param = bss_elems.wmm_param;
3363
+ !elems->wmm_param && bss_elems.wmm_param) {
3364
+ elems->wmm_param = bss_elems.wmm_param;
31563365 sdata_info(sdata,
31573366 "AP bug: WMM param missing from AssocResp\n");
31583367 }
....@@ -3161,48 +3370,57 @@
31613370 * Also check if we requested HT/VHT, otherwise the AP doesn't
31623371 * have to include the IEs in the (re)association response.
31633372 */
3164
- if (!elems.ht_cap_elem && bss_elems.ht_cap_elem &&
3373
+ if (!elems->ht_cap_elem && bss_elems.ht_cap_elem &&
31653374 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
3166
- elems.ht_cap_elem = bss_elems.ht_cap_elem;
3375
+ elems->ht_cap_elem = bss_elems.ht_cap_elem;
31673376 sdata_info(sdata,
31683377 "AP bug: HT capability missing from AssocResp\n");
31693378 }
3170
- if (!elems.ht_operation && bss_elems.ht_operation &&
3379
+ if (!elems->ht_operation && bss_elems.ht_operation &&
31713380 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
3172
- elems.ht_operation = bss_elems.ht_operation;
3381
+ elems->ht_operation = bss_elems.ht_operation;
31733382 sdata_info(sdata,
31743383 "AP bug: HT operation missing from AssocResp\n");
31753384 }
3176
- if (!elems.vht_cap_elem && bss_elems.vht_cap_elem &&
3385
+ if (!elems->vht_cap_elem && bss_elems.vht_cap_elem &&
31773386 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
3178
- elems.vht_cap_elem = bss_elems.vht_cap_elem;
3387
+ elems->vht_cap_elem = bss_elems.vht_cap_elem;
31793388 sdata_info(sdata,
31803389 "AP bug: VHT capa missing from AssocResp\n");
31813390 }
3182
- if (!elems.vht_operation && bss_elems.vht_operation &&
3391
+ if (!elems->vht_operation && bss_elems.vht_operation &&
31833392 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
3184
- elems.vht_operation = bss_elems.vht_operation;
3393
+ elems->vht_operation = bss_elems.vht_operation;
31853394 sdata_info(sdata,
31863395 "AP bug: VHT operation missing from AssocResp\n");
31873396 }
3397
+ kfree(bss_elems.nontx_profile);
31883398 }
31893399
31903400 /*
31913401 * We previously checked these in the beacon/probe response, so
31923402 * they should be present here. This is just a safety net.
31933403 */
3194
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3195
- (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) {
3404
+ if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3405
+ (!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
31963406 sdata_info(sdata,
31973407 "HT AP is missing WMM params or HT capability/operation\n");
31983408 ret = false;
31993409 goto out;
32003410 }
32013411
3202
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3203
- (!elems.vht_cap_elem || !elems.vht_operation)) {
3412
+ if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3413
+ (!elems->vht_cap_elem || !elems->vht_operation)) {
32043414 sdata_info(sdata,
32053415 "VHT AP is missing VHT capability/operation\n");
3416
+ ret = false;
3417
+ goto out;
3418
+ }
3419
+
3420
+ if (is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3421
+ !elems->he_6ghz_capa) {
3422
+ sdata_info(sdata,
3423
+ "HE 6 GHz AP is missing HE 6 GHz band capability\n");
32063424 ret = false;
32073425 goto out;
32083426 }
....@@ -3226,18 +3444,8 @@
32263444 goto out;
32273445 }
32283446
3229
- /*
3230
- * If AP doesn't support HT, or it doesn't have HE mandatory IEs, mark
3231
- * HE as disabled. If on the 5GHz band, make sure it supports VHT.
3232
- */
3233
- if (ifmgd->flags & IEEE80211_STA_DISABLE_HT ||
3234
- (sband->band == NL80211_BAND_5GHZ &&
3235
- ifmgd->flags & IEEE80211_STA_DISABLE_VHT) ||
3236
- (!elems.he_cap && !elems.he_operation))
3237
- ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
3238
-
32393447 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3240
- (!elems.he_cap || !elems.he_operation)) {
3448
+ (!elems->he_cap || !elems->he_operation)) {
32413449 mutex_unlock(&sdata->local->sta_mtx);
32423450 sdata_info(sdata,
32433451 "HE AP is missing HE capability/operation\n");
....@@ -3246,36 +3454,57 @@
32463454 }
32473455
32483456 /* Set up internal HT/VHT capabilities */
3249
- if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
3457
+ if (elems->ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
32503458 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
3251
- elems.ht_cap_elem, sta);
3459
+ elems->ht_cap_elem, sta);
32523460
3253
- if (elems.vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
3461
+ if (elems->vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
32543462 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
3255
- elems.vht_cap_elem, sta);
3463
+ elems->vht_cap_elem, sta);
32563464
3257
- if (elems.he_operation && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3258
- elems.he_cap) {
3465
+ if (elems->he_operation && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3466
+ elems->he_cap) {
32593467 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
3260
- elems.he_cap,
3261
- elems.he_cap_len,
3468
+ elems->he_cap,
3469
+ elems->he_cap_len,
3470
+ elems->he_6ghz_capa,
32623471 sta);
32633472
32643473 bss_conf->he_support = sta->sta.he_cap.has_he;
3474
+ if (elems->rsnx && elems->rsnx_len &&
3475
+ (elems->rsnx[0] & WLAN_RSNX_CAPA_PROTECTED_TWT) &&
3476
+ wiphy_ext_feature_isset(local->hw.wiphy,
3477
+ NL80211_EXT_FEATURE_PROTECTED_TWT))
3478
+ bss_conf->twt_protected = true;
3479
+ else
3480
+ bss_conf->twt_protected = false;
3481
+
3482
+ changed |= ieee80211_recalc_twt_req(sdata, sta, elems);
32653483 } else {
32663484 bss_conf->he_support = false;
3485
+ bss_conf->twt_requester = false;
3486
+ bss_conf->twt_protected = false;
32673487 }
32683488
32693489 if (bss_conf->he_support) {
3270
- bss_conf->bss_color =
3271
- le32_get_bits(elems.he_operation->he_oper_params,
3490
+ bss_conf->he_bss_color.color =
3491
+ le32_get_bits(elems->he_operation->he_oper_params,
32723492 IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
3493
+ bss_conf->he_bss_color.partial =
3494
+ le32_get_bits(elems->he_operation->he_oper_params,
3495
+ IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR);
3496
+ bss_conf->he_bss_color.enabled =
3497
+ !le32_get_bits(elems->he_operation->he_oper_params,
3498
+ IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
3499
+
3500
+ if (bss_conf->he_bss_color.enabled)
3501
+ changed |= BSS_CHANGED_HE_BSS_COLOR;
32733502
32743503 bss_conf->htc_trig_based_pkt_ext =
3275
- le32_get_bits(elems.he_operation->he_oper_params,
3504
+ le32_get_bits(elems->he_operation->he_oper_params,
32763505 IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK);
32773506 bss_conf->frame_time_rts_th =
3278
- le32_get_bits(elems.he_operation->he_oper_params,
3507
+ le32_get_bits(elems->he_operation->he_oper_params,
32793508 IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
32803509
32813510 bss_conf->multi_sta_back_32bit =
....@@ -3286,11 +3515,27 @@
32863515 sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
32873516 IEEE80211_HE_MAC_CAP2_ACK_EN;
32883517
3289
- bss_conf->uora_exists = !!elems.uora_element;
3290
- if (elems.uora_element)
3291
- bss_conf->uora_ocw_range = elems.uora_element[0];
3518
+ bss_conf->uora_exists = !!elems->uora_element;
3519
+ if (elems->uora_element)
3520
+ bss_conf->uora_ocw_range = elems->uora_element[0];
32923521
3522
+ ieee80211_he_op_ie_to_bss_conf(&sdata->vif, elems->he_operation);
3523
+ ieee80211_he_spr_ie_to_bss_conf(&sdata->vif, elems->he_spr);
32933524 /* TODO: OPEN: what happens if BSS color disable is set? */
3525
+ }
3526
+
3527
+ if (cbss->transmitted_bss) {
3528
+ bss_conf->nontransmitted = true;
3529
+ ether_addr_copy(bss_conf->transmitter_bssid,
3530
+ cbss->transmitted_bss->bssid);
3531
+ bss_conf->bssid_indicator = cbss->max_bssid_indicator;
3532
+ bss_conf->bssid_index = cbss->bssid_index;
3533
+ } else {
3534
+ bss_conf->nontransmitted = false;
3535
+ memset(bss_conf->transmitter_bssid, 0,
3536
+ sizeof(bss_conf->transmitter_bssid));
3537
+ bss_conf->bssid_indicator = 0;
3538
+ bss_conf->bssid_index = 0;
32943539 }
32953540
32963541 /*
....@@ -3305,11 +3550,11 @@
33053550 * NSS calculation (that would be done in rate_control_rate_init())
33063551 * and use the # of streams from that element.
33073552 */
3308
- if (elems.opmode_notif &&
3309
- !(*elems.opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)) {
3553
+ if (elems->opmode_notif &&
3554
+ !(*elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)) {
33103555 u8 nss;
33113556
3312
- nss = *elems.opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK;
3557
+ nss = *elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK;
33133558 nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
33143559 nss += 1;
33153560 sta->sta.rx_nss = nss;
....@@ -3324,7 +3569,8 @@
33243569 sta->sta.mfp = false;
33253570 }
33263571
3327
- sta->sta.wme = elems.wmm_param && local->hw.queues >= IEEE80211_NUM_ACS;
3572
+ sta->sta.wme = (elems->wmm_param || elems->s1g_capab) &&
3573
+ local->hw.queues >= IEEE80211_NUM_ACS;
33283574
33293575 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
33303576 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
....@@ -3339,6 +3585,9 @@
33393585 goto out;
33403586 }
33413587
3588
+ if (sdata->wdev.use_4addr)
3589
+ drv_sta_set_4addr(local, sdata, &sta->sta, true);
3590
+
33423591 mutex_unlock(&sdata->local->sta_mtx);
33433592
33443593 /*
....@@ -3348,12 +3597,13 @@
33483597 * 4-bit value.
33493598 */
33503599 ifmgd->wmm_last_param_set = -1;
3600
+ ifmgd->mu_edca_last_param_set = -1;
33513601
33523602 if (ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
33533603 ieee80211_set_wmm_default(sdata, false, false);
3354
- } else if (!ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
3355
- elems.wmm_param_len,
3356
- elems.mu_edca_param_set)) {
3604
+ } else if (!ieee80211_sta_wmm_params(local, sdata, elems->wmm_param,
3605
+ elems->wmm_param_len,
3606
+ elems->mu_edca_param_set)) {
33573607 /* still enable QoS since we might have HT/VHT */
33583608 ieee80211_set_wmm_default(sdata, false, true);
33593609 /* set the disable-WMM flag in this case to disable
....@@ -3367,11 +3617,11 @@
33673617 }
33683618 changed |= BSS_CHANGED_QOS;
33693619
3370
- if (elems.max_idle_period_ie) {
3620
+ if (elems->max_idle_period_ie) {
33713621 bss_conf->max_idle_period =
3372
- le16_to_cpu(elems.max_idle_period_ie->max_idle_period);
3622
+ le16_to_cpu(elems->max_idle_period_ie->max_idle_period);
33733623 bss_conf->protected_keep_alive =
3374
- !!(elems.max_idle_period_ie->idle_options &
3624
+ !!(elems->max_idle_period_ie->idle_options &
33753625 WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE);
33763626 changed |= BSS_CHANGED_KEEP_ALIVE;
33773627 } else {
....@@ -3379,9 +3629,8 @@
33793629 bss_conf->protected_keep_alive = false;
33803630 }
33813631
3382
- /* set AID and assoc capability,
3632
+ /* set assoc capability (AID was already set earlier),
33833633 * ieee80211_set_associated() will tell the driver */
3384
- bss_conf->aid = aid;
33853634 bss_conf->assoc_capability = capab_info;
33863635 ieee80211_set_associated(sdata, cbss, changed);
33873636
....@@ -3396,8 +3645,8 @@
33963645 * Start timer to probe the connection to the AP now.
33973646 * Also start the timer that will detect beacon loss.
33983647 */
3399
- ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
34003648 ieee80211_sta_reset_beacon_monitor(sdata);
3649
+ ieee80211_sta_reset_conn_monitor(sdata);
34013650
34023651 ret = true;
34033652 out:
....@@ -3416,7 +3665,7 @@
34163665 int ac, uapsd_queues = -1;
34173666 u8 *pos;
34183667 bool reassoc;
3419
- struct cfg80211_bss *bss;
3668
+ struct cfg80211_bss *cbss;
34203669 struct ieee80211_event event = {
34213670 .type = MLME_EVENT,
34223671 .u.mlme.data = ASSOC_EVENT,
....@@ -3426,8 +3675,11 @@
34263675
34273676 if (!assoc_data)
34283677 return;
3678
+
34293679 if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid))
34303680 return;
3681
+
3682
+ cbss = assoc_data->bss;
34313683
34323684 /*
34333685 * AssocResp and ReassocResp have identical structure, so process both
....@@ -3440,7 +3692,12 @@
34403692 reassoc = ieee80211_is_reassoc_resp(mgmt->frame_control);
34413693 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
34423694 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
3695
+ pos = mgmt->u.assoc_resp.variable;
34433696 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
3697
+ if (cbss->channel->band == NL80211_BAND_S1GHZ) {
3698
+ pos = (u8 *) mgmt->u.s1g_assoc_resp.variable;
3699
+ aid = 0; /* TODO */
3700
+ }
34443701
34453702 sdata_info(sdata,
34463703 "RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n",
....@@ -3451,8 +3708,8 @@
34513708 fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0)
34523709 return;
34533710
3454
- pos = mgmt->u.assoc_resp.variable;
3455
- ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems);
3711
+ ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems,
3712
+ mgmt->bssid, NULL);
34563713
34573714 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
34583715 elems.timeout_int &&
....@@ -3470,8 +3727,6 @@
34703727 return;
34713728 }
34723729
3473
- bss = assoc_data->bss;
3474
-
34753730 if (status_code != WLAN_STATUS_SUCCESS) {
34763731 sdata_info(sdata, "%pM denied association (code=%d)\n",
34773732 mgmt->sa, status_code);
....@@ -3480,10 +3735,10 @@
34803735 event.u.mlme.reason = status_code;
34813736 drv_event_callback(sdata->local, sdata, &event);
34823737 } else {
3483
- if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
3738
+ if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, &elems)) {
34843739 /* oops -- internal error -- send timeout for now */
34853740 ieee80211_destroy_assoc_data(sdata, false, false);
3486
- cfg80211_assoc_timeout(sdata->dev, bss);
3741
+ cfg80211_assoc_timeout(sdata->dev, cbss);
34873742 return;
34883743 }
34893744 event.u.mlme.status = MLME_SUCCESS;
....@@ -3504,13 +3759,13 @@
35043759 uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
35053760 }
35063761
3507
- cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues);
3762
+ cfg80211_rx_assoc_resp(sdata->dev, cbss, (u8 *)mgmt, len, uapsd_queues,
3763
+ ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len);
35083764 }
35093765
35103766 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
35113767 struct ieee80211_mgmt *mgmt, size_t len,
3512
- struct ieee80211_rx_status *rx_status,
3513
- struct ieee802_11_elems *elems)
3768
+ struct ieee80211_rx_status *rx_status)
35143769 {
35153770 struct ieee80211_local *local = sdata->local;
35163771 struct ieee80211_bss *bss;
....@@ -3518,12 +3773,12 @@
35183773
35193774 sdata_assert_lock(sdata);
35203775
3521
- channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
3776
+ channel = ieee80211_get_channel_khz(local->hw.wiphy,
3777
+ ieee80211_rx_status_to_khz(rx_status));
35223778 if (!channel)
35233779 return;
35243780
3525
- bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
3526
- channel);
3781
+ bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, channel);
35273782 if (bss) {
35283783 sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
35293784 ieee80211_rx_bss_put(local, bss);
....@@ -3537,24 +3792,35 @@
35373792 struct ieee80211_mgmt *mgmt = (void *)skb->data;
35383793 struct ieee80211_if_managed *ifmgd;
35393794 struct ieee80211_rx_status *rx_status = (void *) skb->cb;
3795
+ struct ieee80211_channel *channel;
35403796 size_t baselen, len = skb->len;
3541
- struct ieee802_11_elems elems;
35423797
35433798 ifmgd = &sdata->u.mgd;
35443799
35453800 sdata_assert_lock(sdata);
35463801
3547
- if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
3802
+ /*
3803
+ * According to Draft P802.11ax D6.0 clause 26.17.2.3.2:
3804
+ * "If a 6 GHz AP receives a Probe Request frame and responds with
3805
+ * a Probe Response frame [..], the Address 1 field of the Probe
3806
+ * Response frame shall be set to the broadcast address [..]"
3807
+ * So, on 6GHz band we should also accept broadcast responses.
3808
+ */
3809
+ channel = ieee80211_get_channel(sdata->local->hw.wiphy,
3810
+ rx_status->freq);
3811
+ if (!channel)
3812
+ return;
3813
+
3814
+ if (!ether_addr_equal(mgmt->da, sdata->vif.addr) &&
3815
+ (channel->band != NL80211_BAND_6GHZ ||
3816
+ !is_broadcast_ether_addr(mgmt->da)))
35483817 return; /* ignore ProbeResp to foreign address */
35493818
35503819 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
35513820 if (baselen > len)
35523821 return;
35533822
3554
- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
3555
- false, &elems);
3556
-
3557
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
3823
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status);
35583824
35593825 if (ifmgd->associated &&
35603826 ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
....@@ -3681,12 +3947,23 @@
36813947 }
36823948 }
36833949
3950
+static bool ieee80211_rx_our_beacon(const u8 *tx_bssid,
3951
+ struct cfg80211_bss *bss)
3952
+{
3953
+ if (ether_addr_equal(tx_bssid, bss->bssid))
3954
+ return true;
3955
+ if (!bss->transmitted_bss)
3956
+ return false;
3957
+ return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid);
3958
+}
3959
+
36843960 static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3685
- struct ieee80211_mgmt *mgmt, size_t len,
3961
+ struct ieee80211_hdr *hdr, size_t len,
36863962 struct ieee80211_rx_status *rx_status)
36873963 {
36883964 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
36893965 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
3966
+ struct ieee80211_mgmt *mgmt = (void *) hdr;
36903967 size_t baselen;
36913968 struct ieee802_11_elems elems;
36923969 struct ieee80211_local *local = sdata->local;
....@@ -3696,14 +3973,24 @@
36963973 u32 changed = 0;
36973974 bool erp_valid;
36983975 u8 erp_value = 0;
3699
- u32 ncrc;
3700
- u8 *bssid;
3976
+ u32 ncrc = 0;
3977
+ u8 *bssid, *variable = mgmt->u.beacon.variable;
37013978 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
37023979
37033980 sdata_assert_lock(sdata);
37043981
37053982 /* Process beacon from the current BSS */
3706
- baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
3983
+ bssid = ieee80211_get_bssid(hdr, len, sdata->vif.type);
3984
+ if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
3985
+ struct ieee80211_ext *ext = (void *) mgmt;
3986
+
3987
+ if (ieee80211_is_s1g_short_beacon(ext->frame_control))
3988
+ variable = ext->u.s1g_short_beacon.variable;
3989
+ else
3990
+ variable = ext->u.s1g_beacon.variable;
3991
+ }
3992
+
3993
+ baselen = (u8 *) variable - (u8 *) mgmt;
37073994 if (baselen > len)
37083995 return;
37093996
....@@ -3714,7 +4001,8 @@
37144001 return;
37154002 }
37164003
3717
- if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
4004
+ if (ieee80211_rx_status_to_khz(rx_status) !=
4005
+ ieee80211_channel_to_khz(chanctx_conf->def.chan)) {
37184006 rcu_read_unlock();
37194007 return;
37204008 }
....@@ -3722,15 +4010,16 @@
37224010 rcu_read_unlock();
37234011
37244012 if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
3725
- ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
3726
- ieee802_11_parse_elems(mgmt->u.beacon.variable,
3727
- len - baselen, false, &elems);
4013
+ ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) {
4014
+ ieee802_11_parse_elems(variable,
4015
+ len - baselen, false, &elems,
4016
+ bssid,
4017
+ ifmgd->assoc_data->bss->bssid);
37284018
3729
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
3730
- if (elems.tim && !elems.parse_error) {
3731
- const struct ieee80211_tim_ie *tim_ie = elems.tim;
3732
- ifmgd->dtim_period = tim_ie->dtim_period;
3733
- }
4019
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status);
4020
+
4021
+ if (elems.dtim_period)
4022
+ ifmgd->dtim_period = elems.dtim_period;
37344023 ifmgd->have_beacon = true;
37354024 ifmgd->assoc_data->need_beacon = false;
37364025 if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
....@@ -3738,21 +4027,31 @@
37384027 le64_to_cpu(mgmt->u.beacon.timestamp);
37394028 sdata->vif.bss_conf.sync_device_ts =
37404029 rx_status->device_timestamp;
3741
- if (elems.tim)
3742
- sdata->vif.bss_conf.sync_dtim_count =
3743
- elems.tim->dtim_count;
3744
- else
3745
- sdata->vif.bss_conf.sync_dtim_count = 0;
4030
+ sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count;
37464031 }
4032
+
4033
+ if (elems.mbssid_config_ie)
4034
+ bss_conf->profile_periodicity =
4035
+ elems.mbssid_config_ie->profile_periodicity;
4036
+ else
4037
+ bss_conf->profile_periodicity = 0;
4038
+
4039
+ if (elems.ext_capab_len >= 11 &&
4040
+ (elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
4041
+ bss_conf->ema_ap = true;
4042
+ else
4043
+ bss_conf->ema_ap = false;
4044
+
37474045 /* continue assoc process */
37484046 ifmgd->assoc_data->timeout = jiffies;
37494047 ifmgd->assoc_data->timeout_started = true;
37504048 run_again(sdata, ifmgd->assoc_data->timeout);
4049
+ kfree(elems.nontx_profile);
37514050 return;
37524051 }
37534052
37544053 if (!ifmgd->associated ||
3755
- !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
4054
+ !ieee80211_rx_our_beacon(bssid, ifmgd->associated))
37564055 return;
37574056 bssid = ifmgd->associated->bssid;
37584057
....@@ -3772,13 +4071,20 @@
37724071 */
37734072 ieee80211_sta_reset_beacon_monitor(sdata);
37744073
3775
- ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
3776
- ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
4074
+ /* TODO: CRC urrently not calculated on S1G Beacon Compatibility
4075
+ * element (which carries the beacon interval). Don't forget to add a
4076
+ * bit to care_about_ies[] above if mac80211 is interested in a
4077
+ * changing S1G element.
4078
+ */
4079
+ if (!ieee80211_is_s1g_beacon(hdr->frame_control))
4080
+ ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
4081
+ ncrc = ieee802_11_parse_elems_crc(variable,
37774082 len - baselen, false, &elems,
3778
- care_about_ies, ncrc);
4083
+ care_about_ies, ncrc,
4084
+ mgmt->bssid, bssid);
37794085
37804086 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
3781
- ieee80211_check_tim(elems.tim, elems.tim_len, ifmgd->aid)) {
4087
+ ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) {
37824088 if (local->hw.conf.dynamic_ps_timeout > 0) {
37834089 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
37844090 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
....@@ -3806,7 +4112,7 @@
38064112 struct ieee80211_p2p_noa_attr noa = {};
38074113 int ret;
38084114
3809
- ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
4115
+ ret = cfg80211_get_p2p_attr(variable,
38104116 len - baselen,
38114117 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
38124118 (u8 *) &noa, sizeof(noa));
....@@ -3842,24 +4148,22 @@
38424148 * the driver will use them. The synchronized view is currently
38434149 * guaranteed only in certain callbacks.
38444150 */
3845
- if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
4151
+ if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY) &&
4152
+ !ieee80211_is_s1g_beacon(hdr->frame_control)) {
38464153 sdata->vif.bss_conf.sync_tsf =
38474154 le64_to_cpu(mgmt->u.beacon.timestamp);
38484155 sdata->vif.bss_conf.sync_device_ts =
38494156 rx_status->device_timestamp;
3850
- if (elems.tim)
3851
- sdata->vif.bss_conf.sync_dtim_count =
3852
- elems.tim->dtim_count;
3853
- else
3854
- sdata->vif.bss_conf.sync_dtim_count = 0;
4157
+ sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count;
38554158 }
38564159
3857
- if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
4160
+ if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) ||
4161
+ ieee80211_is_s1g_short_beacon(mgmt->frame_control))
38584162 return;
38594163 ifmgd->beacon_crc = ncrc;
38604164 ifmgd->beacon_crc_valid = true;
38614165
3862
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
4166
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status);
38634167
38644168 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
38654169 rx_status->device_timestamp,
....@@ -3877,10 +4181,7 @@
38774181 */
38784182 if (!ifmgd->have_beacon) {
38794183 /* a few bogus AP send dtim_period = 0 or no TIM IE */
3880
- if (elems.tim)
3881
- bss_conf->dtim_period = elems.tim->dtim_period ?: 1;
3882
- else
3883
- bss_conf->dtim_period = 1;
4184
+ bss_conf->dtim_period = elems.dtim_period ?: 1;
38844185
38854186 changed |= BSS_CHANGED_BEACON_INFO;
38864187 ifmgd->have_beacon = true;
....@@ -3898,17 +4199,21 @@
38984199 } else {
38994200 erp_valid = false;
39004201 }
3901
- changed |= ieee80211_handle_bss_capability(sdata,
3902
- le16_to_cpu(mgmt->u.beacon.capab_info),
3903
- erp_valid, erp_value);
4202
+
4203
+ if (!ieee80211_is_s1g_beacon(hdr->frame_control))
4204
+ changed |= ieee80211_handle_bss_capability(sdata,
4205
+ le16_to_cpu(mgmt->u.beacon.capab_info),
4206
+ erp_valid, erp_value);
39044207
39054208 mutex_lock(&local->sta_mtx);
39064209 sta = sta_info_get(sdata, bssid);
39074210
3908
- if (ieee80211_config_bw(sdata, sta,
3909
- elems.ht_cap_elem, elems.ht_operation,
4211
+ changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
4212
+
4213
+ if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem,
4214
+ elems.vht_cap_elem, elems.ht_operation,
39104215 elems.vht_operation, elems.he_operation,
3911
- bssid, &changed)) {
4216
+ elems.s1g_oper, bssid, &changed)) {
39124217 mutex_unlock(&local->sta_mtx);
39134218 sdata_info(sdata,
39144219 "failed to follow AP %pM bandwidth change, disconnect\n",
....@@ -3919,7 +4224,7 @@
39194224 ieee80211_report_disconnect(sdata, deauth_buf,
39204225 sizeof(deauth_buf), true,
39214226 WLAN_REASON_DEAUTH_LEAVING);
3922
- return;
4227
+ goto free;
39234228 }
39244229
39254230 if (sta && elems.opmode_notif)
....@@ -3934,6 +4239,28 @@
39344239 elems.cisco_dtpc_elem);
39354240
39364241 ieee80211_bss_info_change_notify(sdata, changed);
4242
+free:
4243
+ kfree(elems.nontx_profile);
4244
+}
4245
+
4246
+void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata,
4247
+ struct sk_buff *skb)
4248
+{
4249
+ struct ieee80211_rx_status *rx_status;
4250
+ struct ieee80211_hdr *hdr;
4251
+ u16 fc;
4252
+
4253
+ rx_status = (struct ieee80211_rx_status *) skb->cb;
4254
+ hdr = (struct ieee80211_hdr *) skb->data;
4255
+ fc = le16_to_cpu(hdr->frame_control);
4256
+
4257
+ sdata_lock(sdata);
4258
+ switch (fc & IEEE80211_FCTL_STYPE) {
4259
+ case IEEE80211_STYPE_S1G_BEACON:
4260
+ ieee80211_rx_mgmt_beacon(sdata, hdr, skb->len, rx_status);
4261
+ break;
4262
+ }
4263
+ sdata_unlock(sdata);
39374264 }
39384265
39394266 void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
....@@ -3953,7 +4280,8 @@
39534280
39544281 switch (fc & IEEE80211_FCTL_STYPE) {
39554282 case IEEE80211_STYPE_BEACON:
3956
- ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
4283
+ ieee80211_rx_mgmt_beacon(sdata, (void *)mgmt,
4284
+ skb->len, rx_status);
39574285 break;
39584286 case IEEE80211_STYPE_PROBE_RESP:
39594287 ieee80211_rx_mgmt_probe_resp(sdata, skb);
....@@ -3980,9 +4308,10 @@
39804308 if (ies_len < 0)
39814309 break;
39824310
4311
+ /* CSA IE cannot be overridden, no need for BSSID */
39834312 ieee802_11_parse_elems(
39844313 mgmt->u.action.u.chan_switch.variable,
3985
- ies_len, true, &elems);
4314
+ ies_len, true, &elems, mgmt->bssid, NULL);
39864315
39874316 if (elems.parse_error)
39884317 break;
....@@ -3999,9 +4328,13 @@
39994328 if (ies_len < 0)
40004329 break;
40014330
4331
+ /*
4332
+ * extended CSA IE can't be overridden, no need for
4333
+ * BSSID
4334
+ */
40024335 ieee802_11_parse_elems(
40034336 mgmt->u.action.u.ext_chan_switch.variable,
4004
- ies_len, true, &elems);
4337
+ ies_len, true, &elems, mgmt->bssid, NULL);
40054338
40064339 if (elems.parse_error)
40074340 break;
....@@ -4212,10 +4545,10 @@
42124545
42134546 if (ifmgd->auth_data && ifmgd->auth_data->timeout_started &&
42144547 time_after(jiffies, ifmgd->auth_data->timeout)) {
4215
- if (ifmgd->auth_data->done) {
4548
+ if (ifmgd->auth_data->done || ifmgd->auth_data->waiting) {
42164549 /*
4217
- * ok ... we waited for assoc but userspace didn't,
4218
- * so let's just kill the auth data
4550
+ * ok ... we waited for assoc or continuation but
4551
+ * userspace didn't do it, so kill the auth data
42194552 */
42204553 ieee80211_destroy_auth_data(sdata, false);
42214554 } else if (ieee80211_auth(sdata)) {
....@@ -4324,6 +4657,9 @@
43244657 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
43254658 return;
43264659
4660
+ if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
4661
+ return;
4662
+
43274663 sdata->u.mgd.connection_loss = false;
43284664 ieee80211_queue_work(&sdata->local->hw,
43294665 &sdata->u.mgd.beacon_connection_loss_work);
....@@ -4335,9 +4671,28 @@
43354671 from_timer(sdata, t, u.mgd.conn_mon_timer);
43364672 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
43374673 struct ieee80211_local *local = sdata->local;
4674
+ struct sta_info *sta;
4675
+ unsigned long timeout;
43384676
43394677 if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
43404678 return;
4679
+
4680
+ sta = sta_info_get(sdata, ifmgd->bssid);
4681
+ if (!sta)
4682
+ return;
4683
+
4684
+ timeout = sta->status_stats.last_ack;
4685
+ if (time_before(sta->status_stats.last_ack, sta->rx_stats.last_rx))
4686
+ timeout = sta->rx_stats.last_rx;
4687
+ timeout += IEEE80211_CONNECTION_IDLE_TIME;
4688
+
4689
+ /* If timeout is after now, then update timer to fire at
4690
+ * the later date, but do not actually probe at this time.
4691
+ */
4692
+ if (time_is_after_jiffies(timeout)) {
4693
+ mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout));
4694
+ return;
4695
+ }
43414696
43424697 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
43434698 }
....@@ -4381,7 +4736,7 @@
43814736 * cfg80211 won't know and won't actually abort those attempts,
43824737 * thus we need to do that ourselves.
43834738 */
4384
- ieee80211_send_deauth_disassoc(sdata, bssid,
4739
+ ieee80211_send_deauth_disassoc(sdata, bssid, bssid,
43854740 IEEE80211_STYPE_DEAUTH,
43864741 WLAN_REASON_DEAUTH_LEAVING,
43874742 false, frame_buf);
....@@ -4616,8 +4971,12 @@
46164971 const struct ieee80211_ht_operation *ht_oper = NULL;
46174972 const struct ieee80211_vht_operation *vht_oper = NULL;
46184973 const struct ieee80211_he_operation *he_oper = NULL;
4974
+ const struct ieee80211_s1g_oper_ie *s1g_oper = NULL;
46194975 struct ieee80211_supported_band *sband;
46204976 struct cfg80211_chan_def chandef;
4977
+ bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
4978
+ bool is_5ghz = cbss->channel->band == NL80211_BAND_5GHZ;
4979
+ struct ieee80211_bss *bss = (void *)cbss->priv;
46214980 int ret;
46224981 u32 i;
46234982 bool have_80mhz;
....@@ -4628,10 +4987,24 @@
46284987 IEEE80211_STA_DISABLE_80P80MHZ |
46294988 IEEE80211_STA_DISABLE_160MHZ);
46304989
4990
+ /* disable HT/VHT/HE if we don't support them */
4991
+ if (!sband->ht_cap.ht_supported && !is_6ghz) {
4992
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
4993
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4994
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
4995
+ }
4996
+
4997
+ if (!sband->vht_cap.vht_supported && is_5ghz) {
4998
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
4999
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
5000
+ }
5001
+
5002
+ if (!ieee80211_get_he_sta_cap(sband))
5003
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
5004
+
46315005 rcu_read_lock();
46325006
4633
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
4634
- sband->ht_cap.ht_supported) {
5007
+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && !is_6ghz) {
46355008 const u8 *ht_oper_ie, *ht_cap_ie;
46365009
46375010 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
....@@ -4648,8 +5021,7 @@
46485021 }
46495022 }
46505023
4651
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
4652
- sband->vht_cap.vht_supported) {
5024
+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && !is_6ghz) {
46535025 const u8 *vht_oper_ie, *vht_cap;
46545026
46555027 vht_oper_ie = ieee80211_bss_get_ie(cbss,
....@@ -4659,9 +5031,10 @@
46595031 if (vht_oper && !ht_oper) {
46605032 vht_oper = NULL;
46615033 sdata_info(sdata,
4662
- "AP advertised VHT without HT, disabling both\n");
5034
+ "AP advertised VHT without HT, disabling HT/VHT/HE\n");
46635035 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
46645036 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
5037
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
46655038 }
46665039
46675040 vht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_VHT_CAPABILITY);
....@@ -4671,8 +5044,7 @@
46715044 }
46725045 }
46735046
4674
- if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
4675
- ieee80211_get_he_sta_cap(sband)) {
5047
+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) {
46765048 const struct cfg80211_bss_ies *ies;
46775049 const u8 *he_oper_ie;
46785050
....@@ -4680,7 +5052,7 @@
46805052 he_oper_ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION,
46815053 ies->data, ies->len);
46825054 if (he_oper_ie &&
4683
- he_oper_ie[1] == ieee80211_he_oper_size(&he_oper_ie[3]))
5055
+ he_oper_ie[1] >= ieee80211_he_oper_size(&he_oper_ie[3]))
46845056 he_oper = (void *)(he_oper_ie + 3);
46855057 else
46865058 he_oper = NULL;
....@@ -4703,15 +5075,34 @@
47035075 if (!have_80mhz)
47045076 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
47055077
5078
+ if (sband->band == NL80211_BAND_S1GHZ) {
5079
+ const u8 *s1g_oper_ie;
5080
+
5081
+ s1g_oper_ie = ieee80211_bss_get_ie(cbss,
5082
+ WLAN_EID_S1G_OPERATION);
5083
+ if (s1g_oper_ie && s1g_oper_ie[1] >= sizeof(*s1g_oper))
5084
+ s1g_oper = (void *)(s1g_oper_ie + 2);
5085
+ else
5086
+ sdata_info(sdata,
5087
+ "AP missing S1G operation element?\n");
5088
+ }
5089
+
47065090 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
47075091 cbss->channel,
5092
+ bss->vht_cap_info,
47085093 ht_oper, vht_oper, he_oper,
5094
+ s1g_oper,
47095095 &chandef, false);
47105096
47115097 sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
47125098 local->rx_chains);
47135099
47145100 rcu_read_unlock();
5101
+
5102
+ if (ifmgd->flags & IEEE80211_STA_DISABLE_HE && is_6ghz) {
5103
+ sdata_info(sdata, "Rejecting non-HE 6/7 GHz connection");
5104
+ return -EINVAL;
5105
+ }
47155106
47165107 /* will change later if needed */
47175108 sdata->smps_mode = IEEE80211_SMPS_OFF;
....@@ -4738,6 +5129,40 @@
47385129 out:
47395130 mutex_unlock(&local->mtx);
47405131 return ret;
5132
+}
5133
+
5134
+static bool ieee80211_get_dtim(const struct cfg80211_bss_ies *ies,
5135
+ u8 *dtim_count, u8 *dtim_period)
5136
+{
5137
+ const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len);
5138
+ const u8 *idx_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, ies->data,
5139
+ ies->len);
5140
+ const struct ieee80211_tim_ie *tim = NULL;
5141
+ const struct ieee80211_bssid_index *idx;
5142
+ bool valid = tim_ie && tim_ie[1] >= 2;
5143
+
5144
+ if (valid)
5145
+ tim = (void *)(tim_ie + 2);
5146
+
5147
+ if (dtim_count)
5148
+ *dtim_count = valid ? tim->dtim_count : 0;
5149
+
5150
+ if (dtim_period)
5151
+ *dtim_period = valid ? tim->dtim_period : 0;
5152
+
5153
+ /* Check if value is overridden by non-transmitted profile */
5154
+ if (!idx_ie || idx_ie[1] < 3)
5155
+ return valid;
5156
+
5157
+ idx = (void *)(idx_ie + 2);
5158
+
5159
+ if (dtim_count)
5160
+ *dtim_count = idx->dtim_count;
5161
+
5162
+ if (dtim_period)
5163
+ *dtim_period = idx->dtim_period;
5164
+
5165
+ return true;
47415166 }
47425167
47435168 static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
....@@ -4793,6 +5218,12 @@
47935218 const struct cfg80211_bss_ies *ies;
47945219 int shift = ieee80211_vif_get_shift(&sdata->vif);
47955220
5221
+ /* TODO: S1G Basic Rate Set is expressed elsewhere */
5222
+ if (cbss->channel->band == NL80211_BAND_S1GHZ) {
5223
+ ieee80211_s1g_sta_rate_init(new_sta);
5224
+ goto skip_rates;
5225
+ }
5226
+
47965227 ieee80211_get_rates(sband, bss->supp_rates,
47975228 bss->supp_rates_len,
47985229 &rates, &basic_rates,
....@@ -4807,14 +5238,27 @@
48075238 * doesn't happen any more, but keep the workaround so
48085239 * in case some *other* APs are buggy in different ways
48095240 * we can connect -- with a warning.
5241
+ * Allow this workaround only in case the AP provided at least
5242
+ * one rate.
48105243 */
4811
- if (!basic_rates && min_rate_index >= 0) {
5244
+ if (min_rate_index < 0) {
5245
+ sdata_info(sdata,
5246
+ "No legacy rates in association response\n");
5247
+
5248
+ sta_info_free(local, new_sta);
5249
+ return -EINVAL;
5250
+ } else if (!basic_rates) {
48125251 sdata_info(sdata,
48135252 "No basic rates, using min rate instead\n");
48145253 basic_rates = BIT(min_rate_index);
48155254 }
48165255
4817
- new_sta->sta.supp_rates[cbss->channel->band] = rates;
5256
+ if (rates)
5257
+ new_sta->sta.supp_rates[cbss->channel->band] = rates;
5258
+ else
5259
+ sdata_info(sdata,
5260
+ "No rates found, keeping mandatory only\n");
5261
+
48185262 sdata->vif.bss_conf.basic_rates = basic_rates;
48195263
48205264 /* cf. IEEE 802.11 9.2.12 */
....@@ -4824,6 +5268,7 @@
48245268 else
48255269 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
48265270
5271
+skip_rates:
48275272 memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN);
48285273
48295274 /* set timing information */
....@@ -4831,17 +5276,13 @@
48315276 rcu_read_lock();
48325277 ies = rcu_dereference(cbss->beacon_ies);
48335278 if (ies) {
4834
- const u8 *tim_ie;
4835
-
48365279 sdata->vif.bss_conf.sync_tsf = ies->tsf;
48375280 sdata->vif.bss_conf.sync_device_ts =
48385281 bss->device_ts_beacon;
4839
- tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
4840
- ies->data, ies->len);
4841
- if (tim_ie && tim_ie[1] >= 2)
4842
- sdata->vif.bss_conf.sync_dtim_count = tim_ie[2];
4843
- else
4844
- sdata->vif.bss_conf.sync_dtim_count = 0;
5282
+
5283
+ ieee80211_get_dtim(ies,
5284
+ &sdata->vif.bss_conf.sync_dtim_count,
5285
+ NULL);
48455286 } else if (!ieee80211_hw_check(&sdata->local->hw,
48465287 TIMING_BEACON_ONLY)) {
48475288 ies = rcu_dereference(cbss->proberesp_ies);
....@@ -4906,6 +5347,7 @@
49065347 struct ieee80211_mgd_auth_data *auth_data;
49075348 u16 auth_alg;
49085349 int err;
5350
+ bool cont_auth;
49095351
49105352 /* prepare auth data structure */
49115353
....@@ -4914,7 +5356,7 @@
49145356 auth_alg = WLAN_AUTH_OPEN;
49155357 break;
49165358 case NL80211_AUTHTYPE_SHARED_KEY:
4917
- if (IS_ERR(local->wep_tx_tfm))
5359
+ if (fips_enabled)
49185360 return -EOPNOTSUPP;
49195361 auth_alg = WLAN_AUTH_SHARED_KEY;
49205362 break;
....@@ -4940,6 +5382,9 @@
49405382 return -EOPNOTSUPP;
49415383 }
49425384
5385
+ if (ifmgd->assoc_data)
5386
+ return -EBUSY;
5387
+
49435388 auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
49445389 req->ie_len, GFP_KERNEL);
49455390 if (!auth_data)
....@@ -4959,6 +5404,13 @@
49595404 auth_data->data_len += req->auth_data_len - 4;
49605405 }
49615406
5407
+ /* Check if continuing authentication or trying to authenticate with the
5408
+ * same BSS that we were in the process of authenticating with and avoid
5409
+ * removal and re-addition of the STA entry in
5410
+ * ieee80211_prep_connection().
5411
+ */
5412
+ cont_auth = ifmgd->auth_data && req->bss == ifmgd->auth_data->bss;
5413
+
49625414 if (req->ie && req->ie_len) {
49635415 memcpy(&auth_data->data[auth_data->data_len],
49645416 req->ie, req->ie_len);
....@@ -4975,17 +5427,25 @@
49755427
49765428 /* try to authenticate/probe */
49775429
4978
- if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
4979
- ifmgd->assoc_data) {
4980
- err = -EBUSY;
4981
- goto err_free;
5430
+ if (ifmgd->auth_data) {
5431
+ if (cont_auth && req->auth_type == NL80211_AUTHTYPE_SAE) {
5432
+ auth_data->peer_confirmed =
5433
+ ifmgd->auth_data->peer_confirmed;
5434
+ }
5435
+ ieee80211_destroy_auth_data(sdata, cont_auth);
49825436 }
4983
-
4984
- if (ifmgd->auth_data)
4985
- ieee80211_destroy_auth_data(sdata, false);
49865437
49875438 /* prep auth_data so we don't go into idle on disassoc */
49885439 ifmgd->auth_data = auth_data;
5440
+
5441
+ /* If this is continuation of an ongoing SAE authentication exchange
5442
+ * (i.e., request to send SAE Confirm) and the peer has already
5443
+ * confirmed, mark authentication completed since we are about to send
5444
+ * out SAE Confirm.
5445
+ */
5446
+ if (cont_auth && req->auth_type == NL80211_AUTHTYPE_SAE &&
5447
+ auth_data->peer_confirmed && auth_data->sae_trans == 2)
5448
+ ieee80211_mark_sta_auth(sdata, req->bss->bssid);
49895449
49905450 if (ifmgd->associated) {
49915451 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
....@@ -5004,7 +5464,7 @@
50045464
50055465 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
50065466
5007
- err = ieee80211_prep_connection(sdata, req->bss, false, false);
5467
+ err = ieee80211_prep_connection(sdata, req->bss, cont_auth, false);
50085468 if (err)
50095469 goto err_clear;
50105470
....@@ -5025,7 +5485,6 @@
50255485 mutex_lock(&sdata->local->mtx);
50265486 ieee80211_vif_release_channel(sdata);
50275487 mutex_unlock(&sdata->local->mtx);
5028
- err_free:
50295488 kfree(auth_data);
50305489 return err;
50315490 }
....@@ -5033,6 +5492,8 @@
50335492 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
50345493 struct cfg80211_assoc_request *req)
50355494 {
5495
+ bool is_6ghz = req->bss->channel->band == NL80211_BAND_6GHZ;
5496
+ bool is_5ghz = req->bss->channel->band == NL80211_BAND_5GHZ;
50365497 struct ieee80211_local *local = sdata->local;
50375498 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
50385499 struct ieee80211_bss *bss = (void *)req->bss->priv;
....@@ -5113,31 +5574,19 @@
51135574 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
51145575 ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
51155576 netdev_info(sdata->dev,
5116
- "disabling HE/HT/VHT due to WEP/TKIP use\n");
5577
+ "disabling HT/VHT/HE due to WEP/TKIP use\n");
51175578 }
51185579 }
51195580
5120
- /* Also disable HT if we don't support it or the AP doesn't use WMM */
51215581 sband = local->hw.wiphy->bands[req->bss->channel->band];
5122
- if (!sband->ht_cap.ht_supported ||
5123
- local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
5124
- ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
5125
- ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
5126
- if (!bss->wmm_used &&
5127
- !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
5128
- netdev_info(sdata->dev,
5129
- "disabling HT as WMM/QoS is not supported by the AP\n");
5130
- }
51315582
5132
- /* disable VHT if we don't support it or the AP doesn't use WMM */
5133
- if (!sband->vht_cap.vht_supported ||
5134
- local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
5135
- ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
5583
+ /* also disable HT/VHT/HE if the AP doesn't use WMM */
5584
+ if (!bss->wmm_used) {
5585
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
51365586 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
5137
- if (!bss->wmm_used &&
5138
- !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
5139
- netdev_info(sdata->dev,
5140
- "disabling VHT as WMM/QoS is not supported by the AP\n");
5587
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
5588
+ netdev_info(sdata->dev,
5589
+ "disabling HT/VHT/HE as WMM/QoS is not supported by the AP\n");
51415590 }
51425591
51435592 memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
....@@ -5147,6 +5596,10 @@
51475596 memcpy(&ifmgd->vht_capa, &req->vht_capa, sizeof(ifmgd->vht_capa));
51485597 memcpy(&ifmgd->vht_capa_mask, &req->vht_capa_mask,
51495598 sizeof(ifmgd->vht_capa_mask));
5599
+
5600
+ memcpy(&ifmgd->s1g_capa, &req->s1g_capa, sizeof(ifmgd->s1g_capa));
5601
+ memcpy(&ifmgd->s1g_capa_mask, &req->s1g_capa_mask,
5602
+ sizeof(ifmgd->s1g_capa_mask));
51505603
51515604 if (req->ie && req->ie_len) {
51525605 memcpy(assoc_data->ie, req->ie, req->ie_len);
....@@ -5187,14 +5640,15 @@
51875640 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation))
51885641 assoc_data->ap_ht_param =
51895642 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
5190
- else
5643
+ else if (!is_6ghz)
51915644 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
51925645 vht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_VHT_CAPABILITY);
51935646 if (vht_ie && vht_ie[1] >= sizeof(struct ieee80211_vht_cap))
51945647 memcpy(&assoc_data->ap_vht_cap, vht_ie + 2,
51955648 sizeof(struct ieee80211_vht_cap));
5196
- else
5197
- ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
5649
+ else if (is_5ghz)
5650
+ ifmgd->flags |= IEEE80211_STA_DISABLE_VHT |
5651
+ IEEE80211_STA_DISABLE_HE;
51985652 rcu_read_unlock();
51995653
52005654 if (WARN((sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD) &&
....@@ -5236,6 +5690,7 @@
52365690 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
52375691 sdata->control_port_over_nl80211 =
52385692 req->crypto.control_port_over_nl80211;
5693
+ sdata->control_port_no_preauth = req->crypto.control_port_no_preauth;
52395694 sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto,
52405695 sdata->vif.type);
52415696
....@@ -5269,6 +5724,7 @@
52695724 if (req->flags & ASSOC_REQ_DISABLE_HT) {
52705725 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
52715726 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
5727
+ ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
52725728 }
52735729
52745730 if (req->flags & ASSOC_REQ_DISABLE_VHT)
....@@ -5293,17 +5749,12 @@
52935749 assoc_data->timeout_started = true;
52945750 assoc_data->need_beacon = true;
52955751 } else if (beacon_ies) {
5296
- const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
5297
- beacon_ies->data,
5298
- beacon_ies->len);
5752
+ const struct element *elem;
52995753 u8 dtim_count = 0;
53005754
5301
- if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) {
5302
- const struct ieee80211_tim_ie *tim;
5303
- tim = (void *)(tim_ie + 2);
5304
- ifmgd->dtim_period = tim->dtim_period;
5305
- dtim_count = tim->dtim_count;
5306
- }
5755
+ ieee80211_get_dtim(beacon_ies, &dtim_count,
5756
+ &ifmgd->dtim_period);
5757
+
53075758 ifmgd->have_beacon = true;
53085759 assoc_data->timeout = jiffies;
53095760 assoc_data->timeout_started = true;
....@@ -5314,6 +5765,21 @@
53145765 bss->device_ts_beacon;
53155766 sdata->vif.bss_conf.sync_dtim_count = dtim_count;
53165767 }
5768
+
5769
+ elem = cfg80211_find_ext_elem(WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION,
5770
+ beacon_ies->data, beacon_ies->len);
5771
+ if (elem && elem->datalen >= 3)
5772
+ sdata->vif.bss_conf.profile_periodicity = elem->data[2];
5773
+ else
5774
+ sdata->vif.bss_conf.profile_periodicity = 0;
5775
+
5776
+ elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
5777
+ beacon_ies->data, beacon_ies->len);
5778
+ if (elem && elem->datalen >= 11 &&
5779
+ (elem->data[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
5780
+ sdata->vif.bss_conf.ema_ap = true;
5781
+ else
5782
+ sdata->vif.bss_conf.ema_ap = false;
53175783 } else {
53185784 assoc_data->timeout = jiffies;
53195785 assoc_data->timeout_started = true;
....@@ -5361,7 +5827,7 @@
53615827 ieee80211_get_reason_code_string(req->reason_code));
53625828
53635829 drv_mgd_prepare_tx(sdata->local, sdata, 0);
5364
- ieee80211_send_deauth_disassoc(sdata, req->bssid,
5830
+ ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
53655831 IEEE80211_STYPE_DEAUTH,
53665832 req->reason_code, tx,
53675833 frame_buf);
....@@ -5381,7 +5847,7 @@
53815847 ieee80211_get_reason_code_string(req->reason_code));
53825848
53835849 drv_mgd_prepare_tx(sdata->local, sdata, 0);
5384
- ieee80211_send_deauth_disassoc(sdata, req->bssid,
5850
+ ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
53855851 IEEE80211_STYPE_DEAUTH,
53865852 req->reason_code, tx,
53875853 frame_buf);
....@@ -5471,6 +5937,9 @@
54715937 ifmgd->teardown_skb = NULL;
54725938 ifmgd->orig_teardown_skb = NULL;
54735939 }
5940
+ kfree(ifmgd->assoc_req_ies);
5941
+ ifmgd->assoc_req_ies = NULL;
5942
+ ifmgd->assoc_req_ies_len = 0;
54745943 spin_unlock_bh(&ifmgd->teardown_lock);
54755944 del_timer_sync(&ifmgd->timer);
54765945 sdata_unlock(sdata);