hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
....@@ -8,7 +8,7 @@
88 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
99 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
1010 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11
- * Copyright(c) 2018 Intel Corporation
11
+ * Copyright(c) 2018 - 2019 Intel Corporation
1212 *
1313 * This program is free software; you can redistribute it and/or modify
1414 * it under the terms of version 2 of the GNU General Public License as
....@@ -18,11 +18,6 @@
1818 * WITHOUT ANY WARRANTY; without even the implied warranty of
1919 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2020 * General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program; if not, write to the Free Software
24
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
25
- * USA
2621 *
2722 * The full GNU General Public License is included in this distribution
2823 * in the file called COPYING.
....@@ -36,7 +31,7 @@
3631 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
3732 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3833 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
39
- * Copyright(c) 2018 Intel Corporation
34
+ * Copyright(c) 2018 - 2019 Intel Corporation
4035 * All rights reserved.
4136 *
4237 * Redistribution and use in source and binary forms, with or without
....@@ -135,7 +130,7 @@
135130 /*
136131 * These are the channel numbers in the order that they are stored in the NVM
137132 */
138
-static const u8 iwl_nvm_channels[] = {
133
+static const u16 iwl_nvm_channels[] = {
139134 /* 2.4 GHz */
140135 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
141136 /* 5 GHz */
....@@ -144,7 +139,7 @@
144139 149, 153, 157, 161, 165
145140 };
146141
147
-static const u8 iwl_ext_nvm_channels[] = {
142
+static const u16 iwl_ext_nvm_channels[] = {
148143 /* 2.4 GHz */
149144 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
150145 /* 5 GHz */
....@@ -153,14 +148,26 @@
153148 149, 153, 157, 161, 165, 169, 173, 177, 181
154149 };
155150
151
+static const u16 iwl_uhb_nvm_channels[] = {
152
+ /* 2.4 GHz */
153
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
154
+ /* 5 GHz */
155
+ 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
156
+ 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
157
+ 149, 153, 157, 161, 165, 169, 173, 177, 181,
158
+ /* 6-7 GHz */
159
+ 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69,
160
+ 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129,
161
+ 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185,
162
+ 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233
163
+};
164
+
156165 #define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
157166 #define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels)
167
+#define IWL_NVM_NUM_CHANNELS_UHB ARRAY_SIZE(iwl_uhb_nvm_channels)
158168 #define NUM_2GHZ_CHANNELS 14
159
-#define NUM_2GHZ_CHANNELS_EXT 14
160169 #define FIRST_2GHZ_HT_MINUS 5
161170 #define LAST_2GHZ_HT_PLUS 9
162
-#define LAST_5GHZ_HT 165
163
-#define LAST_5GHZ_HT_FAMILY_8000 181
164171 #define N_HW_ADDR_MASK 0xF
165172
166173 /* rate data (static) */
....@@ -233,6 +240,7 @@
233240 * @REG_CAPA_40MHZ_FORBIDDEN: 11n channel with a width of 40Mhz is forbidden
234241 * for this regulatory domain (valid only in 5Ghz).
235242 * @REG_CAPA_DC_HIGH_ENABLED: DC HIGH allowed.
243
+ * @REG_CAPA_11AX_DISABLED: 11ax is forbidden for this regulatory domain.
236244 */
237245 enum iwl_reg_capa_flags {
238246 REG_CAPA_BF_CCD_LOW_BAND = BIT(0),
....@@ -243,10 +251,70 @@
243251 REG_CAPA_MCS_9_ALLOWED = BIT(5),
244252 REG_CAPA_40MHZ_FORBIDDEN = BIT(7),
245253 REG_CAPA_DC_HIGH_ENABLED = BIT(9),
254
+ REG_CAPA_11AX_DISABLED = BIT(10),
255
+};
256
+
257
+/**
258
+ * enum iwl_reg_capa_flags_v2 - global flags applied for the whole regulatory
259
+ * domain (version 2).
260
+ * @REG_CAPA_V2_STRADDLE_DISABLED: Straddle channels (144, 142, 138) are
261
+ * disabled.
262
+ * @REG_CAPA_V2_BF_CCD_LOW_BAND: Beam-forming or Cyclic Delay Diversity in the
263
+ * 2.4Ghz band is allowed.
264
+ * @REG_CAPA_V2_BF_CCD_HIGH_BAND: Beam-forming or Cyclic Delay Diversity in the
265
+ * 5Ghz band is allowed.
266
+ * @REG_CAPA_V2_160MHZ_ALLOWED: 11ac channel with a width of 160Mhz is allowed
267
+ * for this regulatory domain (valid only in 5Ghz).
268
+ * @REG_CAPA_V2_80MHZ_ALLOWED: 11ac channel with a width of 80Mhz is allowed
269
+ * for this regulatory domain (valid only in 5Ghz).
270
+ * @REG_CAPA_V2_MCS_8_ALLOWED: 11ac with MCS 8 is allowed.
271
+ * @REG_CAPA_V2_MCS_9_ALLOWED: 11ac with MCS 9 is allowed.
272
+ * @REG_CAPA_V2_WEATHER_DISABLED: Weather radar channels (120, 124, 128, 118,
273
+ * 126, 122) are disabled.
274
+ * @REG_CAPA_V2_40MHZ_ALLOWED: 11n channel with a width of 40Mhz is allowed
275
+ * for this regulatory domain (uvalid only in 5Ghz).
276
+ * @REG_CAPA_V2_11AX_DISABLED: 11ax is forbidden for this regulatory domain.
277
+ */
278
+enum iwl_reg_capa_flags_v2 {
279
+ REG_CAPA_V2_STRADDLE_DISABLED = BIT(0),
280
+ REG_CAPA_V2_BF_CCD_LOW_BAND = BIT(1),
281
+ REG_CAPA_V2_BF_CCD_HIGH_BAND = BIT(2),
282
+ REG_CAPA_V2_160MHZ_ALLOWED = BIT(3),
283
+ REG_CAPA_V2_80MHZ_ALLOWED = BIT(4),
284
+ REG_CAPA_V2_MCS_8_ALLOWED = BIT(5),
285
+ REG_CAPA_V2_MCS_9_ALLOWED = BIT(6),
286
+ REG_CAPA_V2_WEATHER_DISABLED = BIT(7),
287
+ REG_CAPA_V2_40MHZ_ALLOWED = BIT(8),
288
+ REG_CAPA_V2_11AX_DISABLED = BIT(10),
289
+};
290
+
291
+/*
292
+* API v2 for reg_capa_flags is relevant from version 6 and onwards of the
293
+* MCC update command response.
294
+*/
295
+#define REG_CAPA_V2_RESP_VER 6
296
+
297
+/**
298
+ * struct iwl_reg_capa - struct for global regulatory capabilities, Used for
299
+ * handling the different APIs of reg_capa_flags.
300
+ *
301
+ * @allow_40mhz: 11n channel with a width of 40Mhz is allowed
302
+ * for this regulatory domain (valid only in 5Ghz).
303
+ * @allow_80mhz: 11ac channel with a width of 80Mhz is allowed
304
+ * for this regulatory domain (valid only in 5Ghz).
305
+ * @allow_160mhz: 11ac channel with a width of 160Mhz is allowed
306
+ * for this regulatory domain (valid only in 5Ghz).
307
+ * @disable_11ax: 11ax is forbidden for this regulatory domain.
308
+ */
309
+struct iwl_reg_capa {
310
+ u16 allow_40mhz;
311
+ u16 allow_80mhz;
312
+ u16 allow_160mhz;
313
+ u16 disable_11ax;
246314 };
247315
248316 static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
249
- int chan, u16 flags)
317
+ int chan, u32 flags)
250318 {
251319 #define CHECK_AND_PRINT_I(x) \
252320 ((flags & NVM_CHANNEL_##x) ? " " #x : "")
....@@ -276,21 +344,17 @@
276344 #undef CHECK_AND_PRINT_I
277345 }
278346
279
-static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
280
- u16 nvm_flags, const struct iwl_cfg *cfg)
347
+static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, enum nl80211_band band,
348
+ u32 nvm_flags, const struct iwl_cfg *cfg)
281349 {
282350 u32 flags = IEEE80211_CHAN_NO_HT40;
283
- u32 last_5ghz_ht = LAST_5GHZ_HT;
284351
285
- if (cfg->nvm_type == IWL_NVM_EXT)
286
- last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
287
-
288
- if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
352
+ if (band == NL80211_BAND_2GHZ && (nvm_flags & NVM_CHANNEL_40MHZ)) {
289353 if (ch_num <= LAST_2GHZ_HT_PLUS)
290354 flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
291355 if (ch_num >= FIRST_2GHZ_HT_MINUS)
292356 flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
293
- } else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
357
+ } else if (nvm_flags & NVM_CHANNEL_40MHZ) {
294358 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
295359 flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
296360 else
....@@ -323,39 +387,54 @@
323387 return flags;
324388 }
325389
390
+static enum nl80211_band iwl_nl80211_band_from_channel_idx(int ch_idx)
391
+{
392
+ if (ch_idx >= NUM_2GHZ_CHANNELS)
393
+ return NL80211_BAND_5GHZ;
394
+ return NL80211_BAND_2GHZ;
395
+}
396
+
326397 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
327398 struct iwl_nvm_data *data,
328
- const __le16 * const nvm_ch_flags,
329
- u32 sbands_flags)
399
+ const void * const nvm_ch_flags,
400
+ u32 sbands_flags, bool v4)
330401 {
331402 int ch_idx;
332403 int n_channels = 0;
333404 struct ieee80211_channel *channel;
334
- u16 ch_flags;
335
- int num_of_ch, num_2ghz_channels;
336
- const u8 *nvm_chan;
405
+ u32 ch_flags;
406
+ int num_of_ch;
407
+ const u16 *nvm_chan;
337408
338
- if (cfg->nvm_type != IWL_NVM_EXT) {
339
- num_of_ch = IWL_NVM_NUM_CHANNELS;
340
- nvm_chan = &iwl_nvm_channels[0];
341
- num_2ghz_channels = NUM_2GHZ_CHANNELS;
342
- } else {
409
+ if (cfg->uhb_supported) {
410
+ num_of_ch = IWL_NVM_NUM_CHANNELS_UHB;
411
+ nvm_chan = iwl_uhb_nvm_channels;
412
+ } else if (cfg->nvm_type == IWL_NVM_EXT) {
343413 num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
344
- nvm_chan = &iwl_ext_nvm_channels[0];
345
- num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT;
414
+ nvm_chan = iwl_ext_nvm_channels;
415
+ } else {
416
+ num_of_ch = IWL_NVM_NUM_CHANNELS;
417
+ nvm_chan = iwl_nvm_channels;
346418 }
347419
348420 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
349
- bool is_5ghz = (ch_idx >= num_2ghz_channels);
421
+ enum nl80211_band band =
422
+ iwl_nl80211_band_from_channel_idx(ch_idx);
350423
351
- ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
424
+ if (v4)
425
+ ch_flags =
426
+ __le32_to_cpup((__le32 *)nvm_ch_flags + ch_idx);
427
+ else
428
+ ch_flags =
429
+ __le16_to_cpup((__le16 *)nvm_ch_flags + ch_idx);
352430
353
- if (is_5ghz && !data->sku_cap_band_52ghz_enable)
431
+ if (band == NL80211_BAND_5GHZ &&
432
+ !data->sku_cap_band_52ghz_enable)
354433 continue;
355434
356435 /* workaround to disable wide channels in 5GHz */
357436 if ((sbands_flags & IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ) &&
358
- is_5ghz) {
437
+ band == NL80211_BAND_5GHZ) {
359438 ch_flags &= ~(NVM_CHANNEL_40MHZ |
360439 NVM_CHANNEL_80MHZ |
361440 NVM_CHANNEL_160MHZ);
....@@ -380,8 +459,7 @@
380459 n_channels++;
381460
382461 channel->hw_value = nvm_chan[ch_idx];
383
- channel->band = is_5ghz ?
384
- NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
462
+ channel->band = band;
385463 channel->center_freq =
386464 ieee80211_channel_to_frequency(
387465 channel->hw_value, channel->band);
....@@ -397,7 +475,7 @@
397475 /* don't put limitations in case we're using LAR */
398476 if (!(sbands_flags & IWL_NVM_SBANDS_FLAGS_LAR))
399477 channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
400
- ch_idx, is_5ghz,
478
+ ch_idx, band,
401479 ch_flags, cfg);
402480 else
403481 channel->flags = 0;
....@@ -411,11 +489,12 @@
411489 return n_channels;
412490 }
413491
414
-static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
492
+static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
415493 struct iwl_nvm_data *data,
416494 struct ieee80211_sta_vht_cap *vht_cap,
417495 u8 tx_chains, u8 rx_chains)
418496 {
497
+ const struct iwl_cfg *cfg = trans->cfg;
419498 int num_rx_ants = num_of_ant(rx_chains);
420499 int num_tx_ants = num_of_ant(tx_chains);
421500 unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?:
....@@ -452,14 +531,14 @@
452531
453532 switch (iwlwifi_mod_params.amsdu_size) {
454533 case IWL_AMSDU_DEF:
455
- if (cfg->mq_rx_supported)
534
+ if (trans->trans_cfg->mq_rx_supported)
456535 vht_cap->cap |=
457536 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
458537 else
459538 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
460539 break;
461540 case IWL_AMSDU_2K:
462
- if (cfg->mq_rx_supported)
541
+ if (trans->trans_cfg->mq_rx_supported)
463542 vht_cap->cap |=
464543 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
465544 else
....@@ -496,125 +575,220 @@
496575 }
497576
498577 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
578
+
579
+ vht_cap->vht_mcs.tx_highest |=
580
+ cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
499581 }
500582
501
-static struct ieee80211_sband_iftype_data iwl_he_capa = {
502
- .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
503
- .he_cap = {
504
- .has_he = true,
505
- .he_cap_elem = {
506
- .mac_cap_info[0] =
507
- IEEE80211_HE_MAC_CAP0_HTC_HE,
508
- .mac_cap_info[1] =
509
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
510
- IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8,
511
- .mac_cap_info[2] =
512
- IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
513
- IEEE80211_HE_MAC_CAP2_ACK_EN,
514
- .mac_cap_info[3] =
515
- IEEE80211_HE_MAC_CAP3_GRP_ADDR_MULTI_STA_BA_DL_MU |
516
- IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2,
517
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
518
- .phy_cap_info[0] =
519
- IEEE80211_HE_PHY_CAP0_DUAL_BAND |
520
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
521
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
522
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
523
- .phy_cap_info[1] =
524
- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
525
- IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
526
- IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS,
527
- .phy_cap_info[2] =
528
- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
529
- IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
530
- IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ,
531
- .phy_cap_info[3] =
532
- IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK |
533
- IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
534
- IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK |
535
- IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
536
- .phy_cap_info[4] =
537
- IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
538
- IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
539
- IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
540
- .phy_cap_info[5] =
541
- IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
542
- IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2,
543
- .phy_cap_info[6] =
544
- IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
545
- .phy_cap_info[7] =
546
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
547
- IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
548
- IEEE80211_HE_PHY_CAP7_MAX_NC_7,
549
- .phy_cap_info[8] =
550
- IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
551
- IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
552
- IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
553
- IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU,
583
+static struct ieee80211_sband_iftype_data iwl_he_capa[] = {
584
+ {
585
+ .types_mask = BIT(NL80211_IFTYPE_STATION),
586
+ .he_cap = {
587
+ .has_he = true,
588
+ .he_cap_elem = {
589
+ .mac_cap_info[0] =
590
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
591
+ .mac_cap_info[1] =
592
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
593
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
594
+ .mac_cap_info[2] =
595
+ IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP,
596
+ .mac_cap_info[3] =
597
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
598
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
599
+ .mac_cap_info[4] =
600
+ IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
601
+ IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
602
+ .mac_cap_info[5] =
603
+ IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 |
604
+ IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 |
605
+ IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |
606
+ IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS |
607
+ IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX,
608
+ .phy_cap_info[0] =
609
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
610
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
611
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
612
+ .phy_cap_info[1] =
613
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
614
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
615
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD,
616
+ .phy_cap_info[2] =
617
+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US,
618
+ .phy_cap_info[3] =
619
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM |
620
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
621
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_NO_DCM |
622
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
623
+ .phy_cap_info[4] =
624
+ IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
625
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
626
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
627
+ .phy_cap_info[5] =
628
+ IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
629
+ IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2,
630
+ .phy_cap_info[6] =
631
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
632
+ .phy_cap_info[7] =
633
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
634
+ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
635
+ IEEE80211_HE_PHY_CAP7_MAX_NC_1,
636
+ .phy_cap_info[8] =
637
+ IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
638
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
639
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
640
+ IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
641
+ IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996,
642
+ .phy_cap_info[9] =
643
+ IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
644
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
645
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |
646
+ IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_RESERVED,
647
+ },
648
+ /*
649
+ * Set default Tx/Rx HE MCS NSS Support field.
650
+ * Indicate support for up to 2 spatial streams and all
651
+ * MCS, without any special cases
652
+ */
653
+ .he_mcs_nss_supp = {
654
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
655
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
656
+ .rx_mcs_160 = cpu_to_le16(0xfffa),
657
+ .tx_mcs_160 = cpu_to_le16(0xfffa),
658
+ .rx_mcs_80p80 = cpu_to_le16(0xffff),
659
+ .tx_mcs_80p80 = cpu_to_le16(0xffff),
660
+ },
661
+ /*
662
+ * Set default PPE thresholds, with PPET16 set to 0,
663
+ * PPET8 set to 7
664
+ */
665
+ .ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
554666 },
555
- /*
556
- * Set default Tx/Rx HE MCS NSS Support field. Indicate support
557
- * for up to 2 spatial streams and all MCS, without any special
558
- * cases
559
- */
560
- .he_mcs_nss_supp = {
561
- .rx_mcs_80 = cpu_to_le16(0xfffa),
562
- .tx_mcs_80 = cpu_to_le16(0xfffa),
563
- .rx_mcs_160 = cpu_to_le16(0xfffa),
564
- .tx_mcs_160 = cpu_to_le16(0xfffa),
565
- .rx_mcs_80p80 = cpu_to_le16(0xffff),
566
- .tx_mcs_80p80 = cpu_to_le16(0xffff),
667
+ },
668
+ {
669
+ .types_mask = BIT(NL80211_IFTYPE_AP),
670
+ .he_cap = {
671
+ .has_he = true,
672
+ .he_cap_elem = {
673
+ .mac_cap_info[0] =
674
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
675
+ .mac_cap_info[1] =
676
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
677
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
678
+ .mac_cap_info[2] =
679
+ IEEE80211_HE_MAC_CAP2_BSR,
680
+ .mac_cap_info[3] =
681
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
682
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
683
+ .mac_cap_info[4] =
684
+ IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
685
+ .mac_cap_info[5] =
686
+ IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU,
687
+ .phy_cap_info[0] =
688
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
689
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
690
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
691
+ .phy_cap_info[1] =
692
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD,
693
+ .phy_cap_info[2] =
694
+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US,
695
+ .phy_cap_info[3] =
696
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM |
697
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
698
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_NO_DCM |
699
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
700
+ .phy_cap_info[4] =
701
+ IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
702
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
703
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
704
+ .phy_cap_info[5] =
705
+ IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
706
+ IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2,
707
+ .phy_cap_info[6] =
708
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
709
+ .phy_cap_info[7] =
710
+ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
711
+ IEEE80211_HE_PHY_CAP7_MAX_NC_1,
712
+ .phy_cap_info[8] =
713
+ IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
714
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
715
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
716
+ IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
717
+ IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996,
718
+ .phy_cap_info[9] =
719
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
720
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB |
721
+ IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_RESERVED,
722
+ },
723
+ /*
724
+ * Set default Tx/Rx HE MCS NSS Support field.
725
+ * Indicate support for up to 2 spatial streams and all
726
+ * MCS, without any special cases
727
+ */
728
+ .he_mcs_nss_supp = {
729
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
730
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
731
+ .rx_mcs_160 = cpu_to_le16(0xfffa),
732
+ .tx_mcs_160 = cpu_to_le16(0xfffa),
733
+ .rx_mcs_80p80 = cpu_to_le16(0xffff),
734
+ .tx_mcs_80p80 = cpu_to_le16(0xffff),
735
+ },
736
+ /*
737
+ * Set default PPE thresholds, with PPET16 set to 0,
738
+ * PPET8 set to 7
739
+ */
740
+ .ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
567741 },
568
- /*
569
- * Set default PPE thresholds, with PPET16 set to 0, PPET8 set
570
- * to 7
571
- */
572
- .ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
573742 },
574743 };
575744
576
-static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
745
+static void iwl_init_he_hw_capab(struct iwl_trans *trans,
746
+ struct iwl_nvm_data *data,
747
+ struct ieee80211_supported_band *sband,
577748 u8 tx_chains, u8 rx_chains)
578749 {
579
- if (sband->band == NL80211_BAND_2GHZ ||
580
- sband->band == NL80211_BAND_5GHZ)
581
- sband->iftype_data = &iwl_he_capa;
582
- else
583
- return;
584
-
585
- sband->n_iftype_data = 1;
750
+ sband->iftype_data = iwl_he_capa;
751
+ sband->n_iftype_data = ARRAY_SIZE(iwl_he_capa);
586752
587753 /* If not 2x2, we need to indicate 1x1 in the Midamble RX Max NSTS */
588754 if ((tx_chains & rx_chains) != ANT_AB) {
589
- iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[1] &=
590
- ~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS;
591
- iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[2] &=
592
- ~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_MAX_NSTS;
755
+ int i;
756
+
757
+ for (i = 0; i < sband->n_iftype_data; i++) {
758
+ iwl_he_capa[i].he_cap.he_cap_elem.phy_cap_info[1] &=
759
+ ~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS;
760
+ iwl_he_capa[i].he_cap.he_cap_elem.phy_cap_info[2] &=
761
+ ~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS;
762
+ iwl_he_capa[i].he_cap.he_cap_elem.phy_cap_info[7] &=
763
+ ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
764
+ }
593765 }
594766 }
595767
596
-static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
768
+static void iwl_init_sbands(struct iwl_trans *trans,
597769 struct iwl_nvm_data *data,
598
- const __le16 *nvm_ch_flags, u8 tx_chains,
599
- u8 rx_chains, u32 sbands_flags)
770
+ const void *nvm_ch_flags, u8 tx_chains,
771
+ u8 rx_chains, u32 sbands_flags, bool v4)
600772 {
773
+ struct device *dev = trans->dev;
774
+ const struct iwl_cfg *cfg = trans->cfg;
601775 int n_channels;
602776 int n_used = 0;
603777 struct ieee80211_supported_band *sband;
604778
605779 n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
606
- sbands_flags);
780
+ sbands_flags, v4);
607781 sband = &data->bands[NL80211_BAND_2GHZ];
608782 sband->band = NL80211_BAND_2GHZ;
609783 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
610784 sband->n_bitrates = N_RATES_24;
611785 n_used += iwl_init_sband_channels(data, sband, n_channels,
612786 NL80211_BAND_2GHZ);
613
- iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
787
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ,
614788 tx_chains, rx_chains);
615789
616790 if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
617
- iwl_init_he_hw_capab(sband, tx_chains, rx_chains);
791
+ iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains);
618792
619793 sband = &data->bands[NL80211_BAND_5GHZ];
620794 sband->band = NL80211_BAND_5GHZ;
....@@ -622,14 +796,14 @@
622796 sband->n_bitrates = N_RATES_52;
623797 n_used += iwl_init_sband_channels(data, sband, n_channels,
624798 NL80211_BAND_5GHZ);
625
- iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
799
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ,
626800 tx_chains, rx_chains);
627801 if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
628
- iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
802
+ iwl_init_vht_hw_capab(trans, data, &sband->vht_cap,
629803 tx_chains, rx_chains);
630804
631805 if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
632
- iwl_init_he_hw_capab(sband, tx_chains, rx_chains);
806
+ iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains);
633807
634808 if (n_channels != n_used)
635809 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
....@@ -715,12 +889,8 @@
715889 static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
716890 struct iwl_nvm_data *data)
717891 {
718
- __le32 mac_addr0 =
719
- cpu_to_le32(iwl_read32(trans,
720
- trans->cfg->csr->mac_addr0_strap));
721
- __le32 mac_addr1 =
722
- cpu_to_le32(iwl_read32(trans,
723
- trans->cfg->csr->mac_addr1_strap));
892
+ __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
893
+ __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
724894
725895 iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
726896 /*
....@@ -730,10 +900,8 @@
730900 if (is_valid_ether_addr(data->hw_addr))
731901 return;
732902
733
- mac_addr0 = cpu_to_le32(iwl_read32(trans,
734
- trans->cfg->csr->mac_addr0_otp));
735
- mac_addr1 = cpu_to_le32(iwl_read32(trans,
736
- trans->cfg->csr->mac_addr1_otp));
903
+ mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
904
+ mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
737905
738906 iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
739907 }
....@@ -820,7 +988,7 @@
820988 }
821989
822990 static bool
823
-iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
991
+iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg,
824992 const __be16 *nvm_hw)
825993 {
826994 /*
....@@ -832,7 +1000,7 @@
8321000 * in 5GHz otherwise the FW will throw a sysassert when we try
8331001 * to use them.
8341002 */
835
- if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
1003
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
8361004 /*
8371005 * Unlike the other sections in the NVM, the hw
8381006 * section uses big-endian.
....@@ -841,7 +1009,7 @@
8411009 u8 sku = (subsystem_id & 0x1e) >> 1;
8421010
8431011 if (sku == 5 || sku == 9) {
844
- IWL_DEBUG_EEPROM(dev,
1012
+ IWL_DEBUG_EEPROM(trans->dev,
8451013 "disabling wide channels in 5GHz (0x%0x %d)\n",
8461014 subsystem_id, sku);
8471015 return true;
....@@ -853,12 +1021,12 @@
8531021
8541022 struct iwl_nvm_data *
8551023 iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
1024
+ const struct iwl_fw *fw,
8561025 const __be16 *nvm_hw, const __le16 *nvm_sw,
8571026 const __le16 *nvm_calib, const __le16 *regulatory,
8581027 const __le16 *mac_override, const __le16 *phy_sku,
859
- u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
1028
+ u8 tx_chains, u8 rx_chains)
8601029 {
861
- struct device *dev = trans->dev;
8621030 struct iwl_nvm_data *data;
8631031 bool lar_enabled;
8641032 u32 sku, radio_cfg;
....@@ -866,16 +1034,18 @@
8661034 u16 lar_config;
8671035 const __le16 *ch_section;
8681036
869
- if (cfg->nvm_type != IWL_NVM_EXT)
870
- data = kzalloc(sizeof(*data) +
871
- sizeof(struct ieee80211_channel) *
872
- IWL_NVM_NUM_CHANNELS,
873
- GFP_KERNEL);
1037
+ if (cfg->uhb_supported)
1038
+ data = kzalloc(struct_size(data, channels,
1039
+ IWL_NVM_NUM_CHANNELS_UHB),
1040
+ GFP_KERNEL);
1041
+ else if (cfg->nvm_type != IWL_NVM_EXT)
1042
+ data = kzalloc(struct_size(data, channels,
1043
+ IWL_NVM_NUM_CHANNELS),
1044
+ GFP_KERNEL);
8741045 else
875
- data = kzalloc(sizeof(*data) +
876
- sizeof(struct ieee80211_channel) *
877
- IWL_NVM_NUM_CHANNELS_EXT,
878
- GFP_KERNEL);
1046
+ data = kzalloc(struct_size(data, channels,
1047
+ IWL_NVM_NUM_CHANNELS_EXT),
1048
+ GFP_KERNEL);
8791049 if (!data)
8801050 return NULL;
8811051
....@@ -935,30 +1105,27 @@
9351105 return NULL;
9361106 }
9371107
938
- if (lar_fw_supported && lar_enabled)
1108
+ if (lar_enabled &&
1109
+ fw_has_capa(&fw->ucode_capa, IWL_UCODE_TLV_CAPA_LAR_SUPPORT))
9391110 sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR;
9401111
941
- if (iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw))
1112
+ if (iwl_nvm_no_wide_in_5ghz(trans, cfg, nvm_hw))
9421113 sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ;
9431114
944
- iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
945
- sbands_flags);
1115
+ iwl_init_sbands(trans, data, ch_section, tx_chains, rx_chains,
1116
+ sbands_flags, false);
9461117 data->calib_version = 255;
9471118
9481119 return data;
9491120 }
9501121 IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
9511122
952
-static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
1123
+static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
9531124 int ch_idx, u16 nvm_flags,
954
- u16 cap_flags,
1125
+ struct iwl_reg_capa reg_capa,
9551126 const struct iwl_cfg *cfg)
9561127 {
9571128 u32 flags = NL80211_RRF_NO_HT40;
958
- u32 last_5ghz_ht = LAST_5GHZ_HT;
959
-
960
- if (cfg->nvm_type == IWL_NVM_EXT)
961
- last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
9621129
9631130 if (ch_idx < NUM_2GHZ_CHANNELS &&
9641131 (nvm_flags & NVM_CHANNEL_40MHZ)) {
....@@ -966,8 +1133,7 @@
9661133 flags &= ~NL80211_RRF_NO_HT40PLUS;
9671134 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
9681135 flags &= ~NL80211_RRF_NO_HT40MINUS;
969
- } else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
970
- (nvm_flags & NVM_CHANNEL_40MHZ)) {
1136
+ } else if (nvm_flags & NVM_CHANNEL_40MHZ) {
9711137 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
9721138 flags &= ~NL80211_RRF_NO_HT40PLUS;
9731139 else
....@@ -996,80 +1162,95 @@
9961162 flags |= NL80211_RRF_GO_CONCURRENT;
9971163
9981164 /*
999
- * cap_flags is per regulatory domain so apply it for every channel
1165
+ * reg_capa is per regulatory domain so apply it for every channel
10001166 */
10011167 if (ch_idx >= NUM_2GHZ_CHANNELS) {
1002
- if (cap_flags & REG_CAPA_40MHZ_FORBIDDEN)
1168
+ if (!reg_capa.allow_40mhz)
10031169 flags |= NL80211_RRF_NO_HT40;
10041170
1005
- if (!(cap_flags & REG_CAPA_80MHZ_ALLOWED))
1171
+ if (!reg_capa.allow_80mhz)
10061172 flags |= NL80211_RRF_NO_80MHZ;
10071173
1008
- if (!(cap_flags & REG_CAPA_160MHZ_ALLOWED))
1174
+ if (!reg_capa.allow_160mhz)
10091175 flags |= NL80211_RRF_NO_160MHZ;
10101176 }
1177
+ if (reg_capa.disable_11ax)
1178
+ flags |= NL80211_RRF_NO_HE;
10111179
10121180 return flags;
10131181 }
10141182
1015
-struct regdb_ptrs {
1016
- struct ieee80211_wmm_rule *rule;
1017
- u32 token;
1018
-};
1183
+static struct iwl_reg_capa iwl_get_reg_capa(u16 flags, u8 resp_ver)
1184
+{
1185
+ struct iwl_reg_capa reg_capa;
1186
+
1187
+ if (resp_ver >= REG_CAPA_V2_RESP_VER) {
1188
+ reg_capa.allow_40mhz = flags & REG_CAPA_V2_40MHZ_ALLOWED;
1189
+ reg_capa.allow_80mhz = flags & REG_CAPA_V2_80MHZ_ALLOWED;
1190
+ reg_capa.allow_160mhz = flags & REG_CAPA_V2_160MHZ_ALLOWED;
1191
+ reg_capa.disable_11ax = flags & REG_CAPA_V2_11AX_DISABLED;
1192
+ } else {
1193
+ reg_capa.allow_40mhz = !(flags & REG_CAPA_40MHZ_FORBIDDEN);
1194
+ reg_capa.allow_80mhz = flags & REG_CAPA_80MHZ_ALLOWED;
1195
+ reg_capa.allow_160mhz = flags & REG_CAPA_160MHZ_ALLOWED;
1196
+ reg_capa.disable_11ax = flags & REG_CAPA_11AX_DISABLED;
1197
+ }
1198
+ return reg_capa;
1199
+}
10191200
10201201 struct ieee80211_regdomain *
10211202 iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
10221203 int num_of_ch, __le32 *channels, u16 fw_mcc,
1023
- u16 geo_info, u16 cap)
1204
+ u16 geo_info, u16 cap, u8 resp_ver)
10241205 {
10251206 int ch_idx;
10261207 u16 ch_flags;
10271208 u32 reg_rule_flags, prev_reg_rule_flags = 0;
1028
- const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
1029
- iwl_ext_nvm_channels : iwl_nvm_channels;
1209
+ const u16 *nvm_chan;
10301210 struct ieee80211_regdomain *regd, *copy_rd;
1031
- int size_of_regd, regd_to_copy;
10321211 struct ieee80211_reg_rule *rule;
1033
- struct regdb_ptrs *regdb_ptrs;
10341212 enum nl80211_band band;
10351213 int center_freq, prev_center_freq = 0;
10361214 int valid_rules = 0;
10371215 bool new_rule;
1038
- int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
1039
- IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
1216
+ int max_num_ch;
1217
+ struct iwl_reg_capa reg_capa;
10401218
1041
- if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
1042
- return ERR_PTR(-EINVAL);
1219
+ if (cfg->uhb_supported) {
1220
+ max_num_ch = IWL_NVM_NUM_CHANNELS_UHB;
1221
+ nvm_chan = iwl_uhb_nvm_channels;
1222
+ } else if (cfg->nvm_type == IWL_NVM_EXT) {
1223
+ max_num_ch = IWL_NVM_NUM_CHANNELS_EXT;
1224
+ nvm_chan = iwl_ext_nvm_channels;
1225
+ } else {
1226
+ max_num_ch = IWL_NVM_NUM_CHANNELS;
1227
+ nvm_chan = iwl_nvm_channels;
1228
+ }
10431229
10441230 if (WARN_ON(num_of_ch > max_num_ch))
10451231 num_of_ch = max_num_ch;
1232
+
1233
+ if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
1234
+ return ERR_PTR(-EINVAL);
10461235
10471236 IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n",
10481237 num_of_ch);
10491238
10501239 /* build a regdomain rule for every valid channel */
1051
- size_of_regd =
1052
- sizeof(struct ieee80211_regdomain) +
1053
- num_of_ch * sizeof(struct ieee80211_reg_rule);
1054
-
1055
- regd = kzalloc(size_of_regd, GFP_KERNEL);
1240
+ regd = kzalloc(struct_size(regd, reg_rules, num_of_ch), GFP_KERNEL);
10561241 if (!regd)
10571242 return ERR_PTR(-ENOMEM);
1058
-
1059
- regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL);
1060
- if (!regdb_ptrs) {
1061
- copy_rd = ERR_PTR(-ENOMEM);
1062
- goto out;
1063
- }
10641243
10651244 /* set alpha2 from FW. */
10661245 regd->alpha2[0] = fw_mcc >> 8;
10671246 regd->alpha2[1] = fw_mcc & 0xff;
10681247
1248
+ /* parse regulatory capability flags */
1249
+ reg_capa = iwl_get_reg_capa(cap, resp_ver);
1250
+
10691251 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
10701252 ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
1071
- band = (ch_idx < NUM_2GHZ_CHANNELS) ?
1072
- NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
1253
+ band = iwl_nl80211_band_from_channel_idx(ch_idx);
10731254 center_freq = ieee80211_channel_to_frequency(nvm_chan[ch_idx],
10741255 band);
10751256 new_rule = false;
....@@ -1081,7 +1262,7 @@
10811262 }
10821263
10831264 reg_rule_flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
1084
- ch_flags, cap,
1265
+ ch_flags, reg_capa,
10851266 cfg);
10861267
10871268 /* we can't continue the same rule */
....@@ -1129,19 +1310,11 @@
11291310 * Narrow down regdom for unused regulatory rules to prevent hole
11301311 * between reg rules to wmm rules.
11311312 */
1132
- regd_to_copy = sizeof(struct ieee80211_regdomain) +
1133
- valid_rules * sizeof(struct ieee80211_reg_rule);
1134
-
1135
- copy_rd = kzalloc(regd_to_copy, GFP_KERNEL);
1136
- if (!copy_rd) {
1313
+ copy_rd = kmemdup(regd, struct_size(regd, reg_rules, valid_rules),
1314
+ GFP_KERNEL);
1315
+ if (!copy_rd)
11371316 copy_rd = ERR_PTR(-ENOMEM);
1138
- goto out;
1139
- }
11401317
1141
- memcpy(copy_rd, regd, regd_to_copy);
1142
-
1143
-out:
1144
- kfree(regdb_ptrs);
11451318 kfree(regd);
11461319 return copy_rd;
11471320 }
....@@ -1260,7 +1433,7 @@
12601433 le32_to_cpu(dword_buff[3]));
12611434
12621435 /* nvm file validation, dword_buff[2] holds the file version */
1263
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
1436
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
12641437 CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP &&
12651438 le32_to_cpu(dword_buff[2]) < 0xE4A) {
12661439 ret = -EFAULT;
....@@ -1347,7 +1520,6 @@
13471520 const struct iwl_fw *fw)
13481521 {
13491522 struct iwl_nvm_get_info cmd = {};
1350
- struct iwl_nvm_get_info_rsp *rsp;
13511523 struct iwl_nvm_data *nvm;
13521524 struct iwl_host_cmd hcmd = {
13531525 .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
....@@ -1356,18 +1528,27 @@
13561528 .id = WIDE_ID(REGULATORY_AND_NVM_GROUP, NVM_GET_INFO)
13571529 };
13581530 int ret;
1359
- bool lar_fw_supported = !iwlwifi_mod_params.lar_disable &&
1360
- fw_has_capa(&fw->ucode_capa,
1361
- IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
13621531 bool empty_otp;
13631532 u32 mac_flags;
13641533 u32 sbands_flags = 0;
1534
+ /*
1535
+ * All the values in iwl_nvm_get_info_rsp v4 are the same as
1536
+ * in v3, except for the channel profile part of the
1537
+ * regulatory. So we can just access the new struct, with the
1538
+ * exception of the latter.
1539
+ */
1540
+ struct iwl_nvm_get_info_rsp *rsp;
1541
+ struct iwl_nvm_get_info_rsp_v3 *rsp_v3;
1542
+ bool v4 = fw_has_api(&fw->ucode_capa,
1543
+ IWL_UCODE_TLV_API_REGULATORY_NVM_INFO);
1544
+ size_t rsp_size = v4 ? sizeof(*rsp) : sizeof(*rsp_v3);
1545
+ void *channel_profile;
13651546
13661547 ret = iwl_trans_send_cmd(trans, &hcmd);
13671548 if (ret)
13681549 return ERR_PTR(ret);
13691550
1370
- if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
1551
+ if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != rsp_size,
13711552 "Invalid payload len in NVM response from FW %d",
13721553 iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
13731554 ret = -EINVAL;
....@@ -1380,9 +1561,7 @@
13801561 if (empty_otp)
13811562 IWL_INFO(trans, "OTP is empty\n");
13821563
1383
- nvm = kzalloc(sizeof(*nvm) +
1384
- sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
1385
- GFP_KERNEL);
1564
+ nvm = kzalloc(struct_size(nvm, channels, IWL_NUM_CHANNELS), GFP_KERNEL);
13861565 if (!nvm) {
13871566 ret = -ENOMEM;
13881567 goto out;
....@@ -1426,16 +1605,22 @@
14261605 nvm->valid_tx_ant = (u8)le32_to_cpu(rsp->phy_sku.tx_chains);
14271606 nvm->valid_rx_ant = (u8)le32_to_cpu(rsp->phy_sku.rx_chains);
14281607
1429
- if (le32_to_cpu(rsp->regulatory.lar_enabled) && lar_fw_supported) {
1608
+ if (le32_to_cpu(rsp->regulatory.lar_enabled) &&
1609
+ fw_has_capa(&fw->ucode_capa,
1610
+ IWL_UCODE_TLV_CAPA_LAR_SUPPORT)) {
14301611 nvm->lar_enabled = true;
14311612 sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR;
14321613 }
14331614
1434
- iwl_init_sbands(trans->dev, trans->cfg, nvm,
1435
- rsp->regulatory.channel_profile,
1615
+ rsp_v3 = (void *)rsp;
1616
+ channel_profile = v4 ? (void *)rsp->regulatory.channel_profile :
1617
+ (void *)rsp_v3->regulatory.channel_profile;
1618
+
1619
+ iwl_init_sbands(trans, nvm,
1620
+ channel_profile,
14361621 nvm->valid_tx_ant & fw->valid_tx_ant,
14371622 nvm->valid_rx_ant & fw->valid_rx_ant,
1438
- sbands_flags);
1623
+ sbands_flags, v4);
14391624
14401625 iwl_free_resp(&hcmd);
14411626 return nvm;