p54: enforce strict tx_queue limits
authorChristian Lamparter <chunkeey@web.de>
Tue, 9 Dec 2008 20:09:00 +0000 (21:09 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 12 Dec 2008 19:01:55 +0000 (14:01 -0500)
The patch fixes an old FIXME in p54pci.c by moving the "queue full"
check into the common library, where we can deal with it properly.

Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54pci.c

index 409ae930d766ffb1d955a7303dc7729ba6a0d573..fac6b416e9e9572806be44413c58a3c115fecc40 100644 (file)
@@ -874,7 +874,27 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
                return -EINVAL;
 
        spin_lock_irqsave(&priv->tx_queue.lock, flags);
+
        left = skb_queue_len(&priv->tx_queue);
+       if (unlikely(left >= 28)) {
+               /*
+                * The tx_queue is nearly full!
+                * We have throttle normal data traffic, because we must
+                * have a few spare slots for control frames left.
+                */
+               ieee80211_stop_queues(dev);
+
+               if (unlikely(left == 32)) {
+                       /*
+                        * The tx_queue is now really full.
+                        *
+                        * TODO: check if the device has crashed and reset it.
+                        */
+                       spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+                       return -ENOSPC;
+               }
+       }
+
        while (left--) {
                u32 hole_size;
                info = IEEE80211_SKB_CB(entry);
@@ -903,7 +923,7 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
        if (!target_skb) {
                spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
                ieee80211_stop_queues(dev);
-               return -ENOMEM;
+               return -ENOSPC;
        }
 
        info = IEEE80211_SKB_CB(skb);
index d21c509325fee92db982611747820c00ce254ace..c28220e401b94578c85f1f25b243f464232d1cf3 100644 (file)
@@ -332,13 +332,6 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
 
        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
        P54P_READ(dev_int);
-
-       /* FIXME: unlikely to happen because the device usually runs out of
-          memory before we fill the ring up, but we can make it impossible */
-       if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) {
-               p54_free_skb(dev, skb);
-               printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
-       }
 }
 
 static void p54p_stop(struct ieee80211_hw *dev)