summaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch')
-rw-r--r--target/linux/generic/patches-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch68
1 files changed, 68 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch b/target/linux/generic/patches-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch
new file mode 100644
index 0000000000..f26e42c20d
--- /dev/null
+++ b/target/linux/generic/patches-3.18/077-07-bgmac-simplify-rx-DMA-error-handling.patch
@@ -0,0 +1,68 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 12 Apr 2015 22:23:07 +0200
+Subject: [PATCH] bgmac: simplify rx DMA error handling
+
+Unmap the DMA buffer before checking it. If it is poisoned, map it again
+and pass it back to the hardware.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -405,25 +405,20 @@ static int bgmac_dma_rx_read(struct bgma
+ u16 len, flags;
+
+ /* Unmap buffer to make it accessible to the CPU */
+- dma_sync_single_for_cpu(dma_dev, slot->dma_addr,
+- BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
++ dma_unmap_single(dma_dev, slot->dma_addr,
++ BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
+
+ /* Get info from the header */
+ len = le16_to_cpu(rx->len);
+ flags = le16_to_cpu(rx->flags);
+
+ do {
+- dma_addr_t old_dma_addr = slot->dma_addr;
+ int err;
+
+ /* Check for poison and drop or pass the packet */
+ if (len == 0xdead && flags == 0xbeef) {
+ bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
+ ring->start);
+- dma_sync_single_for_device(dma_dev,
+- slot->dma_addr,
+- BGMAC_RX_BUF_SIZE,
+- DMA_FROM_DEVICE);
+ break;
+ }
+
+@@ -436,18 +431,8 @@ static int bgmac_dma_rx_read(struct bgma
+ /* Poison the old skb */
+ rx->len = cpu_to_le16(0xdead);
+ rx->flags = cpu_to_le16(0xbeef);
+-
+- dma_sync_single_for_device(dma_dev,
+- slot->dma_addr,
+- BGMAC_RX_BUF_SIZE,
+- DMA_FROM_DEVICE);
+ break;
+ }
+- bgmac_dma_rx_setup_desc(bgmac, ring, ring->start);
+-
+- /* Unmap old skb, we'll pass it to the netfif */
+- dma_unmap_single(dma_dev, old_dma_addr,
+- BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
+
+ skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
+ skb_put(skb, BGMAC_RX_FRAME_OFFSET +
+@@ -461,6 +446,8 @@ static int bgmac_dma_rx_read(struct bgma
+ handled++;
+ } while (0);
+
++ bgmac_dma_rx_setup_desc(bgmac, ring, ring->start);
++
+ if (++ring->start >= BGMAC_RX_RING_SLOTS)
+ ring->start = 0;
+