diff mbox

[U-Boot,2/3] pcnet: align rx buffers for cache invalidation

Message ID 1396885308-61884-3-git-send-email-paul.burton@imgtec.com
State Superseded
Delegated to: Tom Rini
Headers show

Commit Message

Paul Burton April 7, 2014, 3:41 p.m. UTC
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>
---
 drivers/net/pcnet.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

Comments

Tom Rini April 18, 2014, 9:01 p.m. UTC | #1
On Mon, Apr 07, 2014 at 04:41:47PM +0100, Paul Burton wrote:

> 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>

Applied to u-boot/master, thanks!
diff mbox

Patch

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);