hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/net/mac80211/vht.c
....@@ -1,12 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * VHT handling
34 *
45 * Portions of this file
56 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
7
+ * Copyright (C) 2018 - 2020 Intel Corporation
108 */
119
1210 #include <linux/ieee80211.h>
....@@ -231,6 +229,13 @@
231229 memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs,
232230 sizeof(struct ieee80211_vht_mcs_info));
233231
232
+ /* copy EXT_NSS_BW Support value or remove the capability */
233
+ if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_VHT_EXT_NSS_BW))
234
+ vht_cap->cap |= (cap_info & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
235
+ else
236
+ vht_cap->vht_mcs.tx_highest &=
237
+ ~cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
238
+
234239 /* but also restrict MCSes */
235240 for (i = 0; i < 8; i++) {
236241 u16 own_rx, own_tx, peer_rx, peer_tx;
....@@ -294,13 +299,21 @@
294299 break;
295300 default:
296301 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80;
302
+
303
+ if (!(vht_cap->vht_mcs.tx_highest &
304
+ cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE)))
305
+ break;
306
+
307
+ /*
308
+ * If this is non-zero, then it does support 160 MHz after all,
309
+ * in one form or the other. We don't distinguish here (or even
310
+ * above) between 160 and 80+80 yet.
311
+ */
312
+ if (cap_info & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)
313
+ sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160;
297314 }
298315
299316 sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
300
-
301
- /* If HT IE reported 3839 bytes only, stay with that size. */
302
- if (sta->sta.max_amsdu_len == IEEE80211_MAX_MPDU_LEN_HT_3839)
303
- return;
304317
305318 switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
306319 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
....@@ -316,10 +329,32 @@
316329 }
317330 }
318331
332
+/* FIXME: move this to some better location - parses HE now */
319333 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta)
320334 {
321335 struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
336
+ struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap;
322337 u32 cap_width;
338
+
339
+ if (he_cap->has_he) {
340
+ u8 info = he_cap->he_cap_elem.phy_cap_info[0];
341
+
342
+ if (sta->sdata->vif.bss_conf.chandef.chan->band ==
343
+ NL80211_BAND_2GHZ) {
344
+ if (info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G)
345
+ return IEEE80211_STA_RX_BW_40;
346
+ else
347
+ return IEEE80211_STA_RX_BW_20;
348
+ }
349
+
350
+ if (info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G ||
351
+ info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
352
+ return IEEE80211_STA_RX_BW_160;
353
+ else if (info & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)
354
+ return IEEE80211_STA_RX_BW_80;
355
+
356
+ return IEEE80211_STA_RX_BW_20;
357
+ }
323358
324359 if (!vht_cap->vht_supported)
325360 return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
....@@ -330,6 +365,14 @@
330365
331366 if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
332367 cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
368
+ return IEEE80211_STA_RX_BW_160;
369
+
370
+ /*
371
+ * If this is non-zero, then it does support 160 MHz after all,
372
+ * in one form or the other. We don't distinguish here (or even
373
+ * above) between 160 and 80+80 yet.
374
+ */
375
+ if (vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)
333376 return IEEE80211_STA_RX_BW_160;
334377
335378 return IEEE80211_STA_RX_BW_80;
....@@ -408,6 +451,7 @@
408451 }
409452 }
410453
454
+/* FIXME: rename/move - this deals with everything not just VHT */
411455 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta)
412456 {
413457 struct ieee80211_sub_if_data *sdata = sta->sdata;
....@@ -439,11 +483,39 @@
439483
440484 void ieee80211_sta_set_rx_nss(struct sta_info *sta)
441485 {
442
- u8 ht_rx_nss = 0, vht_rx_nss = 0;
486
+ u8 ht_rx_nss = 0, vht_rx_nss = 0, he_rx_nss = 0, rx_nss;
443487
444488 /* if we received a notification already don't overwrite it */
445489 if (sta->sta.rx_nss)
446490 return;
491
+
492
+ if (sta->sta.he_cap.has_he) {
493
+ int i;
494
+ u8 rx_mcs_80 = 0, rx_mcs_160 = 0;
495
+ const struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap;
496
+ u16 mcs_160_map =
497
+ le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
498
+ u16 mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
499
+
500
+ for (i = 7; i >= 0; i--) {
501
+ u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3;
502
+
503
+ if (mcs_160 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
504
+ rx_mcs_160 = i + 1;
505
+ break;
506
+ }
507
+ }
508
+ for (i = 7; i >= 0; i--) {
509
+ u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3;
510
+
511
+ if (mcs_80 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
512
+ rx_mcs_80 = i + 1;
513
+ break;
514
+ }
515
+ }
516
+
517
+ he_rx_nss = min(rx_mcs_80, rx_mcs_160);
518
+ }
447519
448520 if (sta->sta.ht_cap.ht_supported) {
449521 if (sta->sta.ht_cap.mcs.rx_mask[0])
....@@ -474,8 +546,9 @@
474546 /* FIXME: consider rx_highest? */
475547 }
476548
477
- ht_rx_nss = max(ht_rx_nss, vht_rx_nss);
478
- sta->sta.rx_nss = max_t(u8, 1, ht_rx_nss);
549
+ rx_nss = max(vht_rx_nss, ht_rx_nss);
550
+ rx_nss = max(he_rx_nss, rx_nss);
551
+ sta->sta.rx_nss = max_t(u8, 1, rx_nss);
479552 }
480553
481554 u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
....@@ -504,15 +577,21 @@
504577
505578 switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
506579 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
580
+ /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */
507581 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
508582 break;
509583 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ:
584
+ /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */
510585 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_40;
511586 break;
512587 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ:
513
- sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80;
588
+ if (opmode & IEEE80211_OPMODE_NOTIF_BW_160_80P80)
589
+ sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160;
590
+ else
591
+ sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80;
514592 break;
515593 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ:
594
+ /* legacy only, no longer used by newer spec */
516595 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160;
517596 break;
518597 }