wlcore/wl18xx/wl12xx: allow up to 3 mac addresses
authorArik Nemtsov <arik@wizery.com>
Thu, 2 Aug 2012 17:37:21 +0000 (20:37 +0300)
committerLuciano Coelho <luca@coelho.fi>
Thu, 27 Sep 2012 09:13:52 +0000 (12:13 +0300)
Allow 3 native mac addresses on 18xx. On 12xx allow 2 native mac
addresses and set the LAA bit to create a third mac address. This
enabled operation with a separate group interface.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <luca@coelho.fi>
drivers/net/wireless/ti/wl12xx/main.c
drivers/net/wireless/ti/wl12xx/wl12xx.h
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wl18xx/wl18xx.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/wlcore.h

index 0a8bc0c7b6ccda3a185135e536177bfca0f59911..f49ce7c633b6d26c9f8d275aee1cbaffc7ee3666 100644 (file)
@@ -1643,6 +1643,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
        wl->rtable = wl12xx_rtable;
        wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
        wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
+       wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
        wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
        wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
        wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
index 9953374a307da9a02cb86feca80ef5e9ea1f37da..7182bbf6625daac99ddcf00b3581c32ee39c2ef6 100644 (file)
@@ -43,6 +43,8 @@
 #define WL12XX_NUM_TX_DESCRIPTORS 16
 #define WL12XX_NUM_RX_DESCRIPTORS 8
 
+#define WL12XX_NUM_MAC_ADDRESSES 2
+
 struct wl127x_rx_mem_pool_addr {
        u32 addr;
        u32 addr_extra;
index 3f4fbd80d4ae7e42e387e58aaa9d0ff46697019a..93b148fe17a320d09027ede48bf5a9cdc34bbd92 100644 (file)
@@ -1394,6 +1394,7 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
        wl->rtable = wl18xx_rtable;
        wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
        wl->num_rx_desc = WL18XX_NUM_TX_DESCRIPTORS;
+       wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
        wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
        wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
        wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
index a6e61a25124d29013bc985a3925916b680f72331..96a1e438d677fd1f14ea125338c824c25e34b228 100644 (file)
@@ -38,6 +38,8 @@
 #define WL18XX_NUM_TX_DESCRIPTORS 32
 #define WL18XX_NUM_RX_DESCRIPTORS 32
 
+#define WL18XX_NUM_MAC_ADDRESSES 3
+
 struct wl18xx_priv {
        /* buffer for sending commands to FW */
        u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
index ae2b0fd7e558ed43a137dd3f9b08aa864ff1f531..dd0cbd9f6ce1fa6d026ca06800451c978007b7c1 100644 (file)
@@ -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) {
index a7e9d5869db4bdea93ac03a13152c12c4b19c470..165afae2d9ad22ab33bb5f3c0723d66ef3c44ddc 100644 (file)
 /* 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];
 };