hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/wireless/util.c
....@@ -5,17 +5,21 @@
55 * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
66 * Copyright 2013-2014 Intel Mobile Communications GmbH
77 * Copyright 2017 Intel Deutschland GmbH
8
+ * Copyright (C) 2018-2020 Intel Corporation
89 */
910 #include <linux/export.h>
1011 #include <linux/bitops.h>
1112 #include <linux/etherdevice.h>
1213 #include <linux/slab.h>
14
+#include <linux/ieee80211.h>
1315 #include <net/cfg80211.h>
1416 #include <net/ip.h>
1517 #include <net/dsfield.h>
1618 #include <linux/if_vlan.h>
1719 #include <linux/mpls.h>
1820 #include <linux/gcd.h>
21
+#include <linux/bitfield.h>
22
+#include <linux/nospec.h>
1923 #include "core.h"
2024 #include "rdev-ops.h"
2125
....@@ -68,7 +72,7 @@
6872 }
6973 EXPORT_SYMBOL(ieee80211_mandatory_rates);
7074
71
-int ieee80211_channel_to_frequency(int chan, enum nl80211_band band)
75
+u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
7276 {
7377 /* see 802.11 17.3.8.3.2 and Annex J
7478 * there are overlapping channel numbers in 5GHz and 2GHz bands */
....@@ -77,29 +81,68 @@
7781 switch (band) {
7882 case NL80211_BAND_2GHZ:
7983 if (chan == 14)
80
- return 2484;
84
+ return MHZ_TO_KHZ(2484);
8185 else if (chan < 14)
82
- return 2407 + chan * 5;
86
+ return MHZ_TO_KHZ(2407 + chan * 5);
8387 break;
8488 case NL80211_BAND_5GHZ:
8589 if (chan >= 182 && chan <= 196)
86
- return 4000 + chan * 5;
90
+ return MHZ_TO_KHZ(4000 + chan * 5);
8791 else
88
- return 5000 + chan * 5;
92
+ return MHZ_TO_KHZ(5000 + chan * 5);
93
+ break;
94
+ case NL80211_BAND_6GHZ:
95
+ /* see 802.11ax D6.1 27.3.23.2 */
96
+ if (chan == 2)
97
+ return MHZ_TO_KHZ(5935);
98
+ if (chan <= 233)
99
+ return MHZ_TO_KHZ(5950 + chan * 5);
89100 break;
90101 case NL80211_BAND_60GHZ:
91
- if (chan < 5)
92
- return 56160 + chan * 2160;
102
+ if (chan < 7)
103
+ return MHZ_TO_KHZ(56160 + chan * 2160);
93104 break;
105
+ case NL80211_BAND_S1GHZ:
106
+ return 902000 + chan * 500;
94107 default:
95108 ;
96109 }
97110 return 0; /* not supported */
98111 }
99
-EXPORT_SYMBOL(ieee80211_channel_to_frequency);
112
+EXPORT_SYMBOL(ieee80211_channel_to_freq_khz);
100113
101
-int ieee80211_frequency_to_channel(int freq)
114
+enum nl80211_chan_width
115
+ieee80211_s1g_channel_width(const struct ieee80211_channel *chan)
102116 {
117
+ if (WARN_ON(!chan || chan->band != NL80211_BAND_S1GHZ))
118
+ return NL80211_CHAN_WIDTH_20_NOHT;
119
+
120
+ /*S1G defines a single allowed channel width per channel.
121
+ * Extract that width here.
122
+ */
123
+ if (chan->flags & IEEE80211_CHAN_1MHZ)
124
+ return NL80211_CHAN_WIDTH_1;
125
+ else if (chan->flags & IEEE80211_CHAN_2MHZ)
126
+ return NL80211_CHAN_WIDTH_2;
127
+ else if (chan->flags & IEEE80211_CHAN_4MHZ)
128
+ return NL80211_CHAN_WIDTH_4;
129
+ else if (chan->flags & IEEE80211_CHAN_8MHZ)
130
+ return NL80211_CHAN_WIDTH_8;
131
+ else if (chan->flags & IEEE80211_CHAN_16MHZ)
132
+ return NL80211_CHAN_WIDTH_16;
133
+
134
+ pr_err("unknown channel width for channel at %dKHz?\n",
135
+ ieee80211_channel_to_khz(chan));
136
+
137
+ return NL80211_CHAN_WIDTH_1;
138
+}
139
+EXPORT_SYMBOL(ieee80211_s1g_channel_width);
140
+
141
+int ieee80211_freq_khz_to_channel(u32 freq)
142
+{
143
+ /* TODO: just handle MHz for now */
144
+ freq = KHZ_TO_MHZ(freq);
145
+
103146 /* see 802.11 17.3.8.3.2 and Annex J */
104147 if (freq == 2484)
105148 return 14;
....@@ -107,16 +150,22 @@
107150 return (freq - 2407) / 5;
108151 else if (freq >= 4910 && freq <= 4980)
109152 return (freq - 4000) / 5;
110
- else if (freq <= 45000) /* DMG band lower limit */
153
+ else if (freq < 5925)
111154 return (freq - 5000) / 5;
112
- else if (freq >= 58320 && freq <= 64800)
155
+ else if (freq == 5935)
156
+ return 2;
157
+ else if (freq <= 45000) /* DMG band lower limit */
158
+ /* see 802.11ax D6.1 27.3.22.2 */
159
+ return (freq - 5950) / 5;
160
+ else if (freq >= 58320 && freq <= 70200)
113161 return (freq - 56160) / 2160;
114162 else
115163 return 0;
116164 }
117
-EXPORT_SYMBOL(ieee80211_frequency_to_channel);
165
+EXPORT_SYMBOL(ieee80211_freq_khz_to_channel);
118166
119
-struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq)
167
+struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy,
168
+ u32 freq)
120169 {
121170 enum nl80211_band band;
122171 struct ieee80211_supported_band *sband;
....@@ -129,14 +178,16 @@
129178 continue;
130179
131180 for (i = 0; i < sband->n_channels; i++) {
132
- if (sband->channels[i].center_freq == freq)
133
- return &sband->channels[i];
181
+ struct ieee80211_channel *chan = &sband->channels[i];
182
+
183
+ if (ieee80211_channel_to_khz(chan) == freq)
184
+ return chan;
134185 }
135186 }
136187
137188 return NULL;
138189 }
139
-EXPORT_SYMBOL(ieee80211_get_channel);
190
+EXPORT_SYMBOL(ieee80211_get_channel_khz);
140191
141192 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband)
142193 {
....@@ -144,6 +195,7 @@
144195
145196 switch (sband->band) {
146197 case NL80211_BAND_5GHZ:
198
+ case NL80211_BAND_6GHZ:
147199 want = 3;
148200 for (i = 0; i < sband->n_bitrates; i++) {
149201 if (sband->bitrates[i].bitrate == 60 ||
....@@ -175,7 +227,7 @@
175227 sband->bitrates[i].flags |=
176228 IEEE80211_RATE_MANDATORY_G;
177229 want--;
178
- /* fall through */
230
+ fallthrough;
179231 default:
180232 sband->bitrates[i].flags |=
181233 IEEE80211_RATE_ERP_G;
....@@ -188,6 +240,12 @@
188240 /* check for mandatory HT MCS 1..4 */
189241 WARN_ON(!sband->ht_cap.ht_supported);
190242 WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e);
243
+ break;
244
+ case NL80211_BAND_S1GHZ:
245
+ /* Figure 9-589bd: 3 means unsupported, so != 3 means at least
246
+ * mandatory is ok.
247
+ */
248
+ WARN_ON((sband->s1g_cap.nss_mcs[0] & 0x3) == 0x3);
191249 break;
192250 case NUM_NL80211_BANDS:
193251 default:
....@@ -241,7 +299,9 @@
241299 if (pairwise)
242300 max_key_idx = 3;
243301 else if (wiphy_ext_feature_isset(&rdev->wiphy,
244
- NL80211_EXT_FEATURE_BEACON_PROTECTION))
302
+ NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
303
+ wiphy_ext_feature_isset(&rdev->wiphy,
304
+ NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
245305 max_key_idx = 7;
246306 else if (cfg80211_igtk_cipher_supported(rdev))
247307 max_key_idx = 5;
....@@ -269,18 +329,32 @@
269329
270330 switch (params->cipher) {
271331 case WLAN_CIPHER_SUITE_TKIP:
332
+ /* Extended Key ID can only be used with CCMP/GCMP ciphers */
333
+ if ((pairwise && key_idx) ||
334
+ params->mode != NL80211_KEY_RX_TX)
335
+ return -EINVAL;
336
+ break;
272337 case WLAN_CIPHER_SUITE_CCMP:
273338 case WLAN_CIPHER_SUITE_CCMP_256:
274339 case WLAN_CIPHER_SUITE_GCMP:
275340 case WLAN_CIPHER_SUITE_GCMP_256:
276
- /* Disallow pairwise keys with non-zero index unless it's WEP
277
- * or a vendor specific cipher (because current deployments use
278
- * pairwise WEP keys with non-zero indices and for vendor
279
- * specific ciphers this should be validated in the driver or
280
- * hardware level - but 802.11i clearly specifies to use zero)
341
+ /* IEEE802.11-2016 allows only 0 and - when supporting
342
+ * Extended Key ID - 1 as index for pairwise keys.
343
+ * @NL80211_KEY_NO_TX is only allowed for pairwise keys when
344
+ * the driver supports Extended Key ID.
345
+ * @NL80211_KEY_SET_TX can't be set when installing and
346
+ * validating a key.
281347 */
282
- if (pairwise && key_idx)
348
+ if ((params->mode == NL80211_KEY_NO_TX && !pairwise) ||
349
+ params->mode == NL80211_KEY_SET_TX)
283350 return -EINVAL;
351
+ if (wiphy_ext_feature_isset(&rdev->wiphy,
352
+ NL80211_EXT_FEATURE_EXT_KEY_ID)) {
353
+ if (pairwise && (key_idx < 0 || key_idx > 1))
354
+ return -EINVAL;
355
+ } else if (pairwise && key_idx) {
356
+ return -EINVAL;
357
+ }
284358 break;
285359 case WLAN_CIPHER_SUITE_AES_CMAC:
286360 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
....@@ -386,6 +460,11 @@
386460 unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc)
387461 {
388462 unsigned int hdrlen = 24;
463
+
464
+ if (ieee80211_is_ext(fc)) {
465
+ hdrlen = 4;
466
+ goto out;
467
+ }
389468
390469 if (ieee80211_is_data(fc)) {
391470 if (ieee80211_has_a4(fc))
....@@ -755,20 +834,25 @@
755834 {
756835 unsigned int dscp;
757836 unsigned char vlan_priority;
837
+ unsigned int ret;
758838
759839 /* skb->priority values from 256->263 are magic values to
760840 * directly indicate a specific 802.1d priority. This is used
761841 * to allow 802.1d priority to be passed directly in from VLAN
762842 * tags, etc.
763843 */
764
- if (skb->priority >= 256 && skb->priority <= 263)
765
- return skb->priority - 256;
844
+ if (skb->priority >= 256 && skb->priority <= 263) {
845
+ ret = skb->priority - 256;
846
+ goto out;
847
+ }
766848
767849 if (skb_vlan_tag_present(skb)) {
768850 vlan_priority = (skb_vlan_tag_get(skb) & VLAN_PRIO_MASK)
769851 >> VLAN_PRIO_SHIFT;
770
- if (vlan_priority > 0)
771
- return vlan_priority;
852
+ if (vlan_priority > 0) {
853
+ ret = vlan_priority;
854
+ goto out;
855
+ }
772856 }
773857
774858 switch (skb->protocol) {
....@@ -787,8 +871,9 @@
787871 if (!mpls)
788872 return 0;
789873
790
- return (ntohl(mpls->entry) & MPLS_LS_TC_MASK)
874
+ ret = (ntohl(mpls->entry) & MPLS_LS_TC_MASK)
791875 >> MPLS_LS_TC_SHIFT;
876
+ goto out;
792877 }
793878 case htons(ETH_P_80221):
794879 /* 802.21 is always network control traffic */
....@@ -801,22 +886,28 @@
801886 unsigned int i, tmp_dscp = dscp >> 2;
802887
803888 for (i = 0; i < qos_map->num_des; i++) {
804
- if (tmp_dscp == qos_map->dscp_exception[i].dscp)
805
- return qos_map->dscp_exception[i].up;
889
+ if (tmp_dscp == qos_map->dscp_exception[i].dscp) {
890
+ ret = qos_map->dscp_exception[i].up;
891
+ goto out;
892
+ }
806893 }
807894
808895 for (i = 0; i < 8; i++) {
809896 if (tmp_dscp >= qos_map->up[i].low &&
810
- tmp_dscp <= qos_map->up[i].high)
811
- return i;
897
+ tmp_dscp <= qos_map->up[i].high) {
898
+ ret = i;
899
+ goto out;
900
+ }
812901 }
813902 }
814903
815
- return dscp >> 5;
904
+ ret = dscp >> 5;
905
+out:
906
+ return array_index_nospec(ret, IEEE80211_NUM_TIDS);
816907 }
817908 EXPORT_SYMBOL(cfg80211_classify8021d);
818909
819
-const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
910
+const struct element *ieee80211_bss_get_elem(struct cfg80211_bss *bss, u8 id)
820911 {
821912 const struct cfg80211_bss_ies *ies;
822913
....@@ -824,9 +915,9 @@
824915 if (!ies)
825916 return NULL;
826917
827
- return cfg80211_find_ie(ie, ies->data, ies->len);
918
+ return cfg80211_find_elem(id, ies->data, ies->len);
828919 }
829
-EXPORT_SYMBOL(ieee80211_bss_get_ie);
920
+EXPORT_SYMBOL(ieee80211_bss_get_elem);
830921
831922 void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
832923 {
....@@ -852,7 +943,7 @@
852943 }
853944 }
854945
855
- kzfree(wdev->connect_keys);
946
+ kfree_sensitive(wdev->connect_keys);
856947 wdev->connect_keys = NULL;
857948 }
858949
....@@ -937,14 +1028,14 @@
9371028 !(rdev->wiphy.interface_modes & (1 << ntype)))
9381029 return -EOPNOTSUPP;
9391030
940
- /* if it's part of a bridge, reject changing type to station/ibss */
941
- if ((dev->priv_flags & IFF_BRIDGE_PORT) &&
942
- (ntype == NL80211_IFTYPE_ADHOC ||
943
- ntype == NL80211_IFTYPE_STATION ||
944
- ntype == NL80211_IFTYPE_P2P_CLIENT))
945
- return -EBUSY;
946
-
9471031 if (ntype != otype) {
1032
+ /* if it's part of a bridge, reject changing type to station/ibss */
1033
+ if (netif_is_bridge_port(dev) &&
1034
+ (ntype == NL80211_IFTYPE_ADHOC ||
1035
+ ntype == NL80211_IFTYPE_STATION ||
1036
+ ntype == NL80211_IFTYPE_P2P_CLIENT))
1037
+ return -EBUSY;
1038
+
9481039 dev->ieee80211_ptr->use_4addr = false;
9491040 dev->ieee80211_ptr->mesh_id_up_len = 0;
9501041 wdev_lock(dev->ieee80211_ptr);
....@@ -993,7 +1084,7 @@
9931084 case NL80211_IFTYPE_STATION:
9941085 if (dev->ieee80211_ptr->use_4addr)
9951086 break;
996
- /* fall through */
1087
+ fallthrough;
9971088 case NL80211_IFTYPE_OCB:
9981089 case NL80211_IFTYPE_P2P_CLIENT:
9991090 case NL80211_IFTYPE_ADHOC:
....@@ -1227,20 +1318,22 @@
12271318
12281319 static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
12291320 {
1230
-#define SCALE 2048
1231
- u16 mcs_divisors[12] = {
1232
- 34133, /* 16.666666... */
1233
- 17067, /* 8.333333... */
1234
- 11378, /* 5.555555... */
1235
- 8533, /* 4.166666... */
1236
- 5689, /* 2.777777... */
1237
- 4267, /* 2.083333... */
1238
- 3923, /* 1.851851... */
1239
- 3413, /* 1.666666... */
1240
- 2844, /* 1.388888... */
1241
- 2560, /* 1.250000... */
1242
- 2276, /* 1.111111... */
1243
- 2048, /* 1.000000... */
1321
+#define SCALE 6144
1322
+ u32 mcs_divisors[14] = {
1323
+ 102399, /* 16.666666... */
1324
+ 51201, /* 8.333333... */
1325
+ 34134, /* 5.555555... */
1326
+ 25599, /* 4.166666... */
1327
+ 17067, /* 2.777777... */
1328
+ 12801, /* 2.083333... */
1329
+ 11769, /* 1.851851... */
1330
+ 10239, /* 1.666666... */
1331
+ 8532, /* 1.388888... */
1332
+ 7680, /* 1.250000... */
1333
+ 6828, /* 1.111111... */
1334
+ 6144, /* 1.000000... */
1335
+ 5690, /* 0.926106... */
1336
+ 5120, /* 0.833333... */
12441337 };
12451338 u32 rates_160M[3] = { 960777777, 907400000, 816666666 };
12461339 u32 rates_969[3] = { 480388888, 453700000, 408333333 };
....@@ -1252,7 +1345,7 @@
12521345 u64 tmp;
12531346 u32 result;
12541347
1255
- if (WARN_ON_ONCE(rate->mcs > 11))
1348
+ if (WARN_ON_ONCE(rate->mcs > 13))
12561349 return 0;
12571350
12581351 if (WARN_ON_ONCE(rate->he_gi > NL80211_RATE_INFO_HE_GI_3_2))
....@@ -1286,9 +1379,11 @@
12861379 else if (rate->bw == RATE_INFO_BW_HE_RU &&
12871380 rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26)
12881381 result = rates_26[rate->he_gi];
1289
- else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
1290
- rate->bw, rate->he_ru_alloc))
1382
+ else {
1383
+ WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
1384
+ rate->bw, rate->he_ru_alloc);
12911385 return 0;
1386
+ }
12921387
12931388 /* now scale to the appropriate MCS */
12941389 tmp = result;
....@@ -1523,6 +1618,9 @@
15231618 case 128 ... 130:
15241619 *band = NL80211_BAND_5GHZ;
15251620 return true;
1621
+ case 131 ... 135:
1622
+ *band = NL80211_BAND_6GHZ;
1623
+ return true;
15261624 case 81:
15271625 case 82:
15281626 case 83:
....@@ -1562,7 +1660,8 @@
15621660 }
15631661
15641662 if (freq == 2484) {
1565
- if (chandef->width > NL80211_CHAN_WIDTH_40)
1663
+ /* channel 14 is only for IEEE 802.11b */
1664
+ if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
15661665 return false;
15671666
15681667 *op_class = 82; /* channel 14 */
....@@ -1654,7 +1753,7 @@
16541753 }
16551754
16561755 /* 56.16 GHz, channel 1..4 */
1657
- if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
1756
+ if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
16581757 if (chandef->width >= NL80211_CHAN_WIDTH_40)
16591758 return false;
16601759
....@@ -1980,29 +2079,6 @@
19802079 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
19812080 EXPORT_SYMBOL(bridge_tunnel_header);
19822081
1983
-bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
1984
- bool is_4addr, u8 check_swif)
1985
-
1986
-{
1987
- bool is_vlan = iftype == NL80211_IFTYPE_AP_VLAN;
1988
-
1989
- switch (check_swif) {
1990
- case 0:
1991
- if (is_vlan && is_4addr)
1992
- return wiphy->flags & WIPHY_FLAG_4ADDR_AP;
1993
- return wiphy->interface_modes & BIT(iftype);
1994
- case 1:
1995
- if (!(wiphy->software_iftypes & BIT(iftype)) && is_vlan)
1996
- return wiphy->flags & WIPHY_FLAG_4ADDR_AP;
1997
- return wiphy->software_iftypes & BIT(iftype);
1998
- default:
1999
- break;
2000
- }
2001
-
2002
- return false;
2003
-}
2004
-EXPORT_SYMBOL(cfg80211_iftype_allowed);
2005
-
20062082 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
20072083 struct iapp_layer2_update {
20082084 u8 da[ETH_ALEN]; /* broadcast */
....@@ -2047,3 +2123,133 @@
20472123 netif_rx_ni(skb);
20482124 }
20492125 EXPORT_SYMBOL(cfg80211_send_layer2_update);
2126
+
2127
+int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
2128
+ enum ieee80211_vht_chanwidth bw,
2129
+ int mcs, bool ext_nss_bw_capable,
2130
+ unsigned int max_vht_nss)
2131
+{
2132
+ u16 map = le16_to_cpu(cap->supp_mcs.rx_mcs_map);
2133
+ int ext_nss_bw;
2134
+ int supp_width;
2135
+ int i, mcs_encoding;
2136
+
2137
+ if (map == 0xffff)
2138
+ return 0;
2139
+
2140
+ if (WARN_ON(mcs > 9 || max_vht_nss > 8))
2141
+ return 0;
2142
+ if (mcs <= 7)
2143
+ mcs_encoding = 0;
2144
+ else if (mcs == 8)
2145
+ mcs_encoding = 1;
2146
+ else
2147
+ mcs_encoding = 2;
2148
+
2149
+ if (!max_vht_nss) {
2150
+ /* find max_vht_nss for the given MCS */
2151
+ for (i = 7; i >= 0; i--) {
2152
+ int supp = (map >> (2 * i)) & 3;
2153
+
2154
+ if (supp == 3)
2155
+ continue;
2156
+
2157
+ if (supp >= mcs_encoding) {
2158
+ max_vht_nss = i + 1;
2159
+ break;
2160
+ }
2161
+ }
2162
+ }
2163
+
2164
+ if (!(cap->supp_mcs.tx_mcs_map &
2165
+ cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE)))
2166
+ return max_vht_nss;
2167
+
2168
+ ext_nss_bw = le32_get_bits(cap->vht_cap_info,
2169
+ IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
2170
+ supp_width = le32_get_bits(cap->vht_cap_info,
2171
+ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
2172
+
2173
+ /* if not capable, treat ext_nss_bw as 0 */
2174
+ if (!ext_nss_bw_capable)
2175
+ ext_nss_bw = 0;
2176
+
2177
+ /* This is invalid */
2178
+ if (supp_width == 3)
2179
+ return 0;
2180
+
2181
+ /* This is an invalid combination so pretend nothing is supported */
2182
+ if (supp_width == 2 && (ext_nss_bw == 1 || ext_nss_bw == 2))
2183
+ return 0;
2184
+
2185
+ /*
2186
+ * Cover all the special cases according to IEEE 802.11-2016
2187
+ * Table 9-250. All other cases are either factor of 1 or not
2188
+ * valid/supported.
2189
+ */
2190
+ switch (bw) {
2191
+ case IEEE80211_VHT_CHANWIDTH_USE_HT:
2192
+ case IEEE80211_VHT_CHANWIDTH_80MHZ:
2193
+ if ((supp_width == 1 || supp_width == 2) &&
2194
+ ext_nss_bw == 3)
2195
+ return 2 * max_vht_nss;
2196
+ break;
2197
+ case IEEE80211_VHT_CHANWIDTH_160MHZ:
2198
+ if (supp_width == 0 &&
2199
+ (ext_nss_bw == 1 || ext_nss_bw == 2))
2200
+ return max_vht_nss / 2;
2201
+ if (supp_width == 0 &&
2202
+ ext_nss_bw == 3)
2203
+ return (3 * max_vht_nss) / 4;
2204
+ if (supp_width == 1 &&
2205
+ ext_nss_bw == 3)
2206
+ return 2 * max_vht_nss;
2207
+ break;
2208
+ case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
2209
+ if (supp_width == 0 && ext_nss_bw == 1)
2210
+ return 0; /* not possible */
2211
+ if (supp_width == 0 &&
2212
+ ext_nss_bw == 2)
2213
+ return max_vht_nss / 2;
2214
+ if (supp_width == 0 &&
2215
+ ext_nss_bw == 3)
2216
+ return (3 * max_vht_nss) / 4;
2217
+ if (supp_width == 1 &&
2218
+ ext_nss_bw == 0)
2219
+ return 0; /* not possible */
2220
+ if (supp_width == 1 &&
2221
+ ext_nss_bw == 1)
2222
+ return max_vht_nss / 2;
2223
+ if (supp_width == 1 &&
2224
+ ext_nss_bw == 2)
2225
+ return (3 * max_vht_nss) / 4;
2226
+ break;
2227
+ }
2228
+
2229
+ /* not covered or invalid combination received */
2230
+ return max_vht_nss;
2231
+}
2232
+EXPORT_SYMBOL(ieee80211_get_vht_max_nss);
2233
+
2234
+bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
2235
+ bool is_4addr, u8 check_swif)
2236
+
2237
+{
2238
+ bool is_vlan = iftype == NL80211_IFTYPE_AP_VLAN;
2239
+
2240
+ switch (check_swif) {
2241
+ case 0:
2242
+ if (is_vlan && is_4addr)
2243
+ return wiphy->flags & WIPHY_FLAG_4ADDR_AP;
2244
+ return wiphy->interface_modes & BIT(iftype);
2245
+ case 1:
2246
+ if (!(wiphy->software_iftypes & BIT(iftype)) && is_vlan)
2247
+ return wiphy->flags & WIPHY_FLAG_4ADDR_AP;
2248
+ return wiphy->software_iftypes & BIT(iftype);
2249
+ default:
2250
+ break;
2251
+ }
2252
+
2253
+ return false;
2254
+}
2255
+EXPORT_SYMBOL(cfg80211_iftype_allowed);