[PATCH 5/8] net: mrmac: initialize the Rx BD ring in a loop

Padmarao Begari <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
The Rx descriptors are chained by hand, one assignment per descriptor
and per field. Adding a descriptor means adding another block of
next_desc/buf_addr/cntrl assignments, so the number of Rx descriptors
is effectively frozen at two.

Build the same chain in a loop over RX_DESC instead. Each descriptor
points at its successor, the last one wraps back to the first, and each
gets its own PKTSIZE_ALIGN slice of the Rx buffer pool. The tail
descriptor is now the last one of the ring rather than a hardcoded
rx_bd[1]. The resulting ring is identical to the hand-written one for
RX_DESC = 2, but the descriptor count is now a single constant to
change.

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

diff --git a/drivers/net/xilinx_axi_mrmac.c b/drivers/net/xilinx_axi_mrmac.c
index d77b0e3445b..2c97e9576c9 100644
--- a/drivers/net/xilinx_axi_mrmac.c
+++ b/drivers/net/xilinx_axi_mrmac.c
@@ -162,6 +162,7 @@ static int axi_mrmac_start(struct udevice *dev)
 {
 	struct axi_mrmac_priv *priv = dev_get_priv(dev);
 	struct mrmac_regs *regs = priv->iobase;
+	int i;
 
 	/*
 	 * Initialize MCDMA engine. MCDMA engine must be initialized before
@@ -181,27 +182,30 @@ static int axi_mrmac_start(struct udevice *dev)
 	/* Update current descriptor */
 	axi_mrmac_dma_write(&priv->rx_bd[0], &priv->mcdma_rx->current);
 
-	/* Setup Rx BD. MRMAC needs atleast two descriptors */
+	/*
+	 * 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
+	 * slice of the Rx buffer pool. MRMAC needs at least two descriptors.
+	 */
 	memset(priv->rx_bd, 0, RX_BD_TOTAL_SIZE);
 
-	priv->rx_bd[0].next_desc = lower_32_bits((u64)&priv->rx_bd[1]);
-	priv->rx_bd[0].buf_addr = lower_32_bits((u64)priv->rx_buf);
+	for (i = 0; i < RX_DESC; i++) {
+		struct mcdma_bd *next = &priv->rx_bd[(i + 1) % RX_DESC];
+		u8 *buf = priv->rx_buf + i * PKTSIZE_ALIGN;
+		struct mcdma_bd *bd = &priv->rx_bd[i];
 
-	priv->rx_bd[1].next_desc = lower_32_bits((u64)&priv->rx_bd[0]);
-	priv->rx_bd[1].buf_addr = lower_32_bits((u64)priv->rx_buf + PKTSIZE_ALIGN);
+		bd->next_desc = lower_32_bits((u64)next);
+		bd->buf_addr = lower_32_bits((u64)buf);
 
-	if (IS_ENABLED(CONFIG_PHYS_64BIT)) {
-		priv->rx_bd[0].next_desc_msb = upper_32_bits((u64)&priv->rx_bd[1]);
-		priv->rx_bd[0].buf_addr_msb = upper_32_bits((u64)priv->rx_buf);
+		if (IS_ENABLED(CONFIG_PHYS_64BIT)) {
+			bd->next_desc_msb = upper_32_bits((u64)next);
+			bd->buf_addr_msb = upper_32_bits((u64)buf);
+		}
 
-		priv->rx_bd[1].next_desc_msb = upper_32_bits((u64)&priv->rx_bd[0]);
-		priv->rx_bd[1].buf_addr_msb = upper_32_bits((u64)priv->rx_buf + PKTSIZE_ALIGN);
+		bd->cntrl = PKTSIZE_ALIGN;
 	}
 
-	priv->rx_bd[0].cntrl = PKTSIZE_ALIGN;
-	priv->rx_bd[1].cntrl = PKTSIZE_ALIGN;
-
-	/* Flush the last BD so DMA core could see the updates */
+	/* Flush the BDs so DMA core could see the updates */
 	flush_cache((phys_addr_t)priv->rx_bd, RX_BD_TOTAL_SIZE);
 
 	/* It is necessary to flush rx buffers because if you don't do it
@@ -218,7 +222,7 @@ static int axi_mrmac_start(struct udevice *dev)
 	setbits_le32(&priv->mcdma_rx->control, XMCDMA_CR_RUNSTOP_MASK);
 
 	/* Update tail descriptor. Now it's ready to receive data */
-	axi_mrmac_dma_write(&priv->rx_bd[1], &priv->mcdma_rx->tail);
+	axi_mrmac_dma_write(&priv->rx_bd[RX_DESC - 1], &priv->mcdma_rx->tail);
 
 	/* Enable Tx */
 	setbits_le32(&regs->tx_config, MRMAC_TX_EN_MASK);
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.