diff options
Diffstat (limited to 'target/linux/generic/patches-3.18/077-07-bgmac-fix-DMA-rx-corruption.patch')
-rw-r--r-- | target/linux/generic/patches-3.18/077-07-bgmac-fix-DMA-rx-corruption.patch | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.18/077-07-bgmac-fix-DMA-rx-corruption.patch b/target/linux/generic/patches-3.18/077-07-bgmac-fix-DMA-rx-corruption.patch new file mode 100644 index 0000000000..55e80332bd --- /dev/null +++ b/target/linux/generic/patches-3.18/077-07-bgmac-fix-DMA-rx-corruption.patch @@ -0,0 +1,54 @@ +From: Felix Fietkau <nbd@openwrt.org> +Date: Sun, 12 Apr 2015 11:59:47 +0200 +Subject: [PATCH] bgmac: fix DMA rx corruption + +The driver needs to inform the hardware about the first invalid (not yet +filled) rx slot, by writing its DMA descriptor pointer offset to the +BGMAC_DMA_RX_INDEX register. + +This register was set to a value exceeding the rx ring size, effectively +allowing the hardware constant access to the full ring, regardless of +which slots are initialized. + +Fix this by updating the register in bgmac_dma_rx_setup_desc. + +Signed-off-by: Felix Fietkau <nbd@openwrt.org> +--- + +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -380,6 +380,12 @@ static void bgmac_dma_rx_setup_desc(stru + dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr)); + dma_desc->ctl0 = cpu_to_le32(ctl0); + dma_desc->ctl1 = cpu_to_le32(ctl1); ++ ++ desc_idx = (desc_idx + 1) % BGMAC_RX_RING_SLOTS; ++ ++ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, ++ ring->index_base + ++ desc_idx * sizeof(struct bgmac_dma_desc)); + } + + static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, +@@ -394,9 +400,7 @@ static int bgmac_dma_rx_read(struct bgma + end_slot &= BGMAC_DMA_RX_STATDPTR; + end_slot /= sizeof(struct bgmac_dma_desc); + +- ring->end = end_slot; +- +- while (ring->start != ring->end) { ++ while (ring->start != end_slot) { + struct device *dma_dev = bgmac->core->dma_dev; + struct bgmac_slot_info *slot = &ring->slots[ring->start]; + struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET; +@@ -693,10 +697,6 @@ static void bgmac_dma_init(struct bgmac + for (j = 0; j < ring->num_slots; j++) + bgmac_dma_rx_setup_desc(bgmac, ring, j); + +- bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX, +- ring->index_base + +- ring->num_slots * sizeof(struct bgmac_dma_desc)); +- + ring->start = 0; + ring->end = 0; + } |