aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorEran Harary <eran.harary@intel.com>2014-02-04 07:21:38 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-02-13 06:49:37 -0500
commit77db0a3c27dc0f027e5f3956f4ba77246c89a548 (patch)
tree343938182601b80be4b451661e4efaa19fc35b6a /drivers/net/wireless
parent7303dd7f312f0d07a4bf45c62608d5233b5e8062 (diff)
iwlwifi: mvm: new NVM format in family 8000
Support the changes below: - Fields and sections structure were changed. - the NVM file built from DWord instead of Words. - sections header format was changed. Signed-off-by: Eran Harary <eran.harary@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c239
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c63
8 files changed, 271 insertions, 71 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index b3bc30b4292b..662d9936485c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -728,6 +728,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
728 if (tlv_len != sizeof(u32)) 728 if (tlv_len != sizeof(u32))
729 goto invalid_tlv_len; 729 goto invalid_tlv_len;
730 drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); 730 drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
731 drv->fw.valid_tx_ant = (drv->fw.phy_config &
732 FW_PHY_CFG_TX_CHAIN) >>
733 FW_PHY_CFG_TX_CHAIN_POS;
734 drv->fw.valid_rx_ant = (drv->fw.phy_config &
735 FW_PHY_CFG_RX_CHAIN) >>
736 FW_PHY_CFG_RX_CHAIN_POS;
731 break; 737 break;
732 case IWL_UCODE_TLV_SECURE_SEC_RT: 738 case IWL_UCODE_TLV_SECURE_SEC_RT:
733 iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, 739 iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 592c01e11013..3c72cb710b0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -70,6 +70,20 @@
70#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation" 70#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation"
71#define DRV_AUTHOR "<ilw@linux.intel.com>" 71#define DRV_AUTHOR "<ilw@linux.intel.com>"
72 72
73/* radio config bits (actual values from NVM definition) */
74#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
75#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
76#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
77#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
78#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
79#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
80
81#define NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(x) (x & 0xF)
82#define NVM_RF_CFG_DASH_MSK_FAMILY_8000(x) ((x >> 4) & 0xF)
83#define NVM_RF_CFG_STEP_MSK_FAMILY_8000(x) ((x >> 8) & 0xF)
84#define NVM_RF_CFG_TYPE_MSK_FAMILY_8000(x) ((x >> 12) & 0xFFF)
85#define NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(x) ((x >> 24) & 0xF)
86#define NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(x) ((x >> 28) & 0xF)
73 87
74/** 88/**
75 * DOC: Driver system flows - drv component 89 * DOC: Driver system flows - drv component
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index e3c7deafabe6..f0548b8a64b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -81,16 +81,17 @@ struct iwl_nvm_data {
81 bool sku_cap_band_24GHz_enable; 81 bool sku_cap_band_24GHz_enable;
82 bool sku_cap_band_52GHz_enable; 82 bool sku_cap_band_52GHz_enable;
83 bool sku_cap_11n_enable; 83 bool sku_cap_11n_enable;
84 bool sku_cap_11ac_enable;
84 bool sku_cap_amt_enable; 85 bool sku_cap_amt_enable;
85 bool sku_cap_ipan_enable; 86 bool sku_cap_ipan_enable;
86 87
87 u8 radio_cfg_type; 88 u16 radio_cfg_type;
88 u8 radio_cfg_step; 89 u8 radio_cfg_step;
89 u8 radio_cfg_dash; 90 u8 radio_cfg_dash;
90 u8 radio_cfg_pnum; 91 u8 radio_cfg_pnum;
91 u8 valid_tx_ant, valid_rx_ant; 92 u8 valid_tx_ant, valid_rx_ant;
92 93
93 u16 nvm_version; 94 u32 nvm_version;
94 s8 max_tx_pwr_half_dbm; 95 s8 max_tx_pwr_half_dbm;
95 96
96 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 97 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index b0d09987540d..73671072d0f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -288,6 +288,8 @@ struct iwl_fw {
288 288
289 struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX]; 289 struct iwl_tlv_calib_ctrl default_calib[IWL_UCODE_TYPE_MAX];
290 u32 phy_config; 290 u32 phy_config;
291 u8 valid_tx_ant;
292 u8 valid_rx_ant;
291 293
292 bool mvm_fw; 294 bool mvm_fw;
293 295
@@ -296,14 +298,12 @@ struct iwl_fw {
296 298
297static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw) 299static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
298{ 300{
299 return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >> 301 return fw->valid_tx_ant;
300 FW_PHY_CFG_TX_CHAIN_POS;
301} 302}
302 303
303static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw) 304static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
304{ 305{
305 return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >> 306 return fw->valid_rx_ant;
306 FW_PHY_CFG_RX_CHAIN_POS;
307} 307}
308 308
309#endif /* __iwl_fw_h__ */ 309#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 42780971aa04..df3ea60c87d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -71,7 +71,7 @@ enum wkp_nvm_offsets {
71 /* NVM HW-Section offset (in words) definitions */ 71 /* NVM HW-Section offset (in words) definitions */
72 HW_ADDR = 0x15, 72 HW_ADDR = 0x15,
73 73
74/* NVM SW-Section offset (in words) definitions */ 74 /* NVM SW-Section offset (in words) definitions */
75 NVM_SW_SECTION = 0x1C0, 75 NVM_SW_SECTION = 0x1C0,
76 NVM_VERSION = 0, 76 NVM_VERSION = 0,
77 RADIO_CFG = 1, 77 RADIO_CFG = 1,
@@ -79,11 +79,32 @@ enum wkp_nvm_offsets {
79 N_HW_ADDRS = 3, 79 N_HW_ADDRS = 3,
80 NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION, 80 NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
81 81
82/* NVM calibration section offset (in words) definitions */ 82 /* NVM calibration section offset (in words) definitions */
83 NVM_CALIB_SECTION = 0x2B8, 83 NVM_CALIB_SECTION = 0x2B8,
84 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION 84 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
85}; 85};
86 86
87enum family_8000_nvm_offsets {
88 /* NVM HW-Section offset (in words) definitions */
89 HW_ADDR0_FAMILY_8000 = 0x12,
90 HW_ADDR1_FAMILY_8000 = 0x16,
91 MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
92
93 /* NVM SW-Section offset (in words) definitions */
94 NVM_SW_SECTION_FAMILY_8000 = 0x1C0,
95 NVM_VERSION_FAMILY_8000 = 0,
96 RADIO_CFG_FAMILY_8000 = 2,
97 SKU_FAMILY_8000 = 4,
98 N_HW_ADDRS_FAMILY_8000 = 5,
99
100 /* NVM REGULATORY -Section offset (in words) definitions */
101 NVM_CHANNELS_FAMILY_8000 = 0,
102
103 /* NVM calibration section offset (in words) definitions */
104 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
105 XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
106};
107
87/* SKU Capabilities (actual values from NVM definition) */ 108/* SKU Capabilities (actual values from NVM definition) */
88enum nvm_sku_bits { 109enum nvm_sku_bits {
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0), 110 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
@@ -92,14 +113,6 @@ enum nvm_sku_bits {
92 NVM_SKU_CAP_11AC_ENABLE = BIT(3), 113 NVM_SKU_CAP_11AC_ENABLE = BIT(3),
93}; 114};
94 115
95/* radio config bits (actual values from NVM definition) */
96#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
97#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
98#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
99#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
100#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
101#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
102
103/* 116/*
104 * These are the channel numbers in the order that they are stored in the NVM 117 * These are the channel numbers in the order that they are stored in the NVM
105 */ 118 */
@@ -112,7 +125,17 @@ static const u8 iwl_nvm_channels[] = {
112 149, 153, 157, 161, 165 125 149, 153, 157, 161, 165
113}; 126};
114 127
128static const u8 iwl_nvm_channels_family_8000[] = {
129 /* 2.4 GHz */
130 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
131 /* 5 GHz */
132 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
133 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
134 149, 153, 157, 161, 165, 169, 173, 177, 181
135};
136
115#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) 137#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
138#define IWL_NUM_CHANNELS_FAMILY_8000 ARRAY_SIZE(iwl_nvm_channels_family_8000)
116#define NUM_2GHZ_CHANNELS 14 139#define NUM_2GHZ_CHANNELS 14
117#define FIRST_2GHZ_HT_MINUS 5 140#define FIRST_2GHZ_HT_MINUS 5
118#define LAST_2GHZ_HT_PLUS 9 141#define LAST_2GHZ_HT_PLUS 9
@@ -179,13 +202,23 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
179 struct ieee80211_channel *channel; 202 struct ieee80211_channel *channel;
180 u16 ch_flags; 203 u16 ch_flags;
181 bool is_5ghz; 204 bool is_5ghz;
205 int num_of_ch;
206 const u8 *nvm_chan;
207
208 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
209 num_of_ch = IWL_NUM_CHANNELS;
210 nvm_chan = &iwl_nvm_channels[0];
211 } else {
212 num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
213 nvm_chan = &iwl_nvm_channels_family_8000[0];
214 }
182 215
183 for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { 216 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
184 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); 217 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
185 if (!(ch_flags & NVM_CHANNEL_VALID)) { 218 if (!(ch_flags & NVM_CHANNEL_VALID)) {
186 IWL_DEBUG_EEPROM(dev, 219 IWL_DEBUG_EEPROM(dev,
187 "Ch. %d Flags %x [%sGHz] - No traffic\n", 220 "Ch. %d Flags %x [%sGHz] - No traffic\n",
188 iwl_nvm_channels[ch_idx], 221 nvm_chan[ch_idx],
189 ch_flags, 222 ch_flags,
190 (ch_idx >= NUM_2GHZ_CHANNELS) ? 223 (ch_idx >= NUM_2GHZ_CHANNELS) ?
191 "5.2" : "2.4"); 224 "5.2" : "2.4");
@@ -195,7 +228,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
195 channel = &data->channels[n_channels]; 228 channel = &data->channels[n_channels];
196 n_channels++; 229 n_channels++;
197 230
198 channel->hw_value = iwl_nvm_channels[ch_idx]; 231 channel->hw_value = nvm_chan[ch_idx];
199 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ? 232 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
200 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 233 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
201 channel->center_freq = 234 channel->center_freq =
@@ -206,11 +239,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
206 channel->flags = IEEE80211_CHAN_NO_HT40; 239 channel->flags = IEEE80211_CHAN_NO_HT40;
207 if (ch_idx < NUM_2GHZ_CHANNELS && 240 if (ch_idx < NUM_2GHZ_CHANNELS &&
208 (ch_flags & NVM_CHANNEL_40MHZ)) { 241 (ch_flags & NVM_CHANNEL_40MHZ)) {
209 if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS) 242 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
210 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; 243 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
211 if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS) 244 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
212 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; 245 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
213 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT && 246 } else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
214 (ch_flags & NVM_CHANNEL_40MHZ)) { 247 (ch_flags & NVM_CHANNEL_40MHZ)) {
215 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0) 248 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
216 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; 249 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
@@ -302,14 +335,23 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
302} 335}
303 336
304static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 337static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
305 struct iwl_nvm_data *data, const __le16 *nvm_sw, 338 struct iwl_nvm_data *data,
306 bool enable_vht, u8 tx_chains, u8 rx_chains) 339 const __le16 *ch_section, bool enable_vht,
340 u8 tx_chains, u8 rx_chains)
307{ 341{
308 int n_channels = iwl_init_channel_map(dev, cfg, data, 342 int n_channels;
309 &nvm_sw[NVM_CHANNELS]);
310 int n_used = 0; 343 int n_used = 0;
311 struct ieee80211_supported_band *sband; 344 struct ieee80211_supported_band *sband;
312 345
346 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
347 n_channels = iwl_init_channel_map(
348 dev, cfg, data,
349 &ch_section[NVM_CHANNELS]);
350 else
351 n_channels = iwl_init_channel_map(
352 dev, cfg, data,
353 &ch_section[NVM_CHANNELS_FAMILY_8000]);
354
313 sband = &data->bands[IEEE80211_BAND_2GHZ]; 355 sband = &data->bands[IEEE80211_BAND_2GHZ];
314 sband->band = IEEE80211_BAND_2GHZ; 356 sband->band = IEEE80211_BAND_2GHZ;
315 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; 357 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@@ -335,35 +377,122 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
335 n_used, n_channels); 377 n_used, n_channels);
336} 378}
337 379
380static int iwl_get_sku(const struct iwl_cfg *cfg,
381 const __le16 *nvm_sw)
382{
383 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
384 return le16_to_cpup(nvm_sw + SKU);
385 else
386 return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
387}
388
389static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
390 const __le16 *nvm_sw)
391{
392 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
393 return le16_to_cpup(nvm_sw + NVM_VERSION);
394 else
395 return le32_to_cpup((__le32 *)(nvm_sw +
396 NVM_VERSION_FAMILY_8000));
397}
398
399static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
400 const __le16 *nvm_sw)
401{
402 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
403 return le16_to_cpup(nvm_sw + RADIO_CFG);
404 else
405 return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
406}
407
408#define N_HW_ADDRS_MASK_FAMILY_8000 0xF
409static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
410 const __le16 *nvm_sw)
411{
412 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
413 return le16_to_cpup(nvm_sw + N_HW_ADDRS);
414 else
415 return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000))
416 & N_HW_ADDRS_MASK_FAMILY_8000;
417}
418
419static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
420 struct iwl_nvm_data *data,
421 u32 radio_cfg)
422{
423 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
424 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
425 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
426 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
427 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
428 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
429 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
430 return;
431 }
432
433 /* set the radio configuration for family 8000 */
434 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK_FAMILY_8000(radio_cfg);
435 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
436 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
437 data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
438 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(radio_cfg);
439 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(radio_cfg);
440}
441
442static void iwl_set_hw_address(const struct iwl_cfg *cfg,
443 struct iwl_nvm_data *data,
444 const __le16 *nvm_sec)
445{
446 u8 hw_addr[ETH_ALEN];
447
448 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
449 memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
450 else
451 memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
452 ETH_ALEN);
453
454 /* The byte order is little endian 16 bit, meaning 214365 */
455 data->hw_addr[0] = hw_addr[1];
456 data->hw_addr[1] = hw_addr[0];
457 data->hw_addr[2] = hw_addr[3];
458 data->hw_addr[3] = hw_addr[2];
459 data->hw_addr[4] = hw_addr[5];
460 data->hw_addr[5] = hw_addr[4];
461}
462
338struct iwl_nvm_data * 463struct iwl_nvm_data *
339iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 464iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
340 const __le16 *nvm_hw, const __le16 *nvm_sw, 465 const __le16 *nvm_hw, const __le16 *nvm_sw,
341 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains) 466 const __le16 *nvm_calib, const __le16 *regulatory,
467 const __le16 *mac_override, u8 tx_chains, u8 rx_chains)
342{ 468{
343 struct iwl_nvm_data *data; 469 struct iwl_nvm_data *data;
344 u8 hw_addr[ETH_ALEN]; 470 u32 sku;
345 u16 radio_cfg, sku; 471 u32 radio_cfg;
346 472
347 data = kzalloc(sizeof(*data) + 473 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
348 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, 474 data = kzalloc(sizeof(*data) +
349 GFP_KERNEL); 475 sizeof(struct ieee80211_channel) *
476 IWL_NUM_CHANNELS,
477 GFP_KERNEL);
478 else
479 data = kzalloc(sizeof(*data) +
480 sizeof(struct ieee80211_channel) *
481 IWL_NUM_CHANNELS_FAMILY_8000,
482 GFP_KERNEL);
350 if (!data) 483 if (!data)
351 return NULL; 484 return NULL;
352 485
353 data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION); 486 data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
354 487
355 radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG); 488 radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw);
356 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); 489 iwl_set_radio_cfg(cfg, data, radio_cfg);
357 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
358 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
359 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
360 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
361 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
362 490
363 sku = le16_to_cpup(nvm_sw + SKU); 491 sku = iwl_get_sku(cfg, nvm_sw);
364 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; 492 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
365 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; 493 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
366 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; 494 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
495 data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE;
367 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) 496 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
368 data->sku_cap_11n_enable = false; 497 data->sku_cap_11n_enable = false;
369 498
@@ -380,22 +509,34 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
380 return NULL; 509 return NULL;
381 } 510 }
382 511
383 data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS); 512 data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
384 513
385 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); 514 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
386 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); 515 /* Checking for required sections */
516 if (!nvm_calib) {
517 IWL_ERR_DEV(dev,
518 "Can't parse empty Calib NVM sections\n");
519 return NULL;
520 }
521 /* in family 8000 Xtal calibration values moved to OTP */
522 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
523 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
524 }
387 525
388 /* The byte order is little endian 16 bit, meaning 214365 */ 526 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
389 memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN); 527 iwl_set_hw_address(cfg, data, nvm_hw);
390 data->hw_addr[0] = hw_addr[1]; 528
391 data->hw_addr[1] = hw_addr[0]; 529 iwl_init_sbands(dev, cfg, data, nvm_sw,
392 data->hw_addr[2] = hw_addr[3]; 530 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
393 data->hw_addr[3] = hw_addr[2]; 531 rx_chains);
394 data->hw_addr[4] = hw_addr[5]; 532 } else {
395 data->hw_addr[5] = hw_addr[4]; 533 /* MAC address in family 8000 */
534 iwl_set_hw_address(cfg, data, mac_override);
396 535
397 iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE, 536 iwl_init_sbands(dev, cfg, data, regulatory,
398 tx_chains, rx_chains); 537 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
538 rx_chains);
539 }
399 540
400 data->calib_version = 255; 541 data->calib_version = 255;
401 542
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index 0c4399aba8c6..c9c45a39d212 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -75,6 +75,7 @@
75struct iwl_nvm_data * 75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw, 77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains); 78 const __le16 *nvm_calib, const __le16 *regulatory,
79 const __le16 *mac_override, u8 tx_chains, u8 rx_chains);
79 80
80#endif /* __iwl_nvm_parse_h__ */ 81#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index a7c88f1402e9..4d808a91ea7f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -306,7 +306,6 @@ struct iwl_phy_cfg_cmd {
306#define PHY_CFG_RX_CHAIN_B BIT(13) 306#define PHY_CFG_RX_CHAIN_B BIT(13)
307#define PHY_CFG_RX_CHAIN_C BIT(14) 307#define PHY_CFG_RX_CHAIN_C BIT(14)
308 308
309#define NVM_MAX_NUM_SECTIONS 11
310 309
311/* Target of the NVM_ACCESS_CMD */ 310/* Target of the NVM_ACCESS_CMD */
312enum { 311enum {
@@ -318,8 +317,11 @@ enum {
318/* Section types for NVM_ACCESS_CMD */ 317/* Section types for NVM_ACCESS_CMD */
319enum { 318enum {
320 NVM_SECTION_TYPE_SW = 1, 319 NVM_SECTION_TYPE_SW = 1,
320 NVM_SECTION_TYPE_REGULATORY = 3,
321 NVM_SECTION_TYPE_CALIBRATION = 4, 321 NVM_SECTION_TYPE_CALIBRATION = 4,
322 NVM_SECTION_TYPE_PRODUCTION = 5, 322 NVM_SECTION_TYPE_PRODUCTION = 5,
323 NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
324 NVM_MAX_NUM_SECTIONS = 12,
323}; 325};
324 326
325/** 327/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 2d5251b3600c..e80e81a3f828 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -228,13 +228,23 @@ static struct iwl_nvm_data *
228iwl_parse_nvm_sections(struct iwl_mvm *mvm) 228iwl_parse_nvm_sections(struct iwl_mvm *mvm)
229{ 229{
230 struct iwl_nvm_section *sections = mvm->nvm_sections; 230 struct iwl_nvm_section *sections = mvm->nvm_sections;
231 const __le16 *hw, *sw, *calib; 231 const __le16 *hw, *sw, *calib, *regulatory, *mac_override;
232 232
233 /* Checking for required sections */ 233 /* Checking for required sections */
234 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || 234 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
235 !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { 235 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
236 IWL_ERR(mvm, "Can't parse empty NVM sections\n"); 236 !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
237 return NULL; 237 IWL_ERR(mvm, "Can't parse empty NVM sections\n");
238 return NULL;
239 }
240 } else {
241 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
242 !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data ||
243 !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
244 IWL_ERR(mvm,
245 "Can't parse empty family 8000 NVM sections\n");
246 return NULL;
247 }
238 } 248 }
239 249
240 if (WARN_ON(!mvm->cfg)) 250 if (WARN_ON(!mvm->cfg))
@@ -243,7 +253,12 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
243 hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data; 253 hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
244 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 254 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
245 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 255 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
256 regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
257 mac_override =
258 (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data;
259
246 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib, 260 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
261 regulatory, mac_override,
247 iwl_fw_valid_tx_ant(mvm->fw), 262 iwl_fw_valid_tx_ant(mvm->fw),
248 iwl_fw_valid_rx_ant(mvm->fw)); 263 iwl_fw_valid_rx_ant(mvm->fw));
249} 264}
@@ -285,6 +300,8 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
285 300
286#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) 301#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
287#define NVM_WORD2_ID(x) (x >> 12) 302#define NVM_WORD2_ID(x) (x >> 12)
303#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8))
304#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4)
288 305
289 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); 306 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
290 307
@@ -335,8 +352,16 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
335 break; 352 break;
336 } 353 }
337 354
338 section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1)); 355 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
339 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2)); 356 section_size =
357 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
358 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
359 } else {
360 section_size = 2 * NVM_WORD2_LEN_FAMILY_8000(
361 le16_to_cpu(file_sec->word2));
362 section_id = NVM_WORD1_ID_FAMILY_8000(
363 le16_to_cpu(file_sec->word1));
364 }
340 365
341 if (section_size > IWL_MAX_NVM_SECTION_SIZE) { 366 if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
342 IWL_ERR(mvm, "ERROR - section too large (%d)\n", 367 IWL_ERR(mvm, "ERROR - section too large (%d)\n",
@@ -406,6 +431,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
406{ 431{
407 int ret, i, section; 432 int ret, i, section;
408 u8 *nvm_buffer, *temp; 433 u8 *nvm_buffer, *temp;
434 int nvm_to_read[NVM_MAX_NUM_SECTIONS];
435 int num_of_sections_to_read;
409 436
410 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) 437 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
411 return -EINVAL; 438 return -EINVAL;
@@ -418,12 +445,20 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
418 return ret; 445 return ret;
419 } else { 446 } else {
420 /* list of NVM sections we are allowed/need to read */ 447 /* list of NVM sections we are allowed/need to read */
421 int nvm_to_read[] = { 448 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
422 mvm->cfg->nvm_hw_section_num, 449 nvm_to_read[0] = mvm->cfg->nvm_hw_section_num;
423 NVM_SECTION_TYPE_SW, 450 nvm_to_read[1] = NVM_SECTION_TYPE_SW;
424 NVM_SECTION_TYPE_CALIBRATION, 451 nvm_to_read[2] = NVM_SECTION_TYPE_CALIBRATION;
425 NVM_SECTION_TYPE_PRODUCTION, 452 nvm_to_read[3] = NVM_SECTION_TYPE_PRODUCTION;
426 }; 453 num_of_sections_to_read = 4;
454 } else {
455 nvm_to_read[0] = NVM_SECTION_TYPE_SW;
456 nvm_to_read[1] = NVM_SECTION_TYPE_CALIBRATION;
457 nvm_to_read[2] = NVM_SECTION_TYPE_PRODUCTION;
458 nvm_to_read[3] = NVM_SECTION_TYPE_REGULATORY;
459 nvm_to_read[4] = NVM_SECTION_TYPE_MAC_OVERRIDE;
460 num_of_sections_to_read = 5;
461 }
427 462
428 /* Read From FW NVM */ 463 /* Read From FW NVM */
429 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); 464 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
@@ -433,7 +468,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
433 GFP_KERNEL); 468 GFP_KERNEL);
434 if (!nvm_buffer) 469 if (!nvm_buffer)
435 return -ENOMEM; 470 return -ENOMEM;
436 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 471 for (i = 0; i < num_of_sections_to_read; i++) {
437 section = nvm_to_read[i]; 472 section = nvm_to_read[i];
438 /* we override the constness for initial read */ 473 /* we override the constness for initial read */
439 ret = iwl_nvm_read_section(mvm, section, nvm_buffer); 474 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);