aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c137
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 */
80enum wkp_nvm_offsets { 80enum 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
98enum ext_nvm_offsets { 101enum 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
212static 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
212static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, 243static 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);
484static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, 494static 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
493static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) 503static 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)
502static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, 512static 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 &regulatory[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;