]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
b43: Refresh RX poison on buffer recycling
authorMichael Buesch <mb@bu3sch.de>
Fri, 24 Apr 2009 16:05:29 +0000 (16:05 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 8 May 2009 22:44:58 +0000 (15:44 -0700)
upstream commit: cf68636a9773aa97915497fe54fa4a51e3f08f3a

The RX buffer poison needs to be refreshed, if we recycle an RX buffer,
because it might be (partially) overwritten by some DMA operations.

Cc: stable@kernel.org
Cc: Francesco Gringoli <francesco.gringoli@ing.unibs.it>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
drivers/net/wireless/b43/dma.c

index 5420c989f36f9a6b1bb7234151e9dc9ec5d4ffda..dbae6174776ca75d3359032c830a6dfcee821d2f 100644 (file)
@@ -1496,20 +1496,16 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
                        len = le16_to_cpu(rxhdr->frame_len);
                } while (len == 0 && i++ < 5);
                if (unlikely(len == 0)) {
-                       /* recycle the descriptor buffer. */
-                       sync_descbuffer_for_device(ring, meta->dmaaddr,
-                                                  ring->rx_buffersize);
-                       goto drop;
+                       dmaaddr = meta->dmaaddr;
+                       goto drop_recycle_buffer;
                }
        }
        if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) {
                /* Something went wrong with the DMA.
                 * The device did not touch the buffer and did not overwrite the poison. */
                b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n");
-               /* recycle the descriptor buffer. */
-               sync_descbuffer_for_device(ring, meta->dmaaddr,
-                                          ring->rx_buffersize);
-               goto drop;
+               dmaaddr = meta->dmaaddr;
+               goto drop_recycle_buffer;
        }
        if (unlikely(len > ring->rx_buffersize)) {
                /* The data did not fit into one descriptor buffer
@@ -1523,6 +1519,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
                while (1) {
                        desc = ops->idx2desc(ring, *slot, &meta);
                        /* recycle the descriptor buffer. */
+                       b43_poison_rx_buffer(ring, meta->skb);
                        sync_descbuffer_for_device(ring, meta->dmaaddr,
                                                   ring->rx_buffersize);
                        *slot = next_slot(ring, *slot);
@@ -1541,8 +1538,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
        err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
        if (unlikely(err)) {
                b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n");
-               sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
-               goto drop;
+               goto drop_recycle_buffer;
        }
 
        unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
@@ -1552,6 +1548,11 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
        b43_rx(ring->dev, skb, rxhdr);
 drop:
        return;
+
+drop_recycle_buffer:
+       /* Poison and recycle the RX buffer. */
+       b43_poison_rx_buffer(ring, skb);
+       sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
 }
 
 void b43_dma_rx(struct b43_dmaring *ring)