diff mbox

[U-Boot,RESEND,v2,1/3] net: macb: enable dcache in macb

Message ID 1401179465-17298-1-git-send-email-josh.wu@atmel.com
State Accepted, archived
Delegated to: Andreas Bießmann
Headers show

Commit Message

Josh Wu May 27, 2014, 8:31 a.m. UTC
Add to code to flush the dcache after we writing in DMA buffer.
Also we need invalidate the dcache before we check the status in the
DMA buffer.

Tested in SAMA5D3x-EK with gmac0. Tftp download speed shows in below:
	Disable DCache: 1.1 MiB/s
	Enable DCache: 1.6 MiB/s
Increase speed with about 40%.

The code should have no impact with the boards which are not
enable_dcache().
Tested in AT91SAM9M10G45EK.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
---
v2 resend: 
  1. rebase Andreas' macb clean up patch: http://patchwork.ozlabs.org/patch/352624/
  2. add definitions: MACB_TX/RX_DMA_DESC_SIZE for the TX/RX dma descriptor buffer size.
  3. replace the IS_RX/IS_TX with RX/TX, which is more readable.
  4. fix checkpatch warnings.

v1 -> v2: none

 drivers/net/macb.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 57 insertions(+), 4 deletions(-)

Comments

Andreas Bießmann June 14, 2014, 4:14 p.m. UTC | #1
Dear Josh Wu,

Josh Wu <Josh.wu@atmel.com> writes:
>Add to code to flush the dcache after we writing in DMA buffer.
>Also we need invalidate the dcache before we check the status in the
>DMA buffer.
>
>Tested in SAMA5D3x-EK with gmac0. Tftp download speed shows in below:
>	Disable DCache: 1.1 MiB/s
>	Enable DCache: 1.6 MiB/s
>Increase speed with about 40%.
>
>The code should have no impact with the boards which are not
>enable_dcache().
>Tested in AT91SAM9M10G45EK.
>
>Signed-off-by: Josh Wu <josh.wu@atmel.com>
>
>---
>v2 resend: 
>  1. rebase Andreas' macb clean up patch: http://patchwork.ozlabs.org/patch/352624/
>  2. add definitions: MACB_TX/RX_DMA_DESC_SIZE for the TX/RX dma descriptor buffer size.
>  3. replace the IS_RX/IS_TX with RX/TX, which is more readable.
>  4. fix checkpatch warnings.
>
>v1 -> v2: none
>
> drivers/net/macb.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 57 insertions(+), 4 deletions(-)

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bießmann
diff mbox

Patch

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 750331d..01a94a4 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -51,6 +51,10 @@  struct macb_dma_desc {
 	u32	ctrl;
 };
 
+#define DMA_DESC_BYTES(n)	(n * sizeof(struct macb_dma_desc))
+#define MACB_TX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_TX_RING_SIZE))
+#define MACB_RX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_RX_RING_SIZE))
+
 #define RXADDR_USED		0x00000001
 #define RXADDR_WRAP		0x00000002
 
@@ -194,6 +198,39 @@  int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
 }
 #endif
 
+#define RX	1
+#define TX	0
+static inline void macb_invalidate_ring_desc(struct macb_device *macb, bool rx)
+{
+	if (rx)
+		invalidate_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
+			MACB_RX_DMA_DESC_SIZE);
+	else
+		invalidate_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
+			MACB_TX_DMA_DESC_SIZE);
+}
+
+static inline void macb_flush_ring_desc(struct macb_device *macb, bool rx)
+{
+	if (rx)
+		flush_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
+			MACB_RX_DMA_DESC_SIZE);
+	else
+		flush_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
+			MACB_TX_DMA_DESC_SIZE);
+}
+
+static inline void macb_flush_rx_buffer(struct macb_device *macb)
+{
+	flush_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
+				MACB_RX_BUFFER_SIZE);
+}
+
+static inline void macb_invalidate_rx_buffer(struct macb_device *macb)
+{
+	invalidate_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
+				MACB_RX_BUFFER_SIZE);
+}
 
 #if defined(CONFIG_CMD_NET)
 
@@ -218,6 +255,9 @@  static int macb_send(struct eth_device *netdev, void *packet, int length)
 	macb->tx_ring[tx_head].ctrl = ctrl;
 	macb->tx_ring[tx_head].addr = paddr;
 	barrier();
+	macb_flush_ring_desc(macb, TX);
+	/* Do we need check paddr and length is dcache line aligned? */
+	flush_dcache_range(paddr, paddr + length);
 	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
 
 	/*
@@ -226,6 +266,7 @@  static int macb_send(struct eth_device *netdev, void *packet, int length)
 	 */
 	for (i = 0; i <= MACB_TX_TIMEOUT; i++) {
 		barrier();
+		macb_invalidate_ring_desc(macb, TX);
 		ctrl = macb->tx_ring[tx_head].ctrl;
 		if (ctrl & TXBUF_USED)
 			break;
@@ -254,6 +295,8 @@  static void reclaim_rx_buffers(struct macb_device *macb,
 	unsigned int i;
 
 	i = macb->rx_tail;
+
+	macb_invalidate_ring_desc(macb, RX);
 	while (i > new_tail) {
 		macb->rx_ring[i].addr &= ~RXADDR_USED;
 		i++;
@@ -267,6 +310,7 @@  static void reclaim_rx_buffers(struct macb_device *macb,
 	}
 
 	barrier();
+	macb_flush_ring_desc(macb, RX);
 	macb->rx_tail = new_tail;
 }
 
@@ -280,6 +324,8 @@  static int macb_recv(struct eth_device *netdev)
 	u32 status;
 
 	for (;;) {
+		macb_invalidate_ring_desc(macb, RX);
+
 		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
 			return -1;
 
@@ -293,6 +339,8 @@  static int macb_recv(struct eth_device *netdev)
 		if (status & RXBUF_FRAME_END) {
 			buffer = macb->rx_buffer + 128 * macb->rx_tail;
 			length = status & RXBUF_FRMLEN_MASK;
+
+			macb_invalidate_rx_buffer(macb);
 			if (wrapped) {
 				unsigned int headlen, taillen;
 
@@ -506,6 +554,9 @@  static int macb_init(struct eth_device *netdev, bd_t *bd)
 		macb->rx_ring[i].ctrl = 0;
 		paddr += 128;
 	}
+	macb_flush_ring_desc(macb, RX);
+	macb_flush_rx_buffer(macb);
+
 	for (i = 0; i < MACB_TX_RING_SIZE; i++) {
 		macb->tx_ring[i].addr = 0;
 		if (i == (MACB_TX_RING_SIZE - 1))
@@ -513,6 +564,8 @@  static int macb_init(struct eth_device *netdev, bd_t *bd)
 		else
 			macb->tx_ring[i].ctrl = TXBUF_USED;
 	}
+	macb_flush_ring_desc(macb, TX);
+
 	macb->rx_tail = 0;
 	macb->tx_head = 0;
 	macb->tx_tail = 0;
@@ -658,13 +711,13 @@  int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
 
 	macb->rx_buffer = dma_alloc_coherent(MACB_RX_BUFFER_SIZE,
 					     &macb->rx_buffer_dma);
-	macb->rx_ring = dma_alloc_coherent(MACB_RX_RING_SIZE
-					   * sizeof(struct macb_dma_desc),
+	macb->rx_ring = dma_alloc_coherent(MACB_RX_DMA_DESC_SIZE,
 					   &macb->rx_ring_dma);
-	macb->tx_ring = dma_alloc_coherent(MACB_TX_RING_SIZE
-					   * sizeof(struct macb_dma_desc),
+	macb->tx_ring = dma_alloc_coherent(MACB_TX_DMA_DESC_SIZE,
 					   &macb->tx_ring_dma);
 
+	/* TODO: we need check the rx/tx_ring_dma is dcache line aligned */
+
 	macb->regs = regs;
 	macb->phy_addr = phy_addr;