summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/wl12xx/ps.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-07-07 15:25:23 +0400
committerLuciano Coelho <coelho@ti.com>2011-07-08 10:39:47 +0400
commitf1a46384ad568f72c11edbe2a3ec284bf32f2dbd (patch)
tree2d303dfdcbf970db11aa858b1a02fb7d29ef4d4f /drivers/net/wireless/wl12xx/ps.c
parent097f882153f0ec13617074fa3bdb683b8215e20c (diff)
downloadlinux-f1a46384ad568f72c11edbe2a3ec284bf32f2dbd.tar.xz
wl12xx: start/stop queues according to global per-AC counters
Split tx_queue_count to count per-AC skb's queued, instead of relying on the skb-queue len. The skb queues used were only valid in STA-mode, as AP-mode uses per-link queues. This fixes a major regression in AP-mode, caused by the patch "wl12xx: implement Tx watermarks per AC". With that patch applied, we effectively had no regulation of Tx queues in AP-mode. Therefore a sustained high rate of Tx could cause exhaustion of the skb memory pool. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/ps.c')
-rw-r--r--drivers/net/wireless/wl12xx/ps.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 3e68a664c9de..3548377ab9c2 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -193,24 +193,27 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
{
- int i, filtered = 0;
+ int i;
struct sk_buff *skb;
struct ieee80211_tx_info *info;
unsigned long flags;
+ int filtered[NUM_TX_QUEUES];
/* filter all frames currently the low level queus for this hlid */
for (i = 0; i < NUM_TX_QUEUES; i++) {
+ filtered[i] = 0;
while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) {
info = IEEE80211_SKB_CB(skb);
info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
info->status.rates[0].idx = -1;
ieee80211_tx_status_ni(wl->hw, skb);
- filtered++;
+ filtered[i]++;
}
}
spin_lock_irqsave(&wl->wl_lock, flags);
- wl->tx_queue_count -= filtered;
+ for (i = 0; i < NUM_TX_QUEUES; i++)
+ wl->tx_queue_count[i] -= filtered[i];
spin_unlock_irqrestore(&wl->wl_lock, flags);
wl1271_handle_tx_low_watermark(wl);