[openwrt/openwrt] realtek: eth: create new receive data structures

LEDE Commits lede-commits at lists.infradead.org
Thu Feb 12 01:20:11 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/82f3d4a6fab0501f24f1344f6354517e93374970

commit 82f3d4a6fab0501f24f1344f6354517e93374970
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Mon Feb 2 15:11:00 2026 +0100

    realtek: eth: create new receive data structures
    
    Define the needed structures for the redesign of the ethernet
    receive path. They are closely aligned with the already refactored
    transmit path.
    
    The only exception is the additional data buffer where the
    hardware can place the incoming data. This is allocated non-
    coherent and data will be manually synchronized. The old design
    used coherent (aka uncached) memory access.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/21856
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.12/drivers/net/ethernet/rtl838x_eth.c  | 49 ++++++++++++++++++++--
 1 file changed, 46 insertions(+), 3 deletions(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
index 31572fa5fc..7d672a6fb0 100644
--- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
+++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
@@ -34,6 +34,7 @@ int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type
  */
 
 #define RTETH_OWN_CPU		1
+#define RTETH_RX_RING_SIZE	128
 #define RTETH_RX_RINGS		2
 #define RTETH_TX_RING_SIZE	16
 #define RTETH_TX_RINGS		2
@@ -63,9 +64,18 @@ struct rteth_packet {
 	u16			len;
 	u16			cpu_tag[10];
 	/* software mangement and data part */
-	struct sk_buff		*skb;
+	union {
+		struct sk_buff	*skb;
+		char		*buf;
+	};
 } __packed __aligned(1);
 
+struct rteth_rx {
+	int			slot;
+	dma_addr_t		ring[RTETH_RX_RING_SIZE];
+	struct rteth_packet	packet[RTETH_RX_RING_SIZE];
+};
+
 struct rteth_tx {
 	int			slot;
 	dma_addr_t		ring[RTETH_TX_RING_SIZE];
@@ -207,6 +217,12 @@ struct rteth_ctrl {
 	u32 lastEvent;
 	u16 rxrings;
 	u16 rxringlen;
+	/* receive handling */
+	dma_addr_t		rx_buf_dma;
+	char			*rx_buf;
+	dma_addr_t		rx_data_dma;
+	spinlock_t		rx_lock;
+	struct rteth_rx		*rx_data;
 	/* transmit handling */
 	dma_addr_t		tx_dma;
 	spinlock_t		tx_lock;
@@ -550,7 +566,7 @@ static void rteth_setup_cpu_rx_rings(struct rteth_ctrl *ctrl)
 
 	if (ctrl->r->qm_pkt2cpu_intpri_map) {
 		for (int priority = 0; priority < 8; priority++) {
-			int ring = (priority % RTETH_RX_RINGS) + 5;
+			int ring = priority % RTETH_RX_RINGS;
 			int shift = priority * 3;
 
 			sw_w32_mask(0x7 << shift, ring << shift, ctrl->r->qm_pkt2cpu_intpri_map);
@@ -569,7 +585,7 @@ static void rteth_setup_cpu_rx_rings(struct rteth_ctrl *ctrl)
 		for (int reason = 0; reason < reason_cnt; reason++) {
 			int reg = ctrl->r->qm_rsn2cpuqid_ctrl + 4 * (reason / fields_per_reg);
 			int shift = (reason % fields_per_reg) * bits_per_field;
-			int ring = (reason % RTETH_RX_RINGS) + 5;
+			int ring = reason % RTETH_RX_RINGS;
 
 			sw_w32_mask(mask << shift, ring << shift, reg);
 		}
@@ -678,6 +694,9 @@ static void rtl93xx_hw_en_rxtx(struct rteth_ctrl *ctrl)
 
 static void rteth_setup_ring_buffer(struct rteth_ctrl *ctrl, struct ring_b *ring)
 {
+	dma_addr_t rx_buf_dma = ctrl->rx_buf_dma;
+	char *rx_buf = ctrl->rx_buf;
+
 	for (int i = 0; i < ctrl->rxrings; i++) {
 		struct p_hdr *h;
 		int j;
@@ -697,6 +716,24 @@ static void rteth_setup_ring_buffer(struct rteth_ctrl *ctrl, struct ring_b *ring
 		ring->c_rx[i] = 0;
 	}
 
+	for (int r = 0; r < RTETH_RX_RINGS; r++) {
+		for (int i = 0; i < RTETH_RX_RING_SIZE; i++) {
+			ctrl->rx_data[r].packet[i].size = RING_BUFFER;
+			ctrl->rx_data[r].packet[i].dma = rx_buf_dma;
+			ctrl->rx_data[r].packet[i].buf = rx_buf;
+			ctrl->rx_data[r].ring[i] = ctrl->rx_data_dma +
+						   sizeof(struct rteth_rx) * r +
+						   offsetof(struct rteth_rx, packet) +
+						   sizeof(struct rteth_packet) * i +
+						   RTETH_OWN_CPU;
+			rx_buf += RING_BUFFER;
+			rx_buf_dma += RING_BUFFER;
+		}
+
+		ctrl->rx_data[r].ring[RTETH_RX_RING_SIZE - 1] |= WRAP;
+		ctrl->rx_data[r].slot = 0;
+	}
+
 	for (int r = 0; r < RTETH_TX_RINGS; r++) {
 		for (int i = 0; i < RTETH_TX_RING_SIZE; i++) {
 			ctrl->tx_data[r].packet[i].skb = NULL;
@@ -1724,10 +1761,16 @@ static int rtl838x_eth_probe(struct platform_device *pdev)
 	ring = ctrl->membase;
 	ring->rx_space = ctrl->membase + sizeof(struct ring_b) + sizeof(struct notify_b);
 
+	ctrl->rx_buf = dma_alloc_noncoherent(&pdev->dev,
+					     RTETH_RX_RINGS * RTETH_RX_RING_SIZE * RING_BUFFER,
+					     &ctrl->rx_buf_dma, DMA_FROM_DEVICE, GFP_KERNEL);
+	ctrl->rx_data = dmam_alloc_coherent(&pdev->dev, sizeof(struct rteth_rx) * RTETH_RX_RINGS,
+					    &ctrl->rx_data_dma, GFP_KERNEL);
 	ctrl->tx_data = dmam_alloc_coherent(&pdev->dev, sizeof(struct rteth_tx) * RTETH_TX_RINGS,
 					    &ctrl->tx_dma, GFP_KERNEL);
 
 	spin_lock_init(&ctrl->lock);
+	spin_lock_init(&ctrl->rx_lock);
 	spin_lock_init(&ctrl->tx_lock);
 
 	dev->ethtool_ops = &rteth_ethtool_ops;




More information about the lede-commits mailing list