diff options
author | Paul Burton <paul.burton@imgtec.com> | 2014-04-07 16:41:47 +0100 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2014-04-18 10:42:30 -0400 |
commit | a354ddc3d7412c6d7cc702de60be32e580ccf348 (patch) | |
tree | cf49a6530090852c02dab05228ebc358de25787a /drivers/net/pcnet.c | |
parent | f1ae382dfd3850f4fbf34d794a31b8a1d1a5c389 (diff) | |
download | u-boot-a354ddc3d7412c6d7cc702de60be32e580ccf348.zip u-boot-a354ddc3d7412c6d7cc702de60be32e580ccf348.tar.gz u-boot-a354ddc3d7412c6d7cc702de60be32e580ccf348.tar.bz2 |
pcnet: align rx buffers for cache invalidation
The RX buffers are invalidated when a packet is received, however they
were not suitably cache-line aligned. Allocate them seperately to the
pcnet_priv structure and align to ARCH_DMA_MINALIGN in order to ensure
suitable alignment for the cache invalidation, preventing anything else
being placed in the same lines & lost.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Diffstat (limited to 'drivers/net/pcnet.c')
-rw-r--r-- | drivers/net/pcnet.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 8c334c7..2802411 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -80,7 +80,7 @@ struct pcnet_uncached_priv { typedef struct pcnet_priv { struct pcnet_uncached_priv *uc; /* Receive Buffer space */ - unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; + unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; int cur_rx; int cur_tx; } pcnet_priv_t; @@ -335,6 +335,10 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) flush_dcache_range(addr, addr + sizeof(*lp->uc)); addr = UNCACHED_SDRAM(addr); lp->uc = (struct pcnet_uncached_priv *)addr; + + addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->rx_buf)); + flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); + lp->rx_buf = (void *)addr; } uc = lp->uc; @@ -348,7 +352,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - uc->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]); + uc->rx_ring[i].base = PCI_TO_MEM_LE(dev, (*lp->rx_buf)[i]); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); PCNET_DEBUG1 @@ -467,6 +471,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) static int pcnet_recv (struct eth_device *dev) { struct pcnet_rx_head *entry; + unsigned char *buf; int pkt_len = 0; u16 status; @@ -500,14 +505,12 @@ static int pcnet_recv (struct eth_device *dev) printf("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); } else { - invalidate_dcache_range( - (unsigned long)lp->rx_buf[lp->cur_rx], - (unsigned long)lp->rx_buf[lp->cur_rx] + - pkt_len); - NetReceive(lp->rx_buf[lp->cur_rx], pkt_len); + buf = (*lp->rx_buf)[lp->cur_rx]; + invalidate_dcache_range((unsigned long)buf, + (unsigned long)buf + pkt_len); + NetReceive(buf, pkt_len); PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", - lp->cur_rx, pkt_len, - lp->rx_buf[lp->cur_rx]); + lp->cur_rx, pkt_len, buf); } } entry->status |= cpu_to_le16(0x8000); |