diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 46 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/nvm.c | 9 |
2 files changed, 46 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 4049c0d626ba..49963e4a887e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/types.h> | 62 | #include <linux/types.h> |
63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
64 | #include <linux/export.h> | 64 | #include <linux/export.h> |
65 | #include <linux/etherdevice.h> | ||
65 | #include "iwl-drv.h" | 66 | #include "iwl-drv.h" |
66 | #include "iwl-modparams.h" | 67 | #include "iwl-modparams.h" |
67 | #include "iwl-nvm-parse.h" | 68 | #include "iwl-nvm-parse.h" |
@@ -450,13 +451,7 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg, | |||
450 | struct iwl_nvm_data *data, | 451 | struct iwl_nvm_data *data, |
451 | const __le16 *nvm_sec) | 452 | const __le16 *nvm_sec) |
452 | { | 453 | { |
453 | u8 hw_addr[ETH_ALEN]; | 454 | const u8 *hw_addr = (const u8 *)(nvm_sec + HW_ADDR); |
454 | |||
455 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | ||
456 | memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN); | ||
457 | else | ||
458 | memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000, | ||
459 | ETH_ALEN); | ||
460 | 455 | ||
461 | /* The byte order is little endian 16 bit, meaning 214365 */ | 456 | /* The byte order is little endian 16 bit, meaning 214365 */ |
462 | data->hw_addr[0] = hw_addr[1]; | 457 | data->hw_addr[0] = hw_addr[1]; |
@@ -467,6 +462,41 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg, | |||
467 | data->hw_addr[5] = hw_addr[4]; | 462 | data->hw_addr[5] = hw_addr[4]; |
468 | } | 463 | } |
469 | 464 | ||
465 | static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg, | ||
466 | struct iwl_nvm_data *data, | ||
467 | const __le16 *mac_override, | ||
468 | const __le16 *nvm_hw) | ||
469 | { | ||
470 | const u8 *hw_addr; | ||
471 | |||
472 | if (mac_override) { | ||
473 | hw_addr = (const u8 *)(mac_override + | ||
474 | MAC_ADDRESS_OVERRIDE_FAMILY_8000); | ||
475 | |||
476 | /* The byte order is little endian 16 bit, meaning 214365 */ | ||
477 | data->hw_addr[0] = hw_addr[1]; | ||
478 | data->hw_addr[1] = hw_addr[0]; | ||
479 | data->hw_addr[2] = hw_addr[3]; | ||
480 | data->hw_addr[3] = hw_addr[2]; | ||
481 | data->hw_addr[4] = hw_addr[5]; | ||
482 | data->hw_addr[5] = hw_addr[4]; | ||
483 | |||
484 | if (is_valid_ether_addr(hw_addr)) | ||
485 | return; | ||
486 | } | ||
487 | |||
488 | /* take the MAC address from the OTP */ | ||
489 | hw_addr = (const u8 *)(nvm_hw + HW_ADDR0_FAMILY_8000); | ||
490 | data->hw_addr[0] = hw_addr[3]; | ||
491 | data->hw_addr[1] = hw_addr[2]; | ||
492 | data->hw_addr[2] = hw_addr[1]; | ||
493 | data->hw_addr[3] = hw_addr[0]; | ||
494 | |||
495 | hw_addr = (const u8 *)(nvm_hw + HW_ADDR1_FAMILY_8000); | ||
496 | data->hw_addr[4] = hw_addr[1]; | ||
497 | data->hw_addr[5] = hw_addr[0]; | ||
498 | } | ||
499 | |||
470 | struct iwl_nvm_data * | 500 | struct iwl_nvm_data * |
471 | iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | 501 | iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, |
472 | const __le16 *nvm_hw, const __le16 *nvm_sw, | 502 | const __le16 *nvm_hw, const __le16 *nvm_sw, |
@@ -526,7 +556,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
526 | rx_chains); | 556 | rx_chains); |
527 | } else { | 557 | } else { |
528 | /* MAC address in family 8000 */ | 558 | /* MAC address in family 8000 */ |
529 | iwl_set_hw_address(cfg, data, mac_override); | 559 | iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw); |
530 | 560 | ||
531 | iwl_init_sbands(dev, cfg, data, regulatory, | 561 | iwl_init_sbands(dev, cfg, data, regulatory, |
532 | sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, | 562 | sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 2cb6c29b0a97..6d0e659c3dec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -238,13 +238,20 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) | |||
238 | return NULL; | 238 | return NULL; |
239 | } | 239 | } |
240 | } else { | 240 | } else { |
241 | /* SW and REGULATORY sections are mandatory */ | ||
241 | if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || | 242 | 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) { | 243 | !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) { |
244 | IWL_ERR(mvm, | 244 | IWL_ERR(mvm, |
245 | "Can't parse empty family 8000 NVM sections\n"); | 245 | "Can't parse empty family 8000 NVM sections\n"); |
246 | return NULL; | 246 | return NULL; |
247 | } | 247 | } |
248 | /* MAC_OVERRIDE or at least HW section must exist */ | ||
249 | if (!mvm->cfg->nvm_hw_section_num && | ||
250 | !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data) { | ||
251 | IWL_ERR(mvm, | ||
252 | "Can't parse mac_address, empty sections\n"); | ||
253 | return NULL; | ||
254 | } | ||
248 | } | 255 | } |
249 | 256 | ||
250 | if (WARN_ON(!mvm->cfg)) | 257 | if (WARN_ON(!mvm->cfg)) |