mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 05:31:32 +00:00
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>
This commit is contained in:
parent
f1ae382dfd
commit
a354ddc3d7
1 changed files with 12 additions and 9 deletions
|
@ -80,7 +80,7 @@ struct pcnet_uncached_priv {
|
||||||
typedef struct pcnet_priv {
|
typedef struct pcnet_priv {
|
||||||
struct pcnet_uncached_priv *uc;
|
struct pcnet_uncached_priv *uc;
|
||||||
/* Receive Buffer space */
|
/* 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_rx;
|
||||||
int cur_tx;
|
int cur_tx;
|
||||||
} pcnet_priv_t;
|
} 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));
|
flush_dcache_range(addr, addr + sizeof(*lp->uc));
|
||||||
addr = UNCACHED_SDRAM(addr);
|
addr = UNCACHED_SDRAM(addr);
|
||||||
lp->uc = (struct pcnet_uncached_priv *)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;
|
uc = lp->uc;
|
||||||
|
@ -348,7 +352,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis)
|
||||||
*/
|
*/
|
||||||
lp->cur_rx = 0;
|
lp->cur_rx = 0;
|
||||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
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].buf_length = cpu_to_le16(-PKT_BUF_SZ);
|
||||||
uc->rx_ring[i].status = cpu_to_le16(0x8000);
|
uc->rx_ring[i].status = cpu_to_le16(0x8000);
|
||||||
PCNET_DEBUG1
|
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)
|
static int pcnet_recv (struct eth_device *dev)
|
||||||
{
|
{
|
||||||
struct pcnet_rx_head *entry;
|
struct pcnet_rx_head *entry;
|
||||||
|
unsigned char *buf;
|
||||||
int pkt_len = 0;
|
int pkt_len = 0;
|
||||||
u16 status;
|
u16 status;
|
||||||
|
|
||||||
|
@ -500,14 +505,12 @@ static int pcnet_recv (struct eth_device *dev)
|
||||||
printf("%s: Rx%d: invalid packet length %d\n",
|
printf("%s: Rx%d: invalid packet length %d\n",
|
||||||
dev->name, lp->cur_rx, pkt_len);
|
dev->name, lp->cur_rx, pkt_len);
|
||||||
} else {
|
} else {
|
||||||
invalidate_dcache_range(
|
buf = (*lp->rx_buf)[lp->cur_rx];
|
||||||
(unsigned long)lp->rx_buf[lp->cur_rx],
|
invalidate_dcache_range((unsigned long)buf,
|
||||||
(unsigned long)lp->rx_buf[lp->cur_rx] +
|
(unsigned long)buf + pkt_len);
|
||||||
pkt_len);
|
NetReceive(buf, pkt_len);
|
||||||
NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
|
|
||||||
PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
|
PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
|
||||||
lp->cur_rx, pkt_len,
|
lp->cur_rx, pkt_len, buf);
|
||||||
lp->rx_buf[lp->cur_rx]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry->status |= cpu_to_le16(0x8000);
|
entry->status |= cpu_to_le16(0x8000);
|
||||||
|
|
Loading…
Add table
Reference in a new issue