aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-nvm-parse.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c411
1 files changed, 304 insertions, 107 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index c74f1a4edf23..774637746427 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -103,8 +103,16 @@ enum family_8000_nvm_offsets {
103 SKU_FAMILY_8000 = 4, 103 SKU_FAMILY_8000 = 4,
104 N_HW_ADDRS_FAMILY_8000 = 5, 104 N_HW_ADDRS_FAMILY_8000 = 5,
105 105
106 /* NVM PHY-SKU-Section offset (in words) for B0 */
107 RADIO_CFG_FAMILY_8000_B0 = 0,
108 SKU_FAMILY_8000_B0 = 2,
109 N_HW_ADDRS_FAMILY_8000_B0 = 3,
110
106 /* NVM REGULATORY -Section offset (in words) definitions */ 111 /* NVM REGULATORY -Section offset (in words) definitions */
107 NVM_CHANNELS_FAMILY_8000 = 0, 112 NVM_CHANNELS_FAMILY_8000 = 0,
113 NVM_LAR_OFFSET_FAMILY_8000_OLD = 0x4C7,
114 NVM_LAR_OFFSET_FAMILY_8000 = 0x507,
115 NVM_LAR_ENABLED_FAMILY_8000 = 0x7,
108 116
109 /* NVM calibration section offset (in words) definitions */ 117 /* NVM calibration section offset (in words) definitions */
110 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8, 118 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
@@ -146,7 +154,9 @@ static const u8 iwl_nvm_channels_family_8000[] = {
146#define NUM_2GHZ_CHANNELS_FAMILY_8000 14 154#define NUM_2GHZ_CHANNELS_FAMILY_8000 14
147#define FIRST_2GHZ_HT_MINUS 5 155#define FIRST_2GHZ_HT_MINUS 5
148#define LAST_2GHZ_HT_PLUS 9 156#define LAST_2GHZ_HT_PLUS 9
149#define LAST_5GHZ_HT 161 157#define LAST_5GHZ_HT 165
158#define LAST_5GHZ_HT_FAMILY_8000 181
159#define N_HW_ADDR_MASK 0xF
150 160
151/* rate data (static) */ 161/* rate data (static) */
152static struct ieee80211_rate iwl_cfg80211_rates[] = { 162static struct ieee80211_rate iwl_cfg80211_rates[] = {
@@ -201,9 +211,57 @@ enum iwl_nvm_channel_flags {
201#define CHECK_AND_PRINT_I(x) \ 211#define CHECK_AND_PRINT_I(x) \
202 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") 212 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
203 213
214static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
215 u16 nvm_flags, const struct iwl_cfg *cfg)
216{
217 u32 flags = IEEE80211_CHAN_NO_HT40;
218 u32 last_5ghz_ht = LAST_5GHZ_HT;
219
220 if (cfg->device_family == IWL_DEVICE_FAMILY_8000)
221 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
222
223 if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
224 if (ch_num <= LAST_2GHZ_HT_PLUS)
225 flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
226 if (ch_num >= FIRST_2GHZ_HT_MINUS)
227 flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
228 } else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
229 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
230 flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
231 else
232 flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
233 }
234 if (!(nvm_flags & NVM_CHANNEL_80MHZ))
235 flags |= IEEE80211_CHAN_NO_80MHZ;
236 if (!(nvm_flags & NVM_CHANNEL_160MHZ))
237 flags |= IEEE80211_CHAN_NO_160MHZ;
238
239 if (!(nvm_flags & NVM_CHANNEL_IBSS))
240 flags |= IEEE80211_CHAN_NO_IR;
241
242 if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
243 flags |= IEEE80211_CHAN_NO_IR;
244
245 if (nvm_flags & NVM_CHANNEL_RADAR)
246 flags |= IEEE80211_CHAN_RADAR;
247
248 if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
249 flags |= IEEE80211_CHAN_INDOOR_ONLY;
250
251 /* Set the GO concurrent flag only in case that NO_IR is set.
252 * Otherwise it is meaningless
253 */
254 if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
255 (flags & IEEE80211_CHAN_NO_IR))
256 flags |= IEEE80211_CHAN_GO_CONCURRENT;
257
258 return flags;
259}
260
204static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, 261static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
205 struct iwl_nvm_data *data, 262 struct iwl_nvm_data *data,
206 const __le16 * const nvm_ch_flags) 263 const __le16 * const nvm_ch_flags,
264 bool lar_supported)
207{ 265{
208 int ch_idx; 266 int ch_idx;
209 int n_channels = 0; 267 int n_channels = 0;
@@ -228,9 +286,14 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
228 286
229 if (ch_idx >= num_2ghz_channels && 287 if (ch_idx >= num_2ghz_channels &&
230 !data->sku_cap_band_52GHz_enable) 288 !data->sku_cap_band_52GHz_enable)
231 ch_flags &= ~NVM_CHANNEL_VALID; 289 continue;
232 290
233 if (!(ch_flags & NVM_CHANNEL_VALID)) { 291 if (!lar_supported && !(ch_flags & NVM_CHANNEL_VALID)) {
292 /*
293 * Channels might become valid later if lar is
294 * supported, hence we still want to add them to
295 * the list of supported channels to cfg80211.
296 */
234 IWL_DEBUG_EEPROM(dev, 297 IWL_DEBUG_EEPROM(dev,
235 "Ch. %d Flags %x [%sGHz] - No traffic\n", 298 "Ch. %d Flags %x [%sGHz] - No traffic\n",
236 nvm_chan[ch_idx], 299 nvm_chan[ch_idx],
@@ -250,45 +313,6 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
250 ieee80211_channel_to_frequency( 313 ieee80211_channel_to_frequency(
251 channel->hw_value, channel->band); 314 channel->hw_value, channel->band);
252 315
253 /* TODO: Need to be dependent to the NVM */
254 channel->flags = IEEE80211_CHAN_NO_HT40;
255 if (ch_idx < num_2ghz_channels &&
256 (ch_flags & NVM_CHANNEL_40MHZ)) {
257 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
258 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
259 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
260 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
261 } else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
262 (ch_flags & NVM_CHANNEL_40MHZ)) {
263 if ((ch_idx - num_2ghz_channels) % 2 == 0)
264 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
265 else
266 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
267 }
268 if (!(ch_flags & NVM_CHANNEL_80MHZ))
269 channel->flags |= IEEE80211_CHAN_NO_80MHZ;
270 if (!(ch_flags & NVM_CHANNEL_160MHZ))
271 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
272
273 if (!(ch_flags & NVM_CHANNEL_IBSS))
274 channel->flags |= IEEE80211_CHAN_NO_IR;
275
276 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
277 channel->flags |= IEEE80211_CHAN_NO_IR;
278
279 if (ch_flags & NVM_CHANNEL_RADAR)
280 channel->flags |= IEEE80211_CHAN_RADAR;
281
282 if (ch_flags & NVM_CHANNEL_INDOOR_ONLY)
283 channel->flags |= IEEE80211_CHAN_INDOOR_ONLY;
284
285 /* Set the GO concurrent flag only in case that NO_IR is set.
286 * Otherwise it is meaningless
287 */
288 if ((ch_flags & NVM_CHANNEL_GO_CONCURRENT) &&
289 (channel->flags & IEEE80211_CHAN_NO_IR))
290 channel->flags |= IEEE80211_CHAN_GO_CONCURRENT;
291
292 /* Initialize regulatory-based run-time data */ 316 /* Initialize regulatory-based run-time data */
293 317
294 /* 318 /*
@@ -297,6 +321,15 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
297 */ 321 */
298 channel->max_power = IWL_DEFAULT_MAX_TX_POWER; 322 channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
299 is_5ghz = channel->band == IEEE80211_BAND_5GHZ; 323 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
324
325 /* don't put limitations in case we're using LAR */
326 if (!lar_supported)
327 channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
328 ch_idx, is_5ghz,
329 ch_flags, cfg);
330 else
331 channel->flags = 0;
332
300 IWL_DEBUG_EEPROM(dev, 333 IWL_DEBUG_EEPROM(dev,
301 "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", 334 "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
302 channel->hw_value, 335 channel->hw_value,
@@ -370,8 +403,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
370 403
371static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 404static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
372 struct iwl_nvm_data *data, 405 struct iwl_nvm_data *data,
373 const __le16 *ch_section, bool enable_vht, 406 const __le16 *ch_section,
374 u8 tx_chains, u8 rx_chains) 407 u8 tx_chains, u8 rx_chains, bool lar_supported)
375{ 408{
376 int n_channels; 409 int n_channels;
377 int n_used = 0; 410 int n_used = 0;
@@ -380,11 +413,12 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
380 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 413 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
381 n_channels = iwl_init_channel_map( 414 n_channels = iwl_init_channel_map(
382 dev, cfg, data, 415 dev, cfg, data,
383 &ch_section[NVM_CHANNELS]); 416 &ch_section[NVM_CHANNELS], lar_supported);
384 else 417 else
385 n_channels = iwl_init_channel_map( 418 n_channels = iwl_init_channel_map(
386 dev, cfg, data, 419 dev, cfg, data,
387 &ch_section[NVM_CHANNELS_FAMILY_8000]); 420 &ch_section[NVM_CHANNELS_FAMILY_8000],
421 lar_supported);
388 422
389 sband = &data->bands[IEEE80211_BAND_2GHZ]; 423 sband = &data->bands[IEEE80211_BAND_2GHZ];
390 sband->band = IEEE80211_BAND_2GHZ; 424 sband->band = IEEE80211_BAND_2GHZ;
@@ -403,7 +437,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
403 IEEE80211_BAND_5GHZ); 437 IEEE80211_BAND_5GHZ);
404 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ, 438 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
405 tx_chains, rx_chains); 439 tx_chains, rx_chains);
406 if (enable_vht) 440 if (data->sku_cap_11ac_enable)
407 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap, 441 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
408 tx_chains, rx_chains); 442 tx_chains, rx_chains);
409 443
@@ -413,10 +447,15 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
413} 447}
414 448
415static int iwl_get_sku(const struct iwl_cfg *cfg, 449static int iwl_get_sku(const struct iwl_cfg *cfg,
416 const __le16 *nvm_sw) 450 const __le16 *nvm_sw, const __le16 *phy_sku,
451 bool is_family_8000_a_step)
417{ 452{
418 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 453 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
419 return le16_to_cpup(nvm_sw + SKU); 454 return le16_to_cpup(nvm_sw + SKU);
455
456 if (!is_family_8000_a_step)
457 return le32_to_cpup((__le32 *)(phy_sku +
458 SKU_FAMILY_8000_B0));
420 else 459 else
421 return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000)); 460 return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
422} 461}
@@ -432,23 +471,36 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
432} 471}
433 472
434static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, 473static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
435 const __le16 *nvm_sw) 474 const __le16 *nvm_sw, const __le16 *phy_sku,
475 bool is_family_8000_a_step)
436{ 476{
437 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 477 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
438 return le16_to_cpup(nvm_sw + RADIO_CFG); 478 return le16_to_cpup(nvm_sw + RADIO_CFG);
479
480 if (!is_family_8000_a_step)
481 return le32_to_cpup((__le32 *)(phy_sku +
482 RADIO_CFG_FAMILY_8000_B0));
439 else 483 else
440 return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); 484 return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
485
441} 486}
442 487
443#define N_HW_ADDRS_MASK_FAMILY_8000 0xF
444static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, 488static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
445 const __le16 *nvm_sw) 489 const __le16 *nvm_sw, bool is_family_8000_a_step)
446{ 490{
491 int n_hw_addr;
492
447 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 493 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
448 return le16_to_cpup(nvm_sw + N_HW_ADDRS); 494 return le16_to_cpup(nvm_sw + N_HW_ADDRS);
495
496 if (!is_family_8000_a_step)
497 n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw +
498 N_HW_ADDRS_FAMILY_8000_B0));
449 else 499 else
450 return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)) 500 n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw +
451 & N_HW_ADDRS_MASK_FAMILY_8000; 501 N_HW_ADDRS_FAMILY_8000));
502
503 return n_hw_addr & N_HW_ADDR_MASK;
452} 504}
453 505
454static void iwl_set_radio_cfg(const struct iwl_cfg *cfg, 506static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
@@ -491,7 +543,8 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
491 const struct iwl_cfg *cfg, 543 const struct iwl_cfg *cfg,
492 struct iwl_nvm_data *data, 544 struct iwl_nvm_data *data,
493 const __le16 *mac_override, 545 const __le16 *mac_override,
494 const __le16 *nvm_hw) 546 const __le16 *nvm_hw,
547 u32 mac_addr0, u32 mac_addr1)
495{ 548{
496 const u8 *hw_addr; 549 const u8 *hw_addr;
497 550
@@ -515,48 +568,17 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
515 } 568 }
516 569
517 if (nvm_hw) { 570 if (nvm_hw) {
518 /* read the MAC address from OTP */ 571 /* read the MAC address from HW resisters */
519 if (!dev_is_pci(dev) || (data->nvm_version < 0xE08)) { 572 hw_addr = (const u8 *)&mac_addr0;
520 /* read the mac address from the WFPM location */ 573 data->hw_addr[0] = hw_addr[3];
521 hw_addr = (const u8 *)(nvm_hw + 574 data->hw_addr[1] = hw_addr[2];
522 HW_ADDR0_WFPM_FAMILY_8000); 575 data->hw_addr[2] = hw_addr[1];
523 data->hw_addr[0] = hw_addr[3]; 576 data->hw_addr[3] = hw_addr[0];
524 data->hw_addr[1] = hw_addr[2]; 577
525 data->hw_addr[2] = hw_addr[1]; 578 hw_addr = (const u8 *)&mac_addr1;
526 data->hw_addr[3] = hw_addr[0]; 579 data->hw_addr[4] = hw_addr[1];
527 580 data->hw_addr[5] = hw_addr[0];
528 hw_addr = (const u8 *)(nvm_hw + 581
529 HW_ADDR1_WFPM_FAMILY_8000);
530 data->hw_addr[4] = hw_addr[1];
531 data->hw_addr[5] = hw_addr[0];
532 } else if ((data->nvm_version >= 0xE08) &&
533 (data->nvm_version < 0xE0B)) {
534 /* read "reverse order" from the PCIe location */
535 hw_addr = (const u8 *)(nvm_hw +
536 HW_ADDR0_PCIE_FAMILY_8000);
537 data->hw_addr[5] = hw_addr[2];
538 data->hw_addr[4] = hw_addr[1];
539 data->hw_addr[3] = hw_addr[0];
540
541 hw_addr = (const u8 *)(nvm_hw +
542 HW_ADDR1_PCIE_FAMILY_8000);
543 data->hw_addr[2] = hw_addr[3];
544 data->hw_addr[1] = hw_addr[2];
545 data->hw_addr[0] = hw_addr[1];
546 } else {
547 /* read from the PCIe location */
548 hw_addr = (const u8 *)(nvm_hw +
549 HW_ADDR0_PCIE_FAMILY_8000);
550 data->hw_addr[5] = hw_addr[0];
551 data->hw_addr[4] = hw_addr[1];
552 data->hw_addr[3] = hw_addr[2];
553
554 hw_addr = (const u8 *)(nvm_hw +
555 HW_ADDR1_PCIE_FAMILY_8000);
556 data->hw_addr[2] = hw_addr[1];
557 data->hw_addr[1] = hw_addr[2];
558 data->hw_addr[0] = hw_addr[3];
559 }
560 if (!is_valid_ether_addr(data->hw_addr)) 582 if (!is_valid_ether_addr(data->hw_addr))
561 IWL_ERR_DEV(dev, 583 IWL_ERR_DEV(dev,
562 "mac address from hw section is not valid\n"); 584 "mac address from hw section is not valid\n");
@@ -571,11 +593,15 @@ struct iwl_nvm_data *
571iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 593iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
572 const __le16 *nvm_hw, const __le16 *nvm_sw, 594 const __le16 *nvm_hw, const __le16 *nvm_sw,
573 const __le16 *nvm_calib, const __le16 *regulatory, 595 const __le16 *nvm_calib, const __le16 *regulatory,
574 const __le16 *mac_override, u8 tx_chains, u8 rx_chains) 596 const __le16 *mac_override, const __le16 *phy_sku,
597 u8 tx_chains, u8 rx_chains,
598 bool lar_fw_supported, bool is_family_8000_a_step,
599 u32 mac_addr0, u32 mac_addr1)
575{ 600{
576 struct iwl_nvm_data *data; 601 struct iwl_nvm_data *data;
577 u32 sku; 602 u32 sku;
578 u32 radio_cfg; 603 u32 radio_cfg;
604 u16 lar_config;
579 605
580 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 606 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
581 data = kzalloc(sizeof(*data) + 607 data = kzalloc(sizeof(*data) +
@@ -592,22 +618,25 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
592 618
593 data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); 619 data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
594 620
595 radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw); 621 radio_cfg =
622 iwl_get_radio_cfg(cfg, nvm_sw, phy_sku, is_family_8000_a_step);
596 iwl_set_radio_cfg(cfg, data, radio_cfg); 623 iwl_set_radio_cfg(cfg, data, radio_cfg);
597 if (data->valid_tx_ant) 624 if (data->valid_tx_ant)
598 tx_chains &= data->valid_tx_ant; 625 tx_chains &= data->valid_tx_ant;
599 if (data->valid_rx_ant) 626 if (data->valid_rx_ant)
600 rx_chains &= data->valid_rx_ant; 627 rx_chains &= data->valid_rx_ant;
601 628
602 sku = iwl_get_sku(cfg, nvm_sw); 629 sku = iwl_get_sku(cfg, nvm_sw, phy_sku, is_family_8000_a_step);
603 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; 630 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
604 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; 631 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
605 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; 632 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
606 data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE;
607 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) 633 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
608 data->sku_cap_11n_enable = false; 634 data->sku_cap_11n_enable = false;
635 data->sku_cap_11ac_enable = data->sku_cap_11n_enable &&
636 (sku & NVM_SKU_CAP_11AC_ENABLE);
609 637
610 data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); 638 data->n_hw_addrs =
639 iwl_get_n_hw_addrs(cfg, nvm_sw, is_family_8000_a_step);
611 640
612 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { 641 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
613 /* Checking for required sections */ 642 /* Checking for required sections */
@@ -626,16 +655,23 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
626 iwl_set_hw_address(cfg, data, nvm_hw); 655 iwl_set_hw_address(cfg, data, nvm_hw);
627 656
628 iwl_init_sbands(dev, cfg, data, nvm_sw, 657 iwl_init_sbands(dev, cfg, data, nvm_sw,
629 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, 658 tx_chains, rx_chains, lar_fw_supported);
630 rx_chains);
631 } else { 659 } else {
660 u16 lar_offset = data->nvm_version < 0xE39 ?
661 NVM_LAR_OFFSET_FAMILY_8000_OLD :
662 NVM_LAR_OFFSET_FAMILY_8000;
663
664 lar_config = le16_to_cpup(regulatory + lar_offset);
665 data->lar_enabled = !!(lar_config &
666 NVM_LAR_ENABLED_FAMILY_8000);
667
632 /* MAC address in family 8000 */ 668 /* MAC address in family 8000 */
633 iwl_set_hw_address_family_8000(dev, cfg, data, mac_override, 669 iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
634 nvm_hw); 670 nvm_hw, mac_addr0, mac_addr1);
635 671
636 iwl_init_sbands(dev, cfg, data, regulatory, 672 iwl_init_sbands(dev, cfg, data, regulatory,
637 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, 673 tx_chains, rx_chains,
638 rx_chains); 674 lar_fw_supported && data->lar_enabled);
639 } 675 }
640 676
641 data->calib_version = 255; 677 data->calib_version = 255;
@@ -643,3 +679,164 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
643 return data; 679 return data;
644} 680}
645IWL_EXPORT_SYMBOL(iwl_parse_nvm_data); 681IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
682
683static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
684 int ch_idx, u16 nvm_flags,
685 const struct iwl_cfg *cfg)
686{
687 u32 flags = NL80211_RRF_NO_HT40;
688 u32 last_5ghz_ht = LAST_5GHZ_HT;
689
690 if (cfg->device_family == IWL_DEVICE_FAMILY_8000)
691 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
692
693 if (ch_idx < NUM_2GHZ_CHANNELS &&
694 (nvm_flags & NVM_CHANNEL_40MHZ)) {
695 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
696 flags &= ~NL80211_RRF_NO_HT40PLUS;
697 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
698 flags &= ~NL80211_RRF_NO_HT40MINUS;
699 } else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
700 (nvm_flags & NVM_CHANNEL_40MHZ)) {
701 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
702 flags &= ~NL80211_RRF_NO_HT40PLUS;
703 else
704 flags &= ~NL80211_RRF_NO_HT40MINUS;
705 }
706
707 if (!(nvm_flags & NVM_CHANNEL_80MHZ))
708 flags |= NL80211_RRF_NO_80MHZ;
709 if (!(nvm_flags & NVM_CHANNEL_160MHZ))
710 flags |= NL80211_RRF_NO_160MHZ;
711
712 if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
713 flags |= NL80211_RRF_NO_IR;
714
715 if (nvm_flags & NVM_CHANNEL_RADAR)
716 flags |= NL80211_RRF_DFS;
717
718 if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
719 flags |= NL80211_RRF_NO_OUTDOOR;
720
721 /* Set the GO concurrent flag only in case that NO_IR is set.
722 * Otherwise it is meaningless
723 */
724 if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
725 (flags & NL80211_RRF_NO_IR))
726 flags |= NL80211_RRF_GO_CONCURRENT;
727
728 return flags;
729}
730
731struct ieee80211_regdomain *
732iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
733 int num_of_ch, __le32 *channels, u16 fw_mcc)
734{
735 int ch_idx;
736 u16 ch_flags, prev_ch_flags = 0;
737 const u8 *nvm_chan = cfg->device_family == IWL_DEVICE_FAMILY_8000 ?
738 iwl_nvm_channels_family_8000 : iwl_nvm_channels;
739 struct ieee80211_regdomain *regd;
740 int size_of_regd;
741 struct ieee80211_reg_rule *rule;
742 enum ieee80211_band band;
743 int center_freq, prev_center_freq = 0;
744 int valid_rules = 0;
745 bool new_rule;
746 int max_num_ch = cfg->device_family == IWL_DEVICE_FAMILY_8000 ?
747 IWL_NUM_CHANNELS_FAMILY_8000 : IWL_NUM_CHANNELS;
748
749 if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
750 return ERR_PTR(-EINVAL);
751
752 if (WARN_ON(num_of_ch > max_num_ch))
753 num_of_ch = max_num_ch;
754
755 IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n",
756 num_of_ch);
757
758 /* build a regdomain rule for every valid channel */
759 size_of_regd =
760 sizeof(struct ieee80211_regdomain) +
761 num_of_ch * sizeof(struct ieee80211_reg_rule);
762
763 regd = kzalloc(size_of_regd, GFP_KERNEL);
764 if (!regd)
765 return ERR_PTR(-ENOMEM);
766
767 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
768 ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
769 band = (ch_idx < NUM_2GHZ_CHANNELS) ?
770 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
771 center_freq = ieee80211_channel_to_frequency(nvm_chan[ch_idx],
772 band);
773 new_rule = false;
774
775 if (!(ch_flags & NVM_CHANNEL_VALID)) {
776 IWL_DEBUG_DEV(dev, IWL_DL_LAR,
777 "Ch. %d Flags %x [%sGHz] - No traffic\n",
778 nvm_chan[ch_idx],
779 ch_flags,
780 (ch_idx >= NUM_2GHZ_CHANNELS) ?
781 "5.2" : "2.4");
782 continue;
783 }
784
785 /* we can't continue the same rule */
786 if (ch_idx == 0 || prev_ch_flags != ch_flags ||
787 center_freq - prev_center_freq > 20) {
788 valid_rules++;
789 new_rule = true;
790 }
791
792 rule = &regd->reg_rules[valid_rules - 1];
793
794 if (new_rule)
795 rule->freq_range.start_freq_khz =
796 MHZ_TO_KHZ(center_freq - 10);
797
798 rule->freq_range.end_freq_khz = MHZ_TO_KHZ(center_freq + 10);
799
800 /* this doesn't matter - not used by FW */
801 rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
802 rule->power_rule.max_eirp =
803 DBM_TO_MBM(IWL_DEFAULT_MAX_TX_POWER);
804
805 rule->flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
806 ch_flags, cfg);
807
808 /* rely on auto-calculation to merge BW of contiguous chans */
809 rule->flags |= NL80211_RRF_AUTO_BW;
810 rule->freq_range.max_bandwidth_khz = 0;
811
812 prev_ch_flags = ch_flags;
813 prev_center_freq = center_freq;
814
815 IWL_DEBUG_DEV(dev, IWL_DL_LAR,
816 "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x): Ad-Hoc %ssupported\n",
817 center_freq,
818 band == IEEE80211_BAND_5GHZ ? "5.2" : "2.4",
819 CHECK_AND_PRINT_I(VALID),
820 CHECK_AND_PRINT_I(ACTIVE),
821 CHECK_AND_PRINT_I(RADAR),
822 CHECK_AND_PRINT_I(WIDE),
823 CHECK_AND_PRINT_I(40MHZ),
824 CHECK_AND_PRINT_I(80MHZ),
825 CHECK_AND_PRINT_I(160MHZ),
826 CHECK_AND_PRINT_I(INDOOR_ONLY),
827 CHECK_AND_PRINT_I(GO_CONCURRENT),
828 ch_flags,
829 ((ch_flags & NVM_CHANNEL_ACTIVE) &&
830 !(ch_flags & NVM_CHANNEL_RADAR))
831 ? "" : "not ");
832 }
833
834 regd->n_reg_rules = valid_rules;
835
836 /* set alpha2 from FW. */
837 regd->alpha2[0] = fw_mcc >> 8;
838 regd->alpha2[1] = fw_mcc & 0xff;
839
840 return regd;
841}
842IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info);