diff options
Diffstat (limited to 'package/mac80211/patches/510-b43-poison-rx-buffers.patch')
-rw-r--r-- | package/mac80211/patches/510-b43-poison-rx-buffers.patch | 103 |
1 files changed, 0 insertions, 103 deletions
diff --git a/package/mac80211/patches/510-b43-poison-rx-buffers.patch b/package/mac80211/patches/510-b43-poison-rx-buffers.patch deleted file mode 100644 index c1c6d79bd7..0000000000 --- a/package/mac80211/patches/510-b43-poison-rx-buffers.patch +++ /dev/null @@ -1,103 +0,0 @@ -This patch adds poisoning and sanity checking to the RX DMA buffers. -This is used for protection against buggy hardware/firmware that raises -RX interrupts without doing an actual DMA transfer. - -This mechanism protects against rare "bad packets" (due to uninitialized skb data) -and rare kernel crashes due to uninitialized RX headers. - -The poison is selected to not match on valid frames and to be cheap for checking. - -The poison check mechanism _might_ trigger incorrectly, if we are voluntarily -receiving frames with bad PLCP headers. However, this is nonfatal, because the -chance of such a match is basically zero and in case it happens it just results -in dropping the packet. -Bad-PLCP RX defaults to off, and you should leave it off unless you want to listen -to the latest news broadcasted by your microwave oven. - -This patch also moves the initialization of the RX-header "length" field in front of -the mapping of the DMA buffer. The CPU should not touch the buffer after we mapped it. - -Cc: stable@kernel.org -Reported-by: Francesco Gringoli <francesco.gringoli@ing.unibs.it> -Signed-off-by: Michael Buesch <mb@bu3sch.de> - ---- - ---- a/drivers/net/wireless/b43/dma.c -+++ b/drivers/net/wireless/b43/dma.c -@@ -555,11 +555,32 @@ address_error: - return 1; - } - -+static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) -+{ -+ unsigned char *f = skb->data + ring->frameoffset; -+ -+ return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF); -+} -+ -+static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb) -+{ -+ struct b43_rxhdr_fw4 *rxhdr; -+ unsigned char *frame; -+ -+ /* This poisons the RX buffer to detect DMA failures. */ -+ -+ rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); -+ rxhdr->frame_len = 0; -+ -+ B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2); -+ frame = skb->data + ring->frameoffset; -+ memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */); -+} -+ - static int setup_rx_descbuffer(struct b43_dmaring *ring, - struct b43_dmadesc_generic *desc, - struct b43_dmadesc_meta *meta, gfp_t gfp_flags) - { -- struct b43_rxhdr_fw4 *rxhdr; - dma_addr_t dmaaddr; - struct sk_buff *skb; - -@@ -568,6 +589,7 @@ static int setup_rx_descbuffer(struct b4 - skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); - if (unlikely(!skb)) - return -ENOMEM; -+ b43_poison_rx_buffer(ring, skb); - dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { - /* ugh. try to realloc in zone_dma */ -@@ -578,6 +600,7 @@ static int setup_rx_descbuffer(struct b4 - skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); - if (unlikely(!skb)) - return -ENOMEM; -+ b43_poison_rx_buffer(ring, skb); - dmaaddr = map_descbuffer(ring, skb->data, - ring->rx_buffersize, 0); - if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { -@@ -592,9 +615,6 @@ static int setup_rx_descbuffer(struct b4 - ring->ops->fill_descriptor(ring, desc, dmaaddr, - ring->rx_buffersize, 0, 0, 0); - -- rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); -- rxhdr->frame_len = 0; -- - return 0; - } - -@@ -1489,6 +1509,15 @@ static void dma_rx(struct b43_dmaring *r - goto drop; - } - } -+ 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; -+ } - if (unlikely(len > ring->rx_buffersize)) { - /* The data did not fit into one descriptor buffer - * and is split over multiple buffers. |