kernel: add bgmac fixes for various issues
[openwrt/openwrt.git] / target / linux / generic / patches-3.18 / 077-07-bgmac-fix-DMA-rx-corruption.patch
1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Sun, 12 Apr 2015 11:59:47 +0200
3 Subject: [PATCH] bgmac: fix DMA rx corruption
4
5 The driver needs to inform the hardware about the first invalid (not yet
6 filled) rx slot, by writing its DMA descriptor pointer offset to the
7 BGMAC_DMA_RX_INDEX register.
8
9 This register was set to a value exceeding the rx ring size, effectively
10 allowing the hardware constant access to the full ring, regardless of
11 which slots are initialized.
12
13 Fix this by updating the register in bgmac_dma_rx_setup_desc.
14
15 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
16 ---
17
18 --- a/drivers/net/ethernet/broadcom/bgmac.c
19 +++ b/drivers/net/ethernet/broadcom/bgmac.c
20 @@ -380,6 +380,12 @@ static void bgmac_dma_rx_setup_desc(stru
21 dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr));
22 dma_desc->ctl0 = cpu_to_le32(ctl0);
23 dma_desc->ctl1 = cpu_to_le32(ctl1);
24 +
25 + desc_idx = (desc_idx + 1) % BGMAC_RX_RING_SLOTS;
26 +
27 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
28 + ring->index_base +
29 + desc_idx * sizeof(struct bgmac_dma_desc));
30 }
31
32 static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
33 @@ -394,9 +400,7 @@ static int bgmac_dma_rx_read(struct bgma
34 end_slot &= BGMAC_DMA_RX_STATDPTR;
35 end_slot /= sizeof(struct bgmac_dma_desc);
36
37 - ring->end = end_slot;
38 -
39 - while (ring->start != ring->end) {
40 + while (ring->start != end_slot) {
41 struct device *dma_dev = bgmac->core->dma_dev;
42 struct bgmac_slot_info *slot = &ring->slots[ring->start];
43 struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET;
44 @@ -693,10 +697,6 @@ static void bgmac_dma_init(struct bgmac
45 for (j = 0; j < ring->num_slots; j++)
46 bgmac_dma_rx_setup_desc(bgmac, ring, j);
47
48 - bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
49 - ring->index_base +
50 - ring->num_slots * sizeof(struct bgmac_dma_desc));
51 -
52 ring->start = 0;
53 ring->end = 0;
54 }