iwlwifi: read multiple MAC addresses
Wey-Yi Guy [Thu, 15 Jul 2010 12:58:30 +0000 (05:58 -0700)]
Some devices may have multiple MAC
addresses in their EEPROM, read them
and advertise them to cfg80211.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.h

index 573a81b..f8f8ea2 100644 (file)
@@ -3932,8 +3932,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct ieee80211_hw *hw;
        struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
        unsigned long flags;
-       u16 pci_cmd;
-       u8 perm_addr[ETH_ALEN];
+       u16 pci_cmd, num_mac;
 
        /************************
         * 1. Allocating HW data
@@ -4051,9 +4050,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out_free_eeprom;
 
        /* extract MAC Address */
-       iwl_eeprom_get_mac(priv, perm_addr);
-       IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr);
-       SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr);
+       iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
+       IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
+       priv->hw->wiphy->addresses = priv->addresses;
+       priv->hw->wiphy->n_addresses = 1;
+       num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS);
+       if (num_mac > 1) {
+               memcpy(priv->addresses[1].addr, priv->addresses[0].addr,
+                      ETH_ALEN);
+               priv->addresses[1].addr[5]++;
+               priv->hw->wiphy->n_addresses++;
+       }
 
        /************************
         * 5. Setup HW constants
index 4fa8cdd..5e4745d 100644 (file)
@@ -1154,6 +1154,9 @@ struct iwl_priv {
        u32  hw_wa_rev;
        u8   rev_id;
 
+       /* EEPROM MAC addresses */
+       struct mac_address addresses[2];
+
        /* uCode images, save to reload in case of failure */
        int fw_index;                   /* firmware we're trying to load */
        u32 ucode_ver;                  /* version of ucode, copy of
index f8b707d..3209b37 100644 (file)
@@ -402,6 +402,7 @@ struct iwl_eeprom_calib_info {
 #define EEPROM_WOWLAN_MODE                  (2*0x47)   /* 2  bytes */
 #define EEPROM_RADIO_CONFIG                 (2*0x48)   /* 2  bytes */
 #define EEPROM_3945_M_VERSION               (2*0x4A)   /* 1  bytes */
+#define EEPROM_NUM_MAC_ADDRESS              (2*0x4C)   /* 2  bytes */
 
 /* The following masks are to be applied on EEPROM_RADIO_CONFIG */
 #define EEPROM_RF_CFG_TYPE_MSK(x)   (x & 0x3)         /* bits 0-1   */