diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-nvm-parse.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 46 |
1 files changed, 38 insertions, 8 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, |