diff mbox series

net: zynq_gem: Add cache flush to zynq_gem_free_pkt

Message ID a4d4a0326e1ec4ba2f56129fa034ed4bcd297ffe.1582630966.git.michal.simek@xilinx.com
State Accepted
Commit 0f8defd8910ed1a64687f79507c8332b72844aee
Delegated to: Michal Simek
Headers show
Series net: zynq_gem: Add cache flush to zynq_gem_free_pkt | expand

Commit Message

Michal Simek Feb. 25, 2020, 11:42 a.m. UTC
From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>

Add cache flush to zynq_gem_free_pkt. This is necessary
because some net routines would modify this buffer in place.
The cache_invalidate in the zynq_gem_recv function would cause
the modifications to the buffer to overwrite the DMA from the GEM,
if cache coherency is not enabled in the GEM, the next time the
buffer is in use.

Flushing the cache when the buffer is no longer in use by the
net functions ensures that the GEM DMA is going to take place
into a clean buffer.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/net/zynq_gem.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Michal Simek April 6, 2020, 10:59 a.m. UTC | #1
Ășt 25. 2. 2020 v 12:42 odesĂ­latel Michal Simek <michal.simek@xilinx.com> napsal:
>
> From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
>
> Add cache flush to zynq_gem_free_pkt. This is necessary
> because some net routines would modify this buffer in place.
> The cache_invalidate in the zynq_gem_recv function would cause
> the modifications to the buffer to overwrite the DMA from the GEM,
> if cache coherency is not enabled in the GEM, the next time the
> buffer is in use.
>
> Flushing the cache when the buffer is no longer in use by the
> net functions ensures that the GEM DMA is going to take place
> into a clean buffer.
>
> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
>
>  drivers/net/zynq_gem.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
> index 5f2f87d352c4..cfd14665a70d 100644
> --- a/drivers/net/zynq_gem.c
> +++ b/drivers/net/zynq_gem.c
> @@ -578,6 +578,7 @@ static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length)
>         struct zynq_gem_priv *priv = dev_get_priv(dev);
>         struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
>         struct emac_bd *first_bd;
> +       dma_addr_t addr;
>
>         if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) {
>                 priv->rx_first_buf = priv->rxbd_current;
> @@ -592,6 +593,17 @@ static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length)
>                 first_bd->status = 0xF0000000;
>         }
>
> +       /* Flush the cache for the packet as well */
> +#if defined(CONFIG_PHYS_64BIT)
> +       addr = (dma_addr_t)((current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK)
> +               | ((dma_addr_t)current_bd->addr_hi << 32));
> +#else
> +       addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
> +#endif
> +       flush_dcache_range(addr, addr + roundup(PKTSIZE_ALIGN,
> +                                               ARCH_DMA_MINALIGN));
> +       barrier();
> +
>         if ((++priv->rxbd_current) >= RX_BUF)
>                 priv->rxbd_current = 0;
>
> --
> 2.25.1
>

Applied.
M
diff mbox series

Patch

diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 5f2f87d352c4..cfd14665a70d 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -578,6 +578,7 @@  static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length)
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
 	struct emac_bd *first_bd;
+	dma_addr_t addr;
 
 	if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) {
 		priv->rx_first_buf = priv->rxbd_current;
@@ -592,6 +593,17 @@  static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length)
 		first_bd->status = 0xF0000000;
 	}
 
+	/* Flush the cache for the packet as well */
+#if defined(CONFIG_PHYS_64BIT)
+	addr = (dma_addr_t)((current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK)
+		| ((dma_addr_t)current_bd->addr_hi << 32));
+#else
+	addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
+#endif
+	flush_dcache_range(addr, addr + roundup(PKTSIZE_ALIGN,
+						ARCH_DMA_MINALIGN));
+	barrier();
+
 	if ((++priv->rxbd_current) >= RX_BUF)
 		priv->rxbd_current = 0;