Skip to content

Commit

Permalink
iwlwifi: mvm: select the MAC address according to priority
Browse files Browse the repository at this point in the history
For family 8000 products, the driver should take the MAC
address from the mac_override section and only if this
section is empty it should take it from the HW section.

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>
  • Loading branch information
Eran Harary authored and Emmanuel Grumbach committed May 6, 2014
1 parent 26481bf commit 9f32e01
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
46 changes: 38 additions & 8 deletions drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/etherdevice.h>
#include "iwl-drv.h"
#include "iwl-modparams.h"
#include "iwl-nvm-parse.h"
Expand Down Expand Up @@ -450,13 +451,7 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 *nvm_sec)
{
u8 hw_addr[ETH_ALEN];

if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
else
memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
ETH_ALEN);
const u8 *hw_addr = (const u8 *)(nvm_sec + HW_ADDR);

/* The byte order is little endian 16 bit, meaning 214365 */
data->hw_addr[0] = hw_addr[1];
Expand All @@ -467,6 +462,41 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
data->hw_addr[5] = hw_addr[4];
}

static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 *mac_override,
const __le16 *nvm_hw)
{
const u8 *hw_addr;

if (mac_override) {
hw_addr = (const u8 *)(mac_override +
MAC_ADDRESS_OVERRIDE_FAMILY_8000);

/* The byte order is little endian 16 bit, meaning 214365 */
data->hw_addr[0] = hw_addr[1];
data->hw_addr[1] = hw_addr[0];
data->hw_addr[2] = hw_addr[3];
data->hw_addr[3] = hw_addr[2];
data->hw_addr[4] = hw_addr[5];
data->hw_addr[5] = hw_addr[4];

if (is_valid_ether_addr(hw_addr))
return;
}

/* take the MAC address from the OTP */
hw_addr = (const u8 *)(nvm_hw + HW_ADDR0_FAMILY_8000);
data->hw_addr[0] = hw_addr[3];
data->hw_addr[1] = hw_addr[2];
data->hw_addr[2] = hw_addr[1];
data->hw_addr[3] = hw_addr[0];

hw_addr = (const u8 *)(nvm_hw + HW_ADDR1_FAMILY_8000);
data->hw_addr[4] = hw_addr[1];
data->hw_addr[5] = hw_addr[0];
}

struct iwl_nvm_data *
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw,
Expand Down Expand Up @@ -526,7 +556,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
rx_chains);
} else {
/* MAC address in family 8000 */
iwl_set_hw_address(cfg, data, mac_override);
iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw);

iwl_init_sbands(dev, cfg, data, regulatory,
sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
Expand Down
9 changes: 8 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,20 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
return NULL;
}
} else {
/* SW and REGULATORY sections are mandatory */
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
!mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data ||
!mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
IWL_ERR(mvm,
"Can't parse empty family 8000 NVM sections\n");
return NULL;
}
/* MAC_OVERRIDE or at least HW section must exist */
if (!mvm->cfg->nvm_hw_section_num &&
!mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
IWL_ERR(mvm,
"Can't parse mac_address, empty sections\n");
return NULL;
}
}

if (WARN_ON(!mvm->cfg))
Expand Down

0 comments on commit 9f32e01

Please sign in to comment.