diff options
Diffstat (limited to 'drivers/net/wireless/ti/wl1251/main.c')
-rw-r--r-- | drivers/net/wireless/ti/wl1251/main.c | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index be07243d590e..5ac7965c7d53 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -203,13 +203,6 @@ static int wl1251_chip_wakeup(struct wl1251 *wl) goto out; } - if (wl->nvs == NULL && !wl->use_eeprom) { - /* No NVS from netlink, try to get it from the filesystem */ - ret = wl1251_fetch_nvs(wl); - if (ret < 0) - goto out; - } - out: return ret; } @@ -1447,6 +1440,46 @@ static int wl1251_read_eeprom_mac(struct wl1251 *wl) return 0; } +#define NVS_OFF_MAC_LEN 0x19 +#define NVS_OFF_MAC_ADDR_LO 0x1a +#define NVS_OFF_MAC_ADDR_HI 0x1b +#define NVS_OFF_MAC_DATA 0x1c + +static int wl1251_check_nvs_mac(struct wl1251 *wl) +{ + if (wl->nvs_len < 0x24) + return -ENODATA; + + /* length is 2 and data address is 0x546c (ANDed with 0xfffe) */ + if (wl->nvs[NVS_OFF_MAC_LEN] != 2 || + wl->nvs[NVS_OFF_MAC_ADDR_LO] != 0x6d || + wl->nvs[NVS_OFF_MAC_ADDR_HI] != 0x54) + return -EINVAL; + + return 0; +} + +static int wl1251_read_nvs_mac(struct wl1251 *wl) +{ + u8 mac[ETH_ALEN]; + int i, ret; + + ret = wl1251_check_nvs_mac(wl); + if (ret) + return ret; + + /* MAC is stored in reverse order */ + for (i = 0; i < ETH_ALEN; i++) + mac[i] = wl->nvs[NVS_OFF_MAC_DATA + ETH_ALEN - i - 1]; + + /* 00:00:20:07:03:09 is in example file wl1251-nvs.bin, so invalid */ + if (ether_addr_equal_unaligned(mac, "\x00\x00\x20\x07\x03\x09")) + return -EINVAL; + + memcpy(wl->mac_addr, mac, ETH_ALEN); + return 0; +} + static int wl1251_register_hw(struct wl1251 *wl) { int ret; @@ -1490,10 +1523,16 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->queues = 4; + if (wl->nvs == NULL && !wl->use_eeprom) { + ret = wl1251_fetch_nvs(wl); + if (ret < 0) + goto out; + } + if (wl->use_eeprom) ret = wl1251_read_eeprom_mac(wl); else - ret = -EINVAL; + ret = wl1251_read_nvs_mac(wl); if (ret == 0 && !is_valid_ether_addr(wl->mac_addr)) ret = -EINVAL; |