aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/dma.c
diff options
context:
space:
mode:
authorfrancesco.gringoli@ing.unibs.it <francesco.gringoli@ing.unibs.it>2011-12-16 12:34:56 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-19 14:40:22 -0500
commitbad6919469662b7c92bc6353642aaaa777b36bac (patch)
tree35c1429e8216cc5ae4ef2f505a838d523045037f /drivers/net/wireless/b43/dma.c
parent1d8d3dec5fbba15864f25c734a7fda5703234091 (diff)
b43: avoid packet losses in the dma worker code.
Following Rafal request, we verified that on "modern" CPUs using one or more workers is equivalent. Here is patch V3 that addresses the packet loss bug in the dma engine using only one worker. ------- This patch addresses a bug in the dma worker code that keeps draining packets even when the hardware queues are full. In such cases packets can not be passed down to the device and are erroneusly dropped by the code. This problem was already discussed here http://www.mail-archive.com/b43-dev@lists.infradead.org/msg01413.html and acknowledged by Michael. Number of hardware queues is now defined in b43.h (B43_QOS_QUEUE_NUM). Acknowledgements to Riccardo Paolillo <riccardo.paolillo@gmail.com> and Michele Orru <michele.orru@hotmail.it> Signed-off-by: Francesco Gringoli <francesco.gringoli@ing.unibs.it> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/dma.c')
-rw-r--r--drivers/net/wireless/b43/dma.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 5e45604f0f5d..56d37dc967aa 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1465,7 +1465,9 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1465 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || 1465 if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
1466 should_inject_overflow(ring)) { 1466 should_inject_overflow(ring)) {
1467 /* This TX ring is full. */ 1467 /* This TX ring is full. */
1468 ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); 1468 unsigned int skb_mapping = skb_get_queue_mapping(skb);
1469 ieee80211_stop_queue(dev->wl->hw, skb_mapping);
1470 dev->wl->tx_queue_stopped[skb_mapping] = 1;
1469 ring->stopped = 1; 1471 ring->stopped = 1;
1470 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1472 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1471 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); 1473 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1584,12 +1586,21 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1584 } 1586 }
1585 if (ring->stopped) { 1587 if (ring->stopped) {
1586 B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); 1588 B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
1587 ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
1588 ring->stopped = 0; 1589 ring->stopped = 0;
1590 }
1591
1592 if (dev->wl->tx_queue_stopped[ring->queue_prio]) {
1593 dev->wl->tx_queue_stopped[ring->queue_prio] = 0;
1594 } else {
1595 /* If the driver queue is running wake the corresponding
1596 * mac80211 queue. */
1597 ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
1589 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1598 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1590 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); 1599 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
1591 } 1600 }
1592 } 1601 }
1602 /* Add work to the queue. */
1603 ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work);
1593} 1604}
1594 1605
1595static void dma_rx(struct b43_dmaring *ring, int *slot) 1606static void dma_rx(struct b43_dmaring *ring, int *slot)