Skip to content

Commit

Permalink
p54: enforce strict tx_queue limits
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christian Lamparter authored and John W. Linville committed Dec 12, 2008
1 parent 30dab79 commit 39ca5bb
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
22 changes: 21 additions & 1 deletion drivers/net/wireless/p54/p54common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 0 additions & 7 deletions drivers/net/wireless/p54/p54pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 39ca5bb

Please sign in to comment.