[PATCH 2/8] net: mrmac: use a driver-owned RX buffer pool

Padmarao Begari <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
The RX path borrows the shared net_rx_packets[] global for its buffer
descriptors. That global is capped at PKTBUFSRX system-wide and is not
private to this device, so it cannot scale to a deeper RX ring and does
not compose well with multiple different drivers sharing it.

Allocate a driver-owned RX buffer pool (rx_buf, sized
RX_DESC * PKTSIZE_ALIGN) in probe() and point the RX descriptors at
slices of it instead.

Signed-off-by: Padmarao Begari <[email protected]>
---
 drivers/net/xilinx_axi_mrmac.c | 24 +++++++++++++++++-------
 drivers/net/xilinx_axi_mrmac.h |  1 +
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/xilinx_axi_mrmac.c b/drivers/net/xilinx_axi_mrmac.c
index 5ff304fc971..d9d4756d14f 100644
--- a/drivers/net/xilinx_axi_mrmac.c
+++ b/drivers/net/xilinx_axi_mrmac.c
@@ -185,17 +185,17 @@ static int axi_mrmac_start(struct udevice *dev)
 	memset(priv->rx_bd[0], 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)net_rx_packets[0]);
+	priv->rx_bd[0]->buf_addr = lower_32_bits((u64)priv->rx_buf);
 
 	priv->rx_bd[1]->next_desc = lower_32_bits((u64)priv->rx_bd[0]);
-	priv->rx_bd[1]->buf_addr = lower_32_bits((u64)net_rx_packets[1]);
+	priv->rx_bd[1]->buf_addr = lower_32_bits((u64)priv->rx_buf + PKTSIZE_ALIGN);
 
 	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)net_rx_packets[0]);
+		priv->rx_bd[0]->buf_addr_msb = upper_32_bits((u64)priv->rx_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)net_rx_packets[1]);
+		priv->rx_bd[1]->buf_addr_msb = upper_32_bits((u64)priv->rx_buf + PKTSIZE_ALIGN);
 	}
 
 	priv->rx_bd[0]->cntrl = PKTSIZE_ALIGN;
@@ -207,7 +207,7 @@ static int axi_mrmac_start(struct udevice *dev)
 	/* It is necessary to flush rx buffers because if you don't do it
 	 * then cache can contain uninitialized data
 	 */
-	flush_cache((phys_addr_t)priv->rx_bd[0]->buf_addr, RX_BUFF_TOTAL_SIZE);
+	flush_cache((phys_addr_t)priv->rx_buf, RX_BUFF_TOTAL_SIZE);
 
 	/* Start the hardware */
 	setbits_le32(&priv->s2mm_cmn->control, XMCDMA_CR_RUNSTOP_MASK);
@@ -413,7 +413,7 @@ static int axi_mrmac_free_pkt(struct udevice *dev, uchar *packet, int length)
 
 #ifdef DEBUG
 	/* It is useful to clear buffer to be sure that it is consistent */
-	memset(priv->rx_bd[0]->buf_addr, 0, RX_BUFF_TOTAL_SIZE);
+	memset(priv->rx_buf, 0, RX_BUFF_TOTAL_SIZE);
 #endif
 	/* Disable all Rx interrupts before RxBD space setup */
 	clrbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK);
@@ -430,7 +430,7 @@ static int axi_mrmac_free_pkt(struct udevice *dev, uchar *packet, int length)
 	/* It is necessary to flush rx buffers because if you don't do it
 	 * then cache will contain previous packet
 	 */
-	flush_cache((phys_addr_t)priv->rx_bd[0]->buf_addr, RX_BUFF_TOTAL_SIZE);
+	flush_cache((phys_addr_t)priv->rx_buf, RX_BUFF_TOTAL_SIZE);
 
 	/* Enable all IRQ */
 	setbits_le32(&priv->mcdma_rx->control, XMCDMA_IRQ_ALL_MASK);
@@ -495,6 +495,15 @@ static int axi_mrmac_probe(struct udevice *dev)
 	priv->rx_bd[1] = (struct mcdma_bd *)((ulong)priv->rx_bd[0] +
 					     sizeof(struct mcdma_bd));
 
+	/*
+	 * Use a driver-owned RX buffer pool rather than the shared
+	 * net_rx_packets[] global, which is capped at PKTBUFSRX system-wide
+	 * and not private to this device.
+	 */
+	priv->rx_buf = memalign(ARCH_DMA_MINALIGN, RX_BUFF_TOTAL_SIZE);
+	if (!priv->rx_buf)
+		return -ENOMEM;
+
 	priv->txminframe = memalign(ARCH_DMA_MINALIGN, MIN_PKT_SIZE);
 	if (!priv->txminframe)
 		return -ENOMEM;
@@ -509,6 +518,7 @@ static int axi_mrmac_remove(struct udevice *dev)
 	/* Free buffer descriptors */
 	free(priv->tx_bd[0]);
 	free(priv->rx_bd[0]);
+	free(priv->rx_buf);
 	free(priv->txminframe);
 
 	return 0;
diff --git a/drivers/net/xilinx_axi_mrmac.h b/drivers/net/xilinx_axi_mrmac.h
index e2c2105450c..17849d39873 100644
--- a/drivers/net/xilinx_axi_mrmac.h
+++ b/drivers/net/xilinx_axi_mrmac.h
@@ -37,6 +37,7 @@ struct axi_mrmac_priv {
 	struct mcdma_bd *tx_bd[TX_DESC];
 	struct mcdma_bd *rx_bd[RX_DESC];
 	u8 *txminframe;		/* Pointer to hold min length Tx frame(60) */
+	u8 *rx_buf;		/* Driver-owned RX buffer pool (RX_DESC * PKTSIZE_ALIGN) */
 	u32 mrmac_rate;		/* Speed to configure(Read from DT 10G/25G..) */
 };
 
-- 
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.