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.c239
1 files changed, 190 insertions, 49 deletions
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