mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-09-10 12:39:22 -04:00
macb: Introduce a few barriers when dealing with DMA descriptors
There were a few theoretical possibilities that the compiler might optimize away DMA descriptor reads and/or writes and thus cause synchronization problems with the hardware. Insert barriers where we depend on reads/writes actually hitting memory. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
This commit is contained in:
parent
37837828d8
commit
04fcb5d38b
@ -51,6 +51,8 @@
|
|||||||
|
|
||||||
#include "macb.h"
|
#include "macb.h"
|
||||||
|
|
||||||
|
#define barrier() asm volatile("" ::: "memory")
|
||||||
|
|
||||||
#define CFG_MACB_RX_BUFFER_SIZE 4096
|
#define CFG_MACB_RX_BUFFER_SIZE 4096
|
||||||
#define CFG_MACB_RX_RING_SIZE (CFG_MACB_RX_BUFFER_SIZE / 128)
|
#define CFG_MACB_RX_RING_SIZE (CFG_MACB_RX_BUFFER_SIZE / 128)
|
||||||
#define CFG_MACB_TX_RING_SIZE 16
|
#define CFG_MACB_TX_RING_SIZE 16
|
||||||
@ -185,31 +187,31 @@ static int macb_send(struct eth_device *netdev, volatile void *packet,
|
|||||||
|
|
||||||
macb->tx_ring[tx_head].ctrl = ctrl;
|
macb->tx_ring[tx_head].ctrl = ctrl;
|
||||||
macb->tx_ring[tx_head].addr = paddr;
|
macb->tx_ring[tx_head].addr = paddr;
|
||||||
|
barrier();
|
||||||
macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
|
macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I guess this is necessary because the networking core may
|
* I guess this is necessary because the networking core may
|
||||||
* re-use the transmit buffer as soon as we return...
|
* re-use the transmit buffer as soon as we return...
|
||||||
*/
|
*/
|
||||||
i = 0;
|
for (i = 0; i <= CFG_MACB_TX_TIMEOUT; i++) {
|
||||||
while (!(macb->tx_ring[tx_head].ctrl & TXBUF_USED)) {
|
barrier();
|
||||||
if (i > CFG_MACB_TX_TIMEOUT) {
|
ctrl = macb->tx_ring[tx_head].ctrl;
|
||||||
printf("%s: TX timeout\n", netdev->name);
|
if (ctrl & TXBUF_USED)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
udelay(1);
|
udelay(1);
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_unmap_single(packet, length, paddr);
|
dma_unmap_single(packet, length, paddr);
|
||||||
|
|
||||||
if (i <= CFG_MACB_TX_TIMEOUT) {
|
if (i <= CFG_MACB_TX_TIMEOUT) {
|
||||||
ctrl = macb->tx_ring[tx_head].ctrl;
|
|
||||||
if (ctrl & TXBUF_UNDERRUN)
|
if (ctrl & TXBUF_UNDERRUN)
|
||||||
printf("%s: TX underrun\n", netdev->name);
|
printf("%s: TX underrun\n", netdev->name);
|
||||||
if (ctrl & TXBUF_EXHAUSTED)
|
if (ctrl & TXBUF_EXHAUSTED)
|
||||||
printf("%s: TX buffers exhausted in mid frame\n",
|
printf("%s: TX buffers exhausted in mid frame\n",
|
||||||
netdev->name);
|
netdev->name);
|
||||||
|
} else {
|
||||||
|
printf("%s: TX timeout\n", netdev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No one cares anyway */
|
/* No one cares anyway */
|
||||||
@ -234,6 +236,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barrier();
|
||||||
macb->rx_tail = new_tail;
|
macb->rx_tail = new_tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,6 +286,7 @@ static int macb_recv(struct eth_device *netdev)
|
|||||||
rx_tail = 0;
|
rx_tail = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
barrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user