diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 137 |
1 files changed, 62 insertions, 75 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 3014beef4873..c3a5d8ccc95e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | |||
@@ -77,7 +77,7 @@ | |||
77 | #include "iwl-csr.h" | 77 | #include "iwl-csr.h" |
78 | 78 | ||
79 | /* NVM offsets (in words) definitions */ | 79 | /* NVM offsets (in words) definitions */ |
80 | enum wkp_nvm_offsets { | 80 | enum nvm_offsets { |
81 | /* NVM HW-Section offset (in words) definitions */ | 81 | /* NVM HW-Section offset (in words) definitions */ |
82 | SUBSYSTEM_ID = 0x0A, | 82 | SUBSYSTEM_ID = 0x0A, |
83 | HW_ADDR = 0x15, | 83 | HW_ADDR = 0x15, |
@@ -92,7 +92,10 @@ enum wkp_nvm_offsets { | |||
92 | 92 | ||
93 | /* NVM calibration section offset (in words) definitions */ | 93 | /* NVM calibration section offset (in words) definitions */ |
94 | NVM_CALIB_SECTION = 0x2B8, | 94 | NVM_CALIB_SECTION = 0x2B8, |
95 | XTAL_CALIB = 0x316 - NVM_CALIB_SECTION | 95 | XTAL_CALIB = 0x316 - NVM_CALIB_SECTION, |
96 | |||
97 | /* NVM REGULATORY -Section offset (in words) definitions */ | ||
98 | NVM_CHANNELS_SDP = 0, | ||
96 | }; | 99 | }; |
97 | 100 | ||
98 | enum ext_nvm_offsets { | 101 | enum ext_nvm_offsets { |
@@ -206,8 +209,36 @@ enum iwl_nvm_channel_flags { | |||
206 | NVM_CHANNEL_DC_HIGH = BIT(12), | 209 | NVM_CHANNEL_DC_HIGH = BIT(12), |
207 | }; | 210 | }; |
208 | 211 | ||
212 | static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, | ||
213 | int chan, u16 flags) | ||
214 | { | ||
209 | #define CHECK_AND_PRINT_I(x) \ | 215 | #define CHECK_AND_PRINT_I(x) \ |
210 | ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") | 216 | ((flags & NVM_CHANNEL_##x) ? " " #x : "") |
217 | |||
218 | if (!(flags & NVM_CHANNEL_VALID)) { | ||
219 | IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n", | ||
220 | chan, flags); | ||
221 | return; | ||
222 | } | ||
223 | |||
224 | /* Note: already can print up to 101 characters, 110 is the limit! */ | ||
225 | IWL_DEBUG_DEV(dev, level, | ||
226 | "Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n", | ||
227 | chan, flags, | ||
228 | CHECK_AND_PRINT_I(VALID), | ||
229 | CHECK_AND_PRINT_I(IBSS), | ||
230 | CHECK_AND_PRINT_I(ACTIVE), | ||
231 | CHECK_AND_PRINT_I(RADAR), | ||
232 | CHECK_AND_PRINT_I(INDOOR_ONLY), | ||
233 | CHECK_AND_PRINT_I(GO_CONCURRENT), | ||
234 | CHECK_AND_PRINT_I(UNIFORM), | ||
235 | CHECK_AND_PRINT_I(20MHZ), | ||
236 | CHECK_AND_PRINT_I(40MHZ), | ||
237 | CHECK_AND_PRINT_I(80MHZ), | ||
238 | CHECK_AND_PRINT_I(160MHZ), | ||
239 | CHECK_AND_PRINT_I(DC_HIGH)); | ||
240 | #undef CHECK_AND_PRINT_I | ||
241 | } | ||
211 | 242 | ||
212 | static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, | 243 | static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, |
213 | u16 nvm_flags, const struct iwl_cfg *cfg) | 244 | u16 nvm_flags, const struct iwl_cfg *cfg) |
@@ -215,7 +246,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, | |||
215 | u32 flags = IEEE80211_CHAN_NO_HT40; | 246 | u32 flags = IEEE80211_CHAN_NO_HT40; |
216 | u32 last_5ghz_ht = LAST_5GHZ_HT; | 247 | u32 last_5ghz_ht = LAST_5GHZ_HT; |
217 | 248 | ||
218 | if (cfg->ext_nvm) | 249 | if (cfg->nvm_type == IWL_NVM_EXT) |
219 | last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; | 250 | last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; |
220 | 251 | ||
221 | if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) { | 252 | if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) { |
@@ -268,7 +299,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
268 | int num_of_ch, num_2ghz_channels; | 299 | int num_of_ch, num_2ghz_channels; |
269 | const u8 *nvm_chan; | 300 | const u8 *nvm_chan; |
270 | 301 | ||
271 | if (!cfg->ext_nvm) { | 302 | if (cfg->nvm_type != IWL_NVM_EXT) { |
272 | num_of_ch = IWL_NUM_CHANNELS; | 303 | num_of_ch = IWL_NUM_CHANNELS; |
273 | nvm_chan = &iwl_nvm_channels[0]; | 304 | nvm_chan = &iwl_nvm_channels[0]; |
274 | num_2ghz_channels = NUM_2GHZ_CHANNELS; | 305 | num_2ghz_channels = NUM_2GHZ_CHANNELS; |
@@ -302,12 +333,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
302 | * supported, hence we still want to add them to | 333 | * supported, hence we still want to add them to |
303 | * the list of supported channels to cfg80211. | 334 | * the list of supported channels to cfg80211. |
304 | */ | 335 | */ |
305 | IWL_DEBUG_EEPROM(dev, | 336 | iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, |
306 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | 337 | nvm_chan[ch_idx], ch_flags); |
307 | nvm_chan[ch_idx], | ||
308 | ch_flags, | ||
309 | (ch_idx >= num_2ghz_channels) ? | ||
310 | "5.2" : "2.4"); | ||
311 | continue; | 338 | continue; |
312 | } | 339 | } |
313 | 340 | ||
@@ -337,27 +364,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
337 | else | 364 | else |
338 | channel->flags = 0; | 365 | channel->flags = 0; |
339 | 366 | ||
340 | IWL_DEBUG_EEPROM(dev, | 367 | iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, |
341 | "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n", | 368 | channel->hw_value, ch_flags); |
342 | channel->hw_value, | 369 | IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n", |
343 | is_5ghz ? "5.2" : "2.4", | 370 | channel->hw_value, channel->max_power); |
344 | ch_flags, | ||
345 | CHECK_AND_PRINT_I(VALID), | ||
346 | CHECK_AND_PRINT_I(IBSS), | ||
347 | CHECK_AND_PRINT_I(ACTIVE), | ||
348 | CHECK_AND_PRINT_I(RADAR), | ||
349 | CHECK_AND_PRINT_I(INDOOR_ONLY), | ||
350 | CHECK_AND_PRINT_I(GO_CONCURRENT), | ||
351 | CHECK_AND_PRINT_I(UNIFORM), | ||
352 | CHECK_AND_PRINT_I(20MHZ), | ||
353 | CHECK_AND_PRINT_I(40MHZ), | ||
354 | CHECK_AND_PRINT_I(80MHZ), | ||
355 | CHECK_AND_PRINT_I(160MHZ), | ||
356 | CHECK_AND_PRINT_I(DC_HIGH), | ||
357 | channel->max_power, | ||
358 | ((ch_flags & NVM_CHANNEL_IBSS) && | ||
359 | !(ch_flags & NVM_CHANNEL_RADAR)) | ||
360 | ? "" : "not "); | ||
361 | } | 371 | } |
362 | 372 | ||
363 | return n_channels; | 373 | return n_channels; |
@@ -484,7 +494,7 @@ IWL_EXPORT_SYMBOL(iwl_init_sbands); | |||
484 | static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, | 494 | static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, |
485 | const __le16 *phy_sku) | 495 | const __le16 *phy_sku) |
486 | { | 496 | { |
487 | if (!cfg->ext_nvm) | 497 | if (cfg->nvm_type != IWL_NVM_EXT) |
488 | return le16_to_cpup(nvm_sw + SKU); | 498 | return le16_to_cpup(nvm_sw + SKU); |
489 | 499 | ||
490 | return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); | 500 | return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); |
@@ -492,7 +502,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, | |||
492 | 502 | ||
493 | static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) | 503 | static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) |
494 | { | 504 | { |
495 | if (!cfg->ext_nvm) | 505 | if (cfg->nvm_type != IWL_NVM_EXT) |
496 | return le16_to_cpup(nvm_sw + NVM_VERSION); | 506 | return le16_to_cpup(nvm_sw + NVM_VERSION); |
497 | else | 507 | else |
498 | return le32_to_cpup((__le32 *)(nvm_sw + | 508 | return le32_to_cpup((__le32 *)(nvm_sw + |
@@ -502,7 +512,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) | |||
502 | static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, | 512 | static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, |
503 | const __le16 *phy_sku) | 513 | const __le16 *phy_sku) |
504 | { | 514 | { |
505 | if (!cfg->ext_nvm) | 515 | if (cfg->nvm_type != IWL_NVM_EXT) |
506 | return le16_to_cpup(nvm_sw + RADIO_CFG); | 516 | return le16_to_cpup(nvm_sw + RADIO_CFG); |
507 | 517 | ||
508 | return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM)); | 518 | return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM)); |
@@ -513,7 +523,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) | |||
513 | { | 523 | { |
514 | int n_hw_addr; | 524 | int n_hw_addr; |
515 | 525 | ||
516 | if (!cfg->ext_nvm) | 526 | if (cfg->nvm_type != IWL_NVM_EXT) |
517 | return le16_to_cpup(nvm_sw + N_HW_ADDRS); | 527 | return le16_to_cpup(nvm_sw + N_HW_ADDRS); |
518 | 528 | ||
519 | n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); | 529 | n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); |
@@ -525,7 +535,7 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg, | |||
525 | struct iwl_nvm_data *data, | 535 | struct iwl_nvm_data *data, |
526 | u32 radio_cfg) | 536 | u32 radio_cfg) |
527 | { | 537 | { |
528 | if (!cfg->ext_nvm) { | 538 | if (cfg->nvm_type != IWL_NVM_EXT) { |
529 | data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); | 539 | data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); |
530 | data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg); | 540 | data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg); |
531 | data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); | 541 | data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); |
@@ -634,7 +644,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans, | |||
634 | { | 644 | { |
635 | if (cfg->mac_addr_from_csr) { | 645 | if (cfg->mac_addr_from_csr) { |
636 | iwl_set_hw_address_from_csr(trans, data); | 646 | iwl_set_hw_address_from_csr(trans, data); |
637 | } else if (!cfg->ext_nvm) { | 647 | } else if (cfg->nvm_type != IWL_NVM_EXT) { |
638 | const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR); | 648 | const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR); |
639 | 649 | ||
640 | /* The byte order is little endian 16 bit, meaning 214365 */ | 650 | /* The byte order is little endian 16 bit, meaning 214365 */ |
@@ -706,7 +716,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
706 | u16 lar_config; | 716 | u16 lar_config; |
707 | const __le16 *ch_section; | 717 | const __le16 *ch_section; |
708 | 718 | ||
709 | if (!cfg->ext_nvm) | 719 | if (cfg->nvm_type != IWL_NVM_EXT) |
710 | data = kzalloc(sizeof(*data) + | 720 | data = kzalloc(sizeof(*data) + |
711 | sizeof(struct ieee80211_channel) * | 721 | sizeof(struct ieee80211_channel) * |
712 | IWL_NUM_CHANNELS, | 722 | IWL_NUM_CHANNELS, |
@@ -740,7 +750,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
740 | 750 | ||
741 | data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); | 751 | data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); |
742 | 752 | ||
743 | if (!cfg->ext_nvm) { | 753 | if (cfg->nvm_type != IWL_NVM_EXT) { |
744 | /* Checking for required sections */ | 754 | /* Checking for required sections */ |
745 | if (!nvm_calib) { | 755 | if (!nvm_calib) { |
746 | IWL_ERR(trans, | 756 | IWL_ERR(trans, |
@@ -748,11 +758,15 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
748 | kfree(data); | 758 | kfree(data); |
749 | return NULL; | 759 | return NULL; |
750 | } | 760 | } |
761 | |||
762 | ch_section = cfg->nvm_type == IWL_NVM_SDP ? | ||
763 | ®ulatory[NVM_CHANNELS_SDP] : | ||
764 | &nvm_sw[NVM_CHANNELS]; | ||
765 | |||
751 | /* in family 8000 Xtal calibration values moved to OTP */ | 766 | /* in family 8000 Xtal calibration values moved to OTP */ |
752 | data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); | 767 | data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); |
753 | data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); | 768 | data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); |
754 | lar_enabled = true; | 769 | lar_enabled = true; |
755 | ch_section = &nvm_sw[NVM_CHANNELS]; | ||
756 | } else { | 770 | } else { |
757 | u16 lar_offset = data->nvm_version < 0xE39 ? | 771 | u16 lar_offset = data->nvm_version < 0xE39 ? |
758 | NVM_LAR_OFFSET_OLD : | 772 | NVM_LAR_OFFSET_OLD : |
@@ -786,7 +800,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan, | |||
786 | u32 flags = NL80211_RRF_NO_HT40; | 800 | u32 flags = NL80211_RRF_NO_HT40; |
787 | u32 last_5ghz_ht = LAST_5GHZ_HT; | 801 | u32 last_5ghz_ht = LAST_5GHZ_HT; |
788 | 802 | ||
789 | if (cfg->ext_nvm) | 803 | if (cfg->nvm_type == IWL_NVM_EXT) |
790 | last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; | 804 | last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; |
791 | 805 | ||
792 | if (ch_idx < NUM_2GHZ_CHANNELS && | 806 | if (ch_idx < NUM_2GHZ_CHANNELS && |
@@ -834,7 +848,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | |||
834 | int ch_idx; | 848 | int ch_idx; |
835 | u16 ch_flags; | 849 | u16 ch_flags; |
836 | u32 reg_rule_flags, prev_reg_rule_flags = 0; | 850 | u32 reg_rule_flags, prev_reg_rule_flags = 0; |
837 | const u8 *nvm_chan = cfg->ext_nvm ? | 851 | const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? |
838 | iwl_ext_nvm_channels : iwl_nvm_channels; | 852 | iwl_ext_nvm_channels : iwl_nvm_channels; |
839 | struct ieee80211_regdomain *regd; | 853 | struct ieee80211_regdomain *regd; |
840 | int size_of_regd; | 854 | int size_of_regd; |
@@ -843,7 +857,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | |||
843 | int center_freq, prev_center_freq = 0; | 857 | int center_freq, prev_center_freq = 0; |
844 | int valid_rules = 0; | 858 | int valid_rules = 0; |
845 | bool new_rule; | 859 | bool new_rule; |
846 | int max_num_ch = cfg->ext_nvm ? | 860 | int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? |
847 | IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; | 861 | IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; |
848 | 862 | ||
849 | if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) | 863 | if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) |
@@ -873,12 +887,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | |||
873 | new_rule = false; | 887 | new_rule = false; |
874 | 888 | ||
875 | if (!(ch_flags & NVM_CHANNEL_VALID)) { | 889 | if (!(ch_flags & NVM_CHANNEL_VALID)) { |
876 | IWL_DEBUG_DEV(dev, IWL_DL_LAR, | 890 | iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, |
877 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | 891 | nvm_chan[ch_idx], ch_flags); |
878 | nvm_chan[ch_idx], | ||
879 | ch_flags, | ||
880 | (ch_idx >= NUM_2GHZ_CHANNELS) ? | ||
881 | "5.2" : "2.4"); | ||
882 | continue; | 892 | continue; |
883 | } | 893 | } |
884 | 894 | ||
@@ -914,31 +924,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, | |||
914 | prev_center_freq = center_freq; | 924 | prev_center_freq = center_freq; |
915 | prev_reg_rule_flags = reg_rule_flags; | 925 | prev_reg_rule_flags = reg_rule_flags; |
916 | 926 | ||
917 | IWL_DEBUG_DEV(dev, IWL_DL_LAR, | 927 | iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, |
918 | "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x)\n", | 928 | nvm_chan[ch_idx], ch_flags); |
919 | center_freq, | ||
920 | band == NL80211_BAND_5GHZ ? "5.2" : "2.4", | ||
921 | CHECK_AND_PRINT_I(VALID), | ||
922 | CHECK_AND_PRINT_I(IBSS), | ||
923 | CHECK_AND_PRINT_I(ACTIVE), | ||
924 | CHECK_AND_PRINT_I(RADAR), | ||
925 | CHECK_AND_PRINT_I(INDOOR_ONLY), | ||
926 | CHECK_AND_PRINT_I(GO_CONCURRENT), | ||
927 | CHECK_AND_PRINT_I(UNIFORM), | ||
928 | CHECK_AND_PRINT_I(20MHZ), | ||
929 | CHECK_AND_PRINT_I(40MHZ), | ||
930 | CHECK_AND_PRINT_I(80MHZ), | ||
931 | CHECK_AND_PRINT_I(160MHZ), | ||
932 | CHECK_AND_PRINT_I(DC_HIGH), | ||
933 | ch_flags); | ||
934 | IWL_DEBUG_DEV(dev, IWL_DL_LAR, | ||
935 | "Ch. %d [%sGHz] reg_flags 0x%x: %s\n", | ||
936 | center_freq, | ||
937 | band == NL80211_BAND_5GHZ ? "5.2" : "2.4", | ||
938 | reg_rule_flags, | ||
939 | ((ch_flags & NVM_CHANNEL_ACTIVE) && | ||
940 | !(ch_flags & NVM_CHANNEL_RADAR)) | ||
941 | ? "Ad-Hoc" : ""); | ||
942 | } | 929 | } |
943 | 930 | ||
944 | regd->n_reg_rules = valid_rules; | 931 | regd->n_reg_rules = valid_rules; |