diff options
Diffstat (limited to 'drivers/net/wireless/ti/wlcore')
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore.h | 11 |
2 files changed, 32 insertions, 9 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index ae2b0fd7e558..dd0cbd9f6ce1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5074,18 +5074,17 @@ out: mutex_unlock(&wl->mutex); } -static void wl12xx_derive_mac_addresses(struct wl1271 *wl, - u32 oui, u32 nic, int n) +static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic) { int i; - wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x, n %d", - oui, nic, n); + wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x", + oui, nic); - if (nic + n - 1 > 0xffffff) + if (nic + WLCORE_NUM_MAC_ADDRESSES - wl->num_mac_addr > 0xffffff) wl1271_warning("NIC part of the MAC address wraps around!"); - for (i = 0; i < n; i++) { + for (i = 0; i < wl->num_mac_addr; i++) { wl->addresses[i].addr[0] = (u8)(oui >> 16); wl->addresses[i].addr[1] = (u8)(oui >> 8); wl->addresses[i].addr[2] = (u8) oui; @@ -5095,7 +5094,22 @@ static void wl12xx_derive_mac_addresses(struct wl1271 *wl, nic++; } - wl->hw->wiphy->n_addresses = n; + /* we may be one address short at the most */ + WARN_ON(wl->num_mac_addr + 1 < WLCORE_NUM_MAC_ADDRESSES); + + /* + * turn on the LAA bit in the first address and use it as + * the last address. + */ + if (wl->num_mac_addr < WLCORE_NUM_MAC_ADDRESSES) { + int idx = WLCORE_NUM_MAC_ADDRESSES - 1; + memcpy(&wl->addresses[idx], &wl->addresses[0], + sizeof(wl->addresses[0])); + /* LAA bit */ + wl->addresses[idx].addr[2] |= BIT(1); + } + + wl->hw->wiphy->n_addresses = WLCORE_NUM_MAC_ADDRESSES; wl->hw->wiphy->addresses = wl->addresses; } @@ -5155,7 +5169,7 @@ static int wl1271_register_hw(struct wl1271 *wl) nic_addr = wl->fuse_nic_addr + 1; } - wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr, 2); + wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr); ret = ieee80211_register_hw(wl->hw); if (ret < 0) { diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index a7e9d5869db4..165afae2d9ad 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -31,6 +31,12 @@ /* The maximum number of Tx descriptors in all chip families */ #define WLCORE_MAX_TX_DESCRIPTORS 32 +/* + * We always allocate this number of mac addresses. If we don't + * have enough allocated addresses, the LAA bit is used + */ +#define WLCORE_NUM_MAC_ADDRESSES 3 + /* forward declaration */ struct wl1271_tx_hw_descr; enum wl_rx_buf_align; @@ -181,7 +187,7 @@ struct wl1271 { u32 fuse_nic_addr; /* we have up to 2 MAC addresses */ - struct mac_address addresses[2]; + struct mac_address addresses[WLCORE_NUM_MAC_ADDRESSES]; int channel; u8 system_hlid; @@ -394,6 +400,9 @@ struct wl1271 { /* sleep auth value currently configured to FW */ int sleep_auth; + /* the number of allocated MAC addresses in this chip */ + int num_mac_addr; + /* the minimum FW version required for the driver to work */ unsigned int min_fw_ver[NUM_FW_VER]; }; |