The current descriptor register is written before the Rx descriptors
are filled in and flushed, so the register is programmed against a ring
that does not exist yet.

Write CURDESC after the descriptor setup and the flush_cache() calls,
so it is programmed only once the ring it refers to is complete in
memory.

The channel is halted for the whole of that window, so the old order
reads no half-built descriptor either.

Signed-off-by: Padmarao Begari <[email protected]>
---
 drivers/net/xilinx_axi_mrmac.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/xilinx_axi_mrmac.c b/drivers/net/xilinx_axi_mrmac.c
index 2c97e9576c9..45112a42758 100644
--- a/drivers/net/xilinx_axi_mrmac.c
+++ b/drivers/net/xilinx_axi_mrmac.c
@@ -179,9 +179,6 @@ static int axi_mrmac_start(struct udevice *dev)
        /* Disable all Rx interrupts before RxBD space setup */
        clrbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK);
 
-       /* Update current descriptor */
-       axi_mrmac_dma_write(&priv->rx_bd[0], &priv->mcdma_rx->current);
-
        /*
         * Setup Rx BDs as a closed ring: every descriptor points at the next
         * one and the last one wraps back to the first, each with its own
@@ -213,6 +210,9 @@ static int axi_mrmac_start(struct udevice *dev)
         */
        flush_cache((phys_addr_t)priv->rx_buf, RX_BUFF_TOTAL_SIZE);
 
+       /* Update current descriptor once the ring is built and flushed */
+       axi_mrmac_dma_write(&priv->rx_bd[0], &priv->mcdma_rx->current);
+
        /* Start the hardware */
        setbits_le32(&priv->s2mm_cmn->control, XMCDMA_CR_RUNSTOP_MASK);
        setbits_le32(&priv->mm2s_cmn->control, XMCDMA_CR_RUNSTOP_MASK);
-- 
2.34.1

Reply via email to