wl12xx: use round-robin policy for tx
authorEliad Peller <eliad@wizery.com>
Mon, 10 Oct 2011 08:13:17 +0000 (10:13 +0200)
committerLuciano Coelho <coelho@ti.com>
Tue, 11 Oct 2011 12:29:57 +0000 (15:29 +0300)
Currently, a single vif might starve all the other vifs.
Save the last vif we dequeued a packet from, and continue
with the following one using a round-robin policy.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/wl12xx.h

index 6e6ac63fb8cd3e41903b5cae049687cf7bec95cc..f29d18daaa82a680e29d4a8ee4e74b23eb47b75f 100644 (file)
@@ -2282,6 +2282,8 @@ deinit:
 
        wl12xx_tx_reset_wlvif(wl, wlvif);
        wl1271_free_ap_keys(wl, wlvif);
+       if (wl->last_wlvif == wlvif)
+               wl->last_wlvif = NULL;
        list_del(&wlvif->list);
        memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map));
        wlvif->role_id = WL12XX_INVALID_ROLE_ID;
index 69ac03f5d54b17e368014fd53566a84358f28875..5aeef95229ebfa96b30c3574a5bd16e36bca715c 100644 (file)
@@ -590,14 +590,28 @@ static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl,
 static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
 {
        unsigned long flags;
-       struct wl12xx_vif *wlvif;
+       struct wl12xx_vif *wlvif = wl->last_wlvif;
        struct sk_buff *skb = NULL;
 
-       /* TODO: rememeber last vif and consider it */
-       wl12xx_for_each_wlvif(wl, wlvif) {
-               skb = wl12xx_vif_skb_dequeue(wl, wlvif);
-               if (skb)
-                       break;
+       if (wlvif) {
+               wl12xx_for_each_wlvif_continue(wl, wlvif) {
+                       skb = wl12xx_vif_skb_dequeue(wl, wlvif);
+                       if (skb) {
+                               wl->last_wlvif = wlvif;
+                               break;
+                       }
+               }
+       }
+
+       /* do another pass */
+       if (!skb) {
+               wl12xx_for_each_wlvif(wl, wlvif) {
+                       skb = wl12xx_vif_skb_dequeue(wl, wlvif);
+                       if (skb) {
+                               wl->last_wlvif = wlvif;
+                               break;
+                       }
+               }
        }
 
        if (!skb &&
index d169d52f6d1cff193a0729afbcf6b84320d3a9da..8815fd9a0f47cfcc5dbafb3af3275cdd0e08dfe0 100644 (file)
@@ -552,6 +552,9 @@ struct wl1271 {
 
        /* AP-mode - number of currently connected stations */
        int active_sta_count;
+
+       /* last wlvif we transmitted from */
+       struct wl12xx_vif *last_wlvif;
 };
 
 struct wl1271_station {
@@ -693,6 +696,9 @@ struct ieee80211_vif *wl12xx_wlvif_to_vif(struct wl12xx_vif *wlvif)
 #define wl12xx_for_each_wlvif(wl, wlvif) \
                list_for_each_entry(wlvif, &wl->wlvif_list, list)
 
+#define wl12xx_for_each_wlvif_continue(wl, wlvif) \
+               list_for_each_entry_continue(wlvif, &wl->wlvif_list, list)
+
 #define wl12xx_for_each_wlvif_bss_type(wl, wlvif, _bss_type)   \
                wl12xx_for_each_wlvif(wl, wlvif)                \
                        if (wlvif->bss_type == _bss_type)