[U-Boot] [PATCH v2 1/3] net: macb: enable dcache in macb
Bo Shen
voice.shen at atmel.com
Tue May 20 03:50:04 CEST 2014
Hi Josh,
On 05/19/2014 07:51 PM, Josh Wu wrote:
> 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 at atmel.com>
For this patch set, tested ok on sama5d3xek board.
Tested-by: Bo Shen <voice.shen at atmel.com>
Acked-by: Bo Shen <voice.shen at atmel.com>
Best Regards,
Bo Shen
> ---
> v1 -> v2:
> no change.
>
> drivers/net/macb.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/drivers/net/macb.c b/drivers/net/macb.c
> index 781a272..b18f07b 100644
> --- a/drivers/net/macb.c
> +++ b/drivers/net/macb.c
> @@ -194,6 +194,39 @@ int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
> }
> #endif
>
> +#define IS_RX 1
> +#define IS_TX 0
> +static inline void macb_invalidate_ring_desc(struct macb_device *macb, bool is_rx)
> +{
> + if (is_rx)
> + invalidate_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
> + CONFIG_SYS_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
> + else
> + invalidate_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
> + CONFIG_SYS_MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc));
> +}
> +
> +static inline void macb_flush_ring_desc(struct macb_device *macb, bool is_rx)
> +{
> + if (is_rx)
> + flush_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
> + CONFIG_SYS_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
> + else
> + flush_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
> + CONFIG_SYS_MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc));
> +}
> +
> +static inline void macb_flush_rx_buffer(struct macb_device *macb)
> +{
> + flush_dcache_range(macb->rx_buffer_dma,
> + macb->rx_buffer_dma + CONFIG_SYS_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 + CONFIG_SYS_MACB_RX_BUFFER_SIZE);
> +}
>
> #if defined(CONFIG_CMD_NET)
>
> @@ -217,6 +250,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, IS_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));
>
> /*
> @@ -225,6 +261,7 @@ static int macb_send(struct eth_device *netdev, void *packet, int length)
> */
> for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) {
> barrier();
> + macb_invalidate_ring_desc(macb, IS_TX);
> ctrl = macb->tx_ring[tx_head].ctrl;
> if (ctrl & TXBUF_USED)
> break;
> @@ -253,6 +290,8 @@ static void reclaim_rx_buffers(struct macb_device *macb,
> unsigned int i;
>
> i = macb->rx_tail;
> +
> + macb_invalidate_ring_desc(macb, IS_RX);
> while (i > new_tail) {
> macb->rx_ring[i].addr &= ~RXADDR_USED;
> i++;
> @@ -266,6 +305,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
> }
>
> barrier();
> + macb_flush_ring_desc(macb, IS_RX);
> macb->rx_tail = new_tail;
> }
>
> @@ -279,6 +319,8 @@ static int macb_recv(struct eth_device *netdev)
> u32 status;
>
> for (;;) {
> + macb_invalidate_ring_desc(macb, IS_RX);
> +
> if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
> return -1;
>
> @@ -292,6 +334,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 +550,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, IS_RX);
> + macb_flush_rx_buffer(macb);
> +
> for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) {
> macb->tx_ring[i].addr = 0;
> if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1))
> @@ -513,6 +560,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, IS_TX);
> +
> macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
>
> macb_writel(macb, RBQP, macb->rx_ring_dma);
> @@ -663,6 +712,8 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
> * sizeof(struct macb_dma_desc),
> &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;
>
>
More information about the U-Boot
mailing list