wlcore/wl12xx/wl18xx: configure num_links per-hw
authorEliad Peller <eliad@wizery.com>
Mon, 10 Feb 2014 11:47:22 +0000 (13:47 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 13 Feb 2014 20:20:15 +0000 (15:20 -0500)
Upcoming fw versions will have different max links support
(according to the hw). Get ready for it by configuring
wl->num_links per-hw, instead of using the const WL12XX_MAX_LINKS.

However, continue using WLCORE_MAX_LINKS in order to simplify
structs declarations (we use it in multiple bitmaps, and converting
them to dynamic arrays is just cumbersome).

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
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/cmd.c
drivers/net/wireless/ti/wlcore/event.c
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/rx.c
drivers/net/wireless/ti/wlcore/tx.c
drivers/net/wireless/ti/wlcore/wlcore.h
drivers/net/wireless/ti/wlcore/wlcore_i.h

index 3ad8767..69df5bc 100644 (file)
@@ -1749,9 +1749,12 @@ static int wl12xx_setup(struct wl1271 *wl)
        struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
        struct wl12xx_platform_data *pdata = pdev_data->pdata;
 
+       BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
+
        wl->rtable = wl12xx_rtable;
        wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
        wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
+       wl->num_links = WL12XX_MAX_LINKS;
        wl->num_channels = 1;
        wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
        wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
index b9950f8..26b1a3f 100644 (file)
@@ -65,6 +65,8 @@
 
 #define WL12XX_RX_BA_MAX_SESSIONS 3
 
+#define WL12XX_MAX_LINKS 12
+
 struct wl127x_rx_mem_pool_addr {
        u32 addr;
        u32 addr_extra;
index cbf9bf3..6011b22 100644 (file)
@@ -1752,9 +1752,12 @@ static int wl18xx_setup(struct wl1271 *wl)
        struct wl18xx_priv *priv = wl->priv;
        int ret;
 
+       BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
+
        wl->rtable = wl18xx_rtable;
        wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
        wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
+       wl->num_links = WL18XX_MAX_LINKS;
        wl->num_channels = 2;
        wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
        wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
index d32a6af..38174e9 100644 (file)
@@ -42,6 +42,8 @@
 
 #define WL18XX_RX_BA_MAX_SESSIONS 5
 
+#define WL18XX_MAX_LINKS 12
+
 struct wl18xx_priv {
        /* buffer for sending commands to FW */
        u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
@@ -114,7 +116,7 @@ struct wl18xx_fw_packet_counters {
        u8 tx_released_pkts[NUM_TX_QUEUES];
 
        /* Cumulative counter of freed packets per HLID */
-       u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
+       u8 tx_lnk_free_pkts[WL18XX_MAX_LINKS];
 
        /* Cumulative counter of released Voice memory blocks */
        u8 tx_voice_released_blks;
index 4d19fd2..ab5ca32 100644 (file)
@@ -312,8 +312,8 @@ static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid)
 int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 {
        unsigned long flags;
-       u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
-       if (link >= WL12XX_MAX_LINKS)
+       u8 link = find_first_zero_bit(wl->links_map, wl->num_links);
+       if (link >= wl->num_links)
                return -EBUSY;
 
        wl->session_ids[link] = wlcore_get_new_session_id(wl, link);
index 8d3b349..1f9a360 100644 (file)
@@ -67,7 +67,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
                u8 hlid;
                struct wl1271_link *lnk;
                for_each_set_bit(hlid, wlvif->ap.sta_hlid_map,
-                                WL12XX_MAX_LINKS) {
+                                wl->num_links) {
                        lnk = &wl->links[hlid];
                        if (!lnk->ba_bitmap)
                                continue;
@@ -172,7 +172,7 @@ static void wlcore_disconnect_sta(struct wl1271 *wl, unsigned long sta_bitmap)
        const u8 *addr;
        int h;
 
-       for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) {
+       for_each_set_bit(h, &sta_bitmap, wl->num_links) {
                bool found = false;
                /* find the ap vif connected to this sta */
                wl12xx_for_each_wlvif_ap(wl, wlvif) {
index 70a3e57..c35d1dc 100644 (file)
@@ -372,7 +372,7 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
                wl->ap_fw_ps_map = cur_fw_ps_map;
        }
 
-       for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS)
+       for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, wl->num_links)
                wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
                                            wl->links[hlid].allocated_pkts);
 }
@@ -412,7 +412,7 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
        }
 
 
-       for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) {
+       for_each_set_bit(i, wl->links_map, wl->num_links) {
                u8 diff;
                lnk = &wl->links[i];
 
@@ -5855,7 +5855,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
        int i, j, ret;
        unsigned int order;
 
-       BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS);
+       BUILD_BUG_ON(AP_MAX_STATIONS > WLCORE_MAX_LINKS);
 
        hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
        if (!hw) {
@@ -5878,8 +5878,12 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
 
        wl->hw = hw;
 
+       /*
+        * wl->num_links is not configured yet, so just use WLCORE_MAX_LINKS.
+        * we don't allocate any additional resource here, so that's fine.
+        */
        for (i = 0; i < NUM_TX_QUEUES; i++)
-               for (j = 0; j < WL12XX_MAX_LINKS; j++)
+               for (j = 0; j < WLCORE_MAX_LINKS; j++)
                        skb_queue_head_init(&wl->links[j].tx_queue[i]);
 
        skb_queue_head_init(&wl->deferred_rx_queue);
index a047e87..e125974 100644 (file)
@@ -205,7 +205,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
 
 int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
 {
-       unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
+       unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
        u32 buf_size;
        u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc;
        u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc;
@@ -263,12 +263,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
                                                  wl->aggr_buf + pkt_offset,
                                                  pkt_len, rx_align,
                                                  &hlid) == 1) {
-                               if (hlid < WL12XX_MAX_LINKS)
+                               if (hlid < wl->num_links)
                                        __set_bit(hlid, active_hlids);
                                else
                                        WARN(1,
-                                            "hlid exceeded WL12XX_MAX_LINKS "
-                                            "(%d)\n", hlid);
+                                            "hlid (%d) exceeded MAX_LINKS\n",
+                                            hlid);
                        }
 
                        wl->rx_counter++;
index ca886ef..06ab5c6 100644 (file)
@@ -565,11 +565,11 @@ static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl,
        int i, h, start_hlid;
 
        /* start from the link after the last one */
-       start_hlid = (wlvif->last_tx_hlid + 1) % WL12XX_MAX_LINKS;
+       start_hlid = (wlvif->last_tx_hlid + 1) % wl->num_links;
 
        /* dequeue according to AC, round robin on each link */
-       for (i = 0; i < WL12XX_MAX_LINKS; i++) {
-               h = (start_hlid + i) % WL12XX_MAX_LINKS;
+       for (i = 0; i < wl->num_links; i++) {
+               h = (start_hlid + i) % wl->num_links;
 
                /* only consider connected stations */
                if (!test_bit(h, wlvif->links_map))
@@ -693,8 +693,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
 
                /* make sure we dequeue the same packet next time */
-               wlvif->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) %
-                                     WL12XX_MAX_LINKS;
+               wlvif->last_tx_hlid = (hlid + wl->num_links - 1) %
+                                     wl->num_links;
        }
 
        spin_lock_irqsave(&wl->wl_lock, flags);
@@ -727,7 +727,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids)
        timeout = wl->conf.rx_streaming.duration;
        wl12xx_for_each_wlvif_sta(wl, wlvif) {
                bool found = false;
-               for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) {
+               for_each_set_bit(hlid, active_hlids, wl->num_links) {
                        if (test_bit(hlid, wlvif->links_map)) {
                                found  = true;
                                break;
@@ -764,7 +764,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl)
        struct wl1271_tx_hw_descr *desc;
        u32 buf_offset = 0, last_len = 0;
        bool sent_packets = false;
-       unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
+       unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
        int ret = 0;
        int bus_ret = 0;
        u8 hlid;
@@ -1066,7 +1066,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
        int i;
 
        /* TX failure */
-       for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
+       for_each_set_bit(i, wlvif->links_map, wl->num_links) {
                if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
                    i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
                        /* this calls wl12xx_free_link */
@@ -1090,7 +1090,7 @@ void wl12xx_tx_reset(struct wl1271 *wl)
 
        /* only reset the queues if something bad happened */
        if (wl1271_tx_total_queue_count(wl) != 0) {
-               for (i = 0; i < WL12XX_MAX_LINKS; i++)
+               for (i = 0; i < wl->num_links; i++)
                        wl1271_tx_reset_link_queues(wl, i);
 
                for (i = 0; i < NUM_TX_QUEUES; i++)
@@ -1183,7 +1183,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
                       WL1271_TX_FLUSH_TIMEOUT / 1000);
 
        /* forcibly flush all Tx buffers on our queues */
-       for (i = 0; i < WL12XX_MAX_LINKS; i++)
+       for (i = 0; i < wl->num_links; i++)
                wl1271_tx_reset_link_queues(wl, i);
 
 out_wake:
index cec5265..98b1875 100644 (file)
@@ -222,7 +222,7 @@ struct wl1271 {
        int channel;
        u8 system_hlid;
 
-       unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
+       unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
        unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
        unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
        unsigned long rate_policies_map[
@@ -230,7 +230,7 @@ struct wl1271 {
        unsigned long klv_templates_map[
                        BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
 
-       u8 session_ids[WL12XX_MAX_LINKS];
+       u8 session_ids[WLCORE_MAX_LINKS];
 
        struct list_head wlvif_list;
 
@@ -378,7 +378,7 @@ struct wl1271 {
         * AP-mode - links indexed by HLID. The global and broadcast links
         * are always active.
         */
-       struct wl1271_link links[WL12XX_MAX_LINKS];
+       struct wl1271_link links[WLCORE_MAX_LINKS];
 
        /* number of currently active links */
        int active_link_count;
@@ -436,6 +436,8 @@ struct wl1271 {
        u32 num_tx_desc;
        /* number of RX descriptors the HW supports. */
        u32 num_rx_desc;
+       /* number of links the HW supports */
+       u8 num_links;
 
        /* translate HW Tx rates to standard rate-indices */
        const u8 **band_rate_to_idx;
index 32e1e8b..256d09b 100644 (file)
 #define WL1271_DEFAULT_DTIM_PERIOD 1
 
 #define WL12XX_MAX_ROLES           4
-#define WL12XX_MAX_LINKS           12
 #define WL12XX_INVALID_ROLE_ID     0xff
 #define WL12XX_INVALID_LINK_ID     0xff
 
+/*
+ * max number of links allowed by all HWs.
+ * this is NOT the actual max links supported by the current hw.
+ */
+#define WLCORE_MAX_LINKS 12
+
 /* the driver supports the 2.4Ghz and 5Ghz bands */
 #define WLCORE_NUM_BANDS           2
 
@@ -156,7 +161,7 @@ struct wl_fw_status {
 
                /*
                 * Cumulative counter of freed packets per HLID
-                * (length of the array is WL12XX_MAX_LINKS)
+                * (length of the array is wl->num_links)
                 */
                u8 *tx_lnk_free_pkts;
 
@@ -357,7 +362,7 @@ struct wl12xx_vif {
 
                        /* HLIDs bitmap of associated stations */
                        unsigned long sta_hlid_map[BITS_TO_LONGS(
-                                                       WL12XX_MAX_LINKS)];
+                                                       WLCORE_MAX_LINKS)];
 
                        /* recoreded keys - set here before AP startup */
                        struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS];
@@ -374,7 +379,7 @@ struct wl12xx_vif {
        /* counters of packets per AC, across all links in the vif */
        int tx_queue_count[NUM_TX_QUEUES];
 
-       unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
+       unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
 
        u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
        u8 ssid_len;