realtek: eth: add new transmit structures
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Wed, 28 Jan 2026 17:51:31 +0000 (18:51 +0100)
committerRobert Marko <robimarko@gmail.com>
Sun, 1 Feb 2026 10:27:58 +0000 (11:27 +0100)
The ethernet driver will get a new transmit function. As a first
step add the required structures and initialize them.

To get an idea: In the future the transmit buffer will hold only
the needed packet header information. The real data is kept in the
SKBs. So only pointers will be changed and memory moving can be
avoided. The SoC will transfer packet data directly from the SKBs.

Additionally a new transmit lock will be established that is
separated from the current driver lock. This is only needed
to guard the "kick-the-engine" command. So contention of the old
global lock can be reduced.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/21778
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h

index 39bf092a8ebb30b4334182d87e9c49d6965c8572..3f5621179a5ea66d0f996d37ce91e399224a4bcd 100644 (file)
@@ -32,6 +32,11 @@ int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type
  * for an RX ring, MAX_ENTRIES the maximum number of entries
  * available in total for all queues.
  */
+
+#define RTETH_OWN_CPU          1
+#define RTETH_TX_RING_SIZE     16
+#define RTETH_TX_RINGS         2
+
 #define MAX_RXRINGS    32
 #define MAX_RXLEN      300
 #define MAX_ENTRIES    (300 * 8)
@@ -50,6 +55,24 @@ int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type
 #define WRAP           0x2
 #define RING_BUFFER    1600
 
+struct rteth_packet {
+       /* hardware header part as required by SoC */
+       dma_addr_t              dma;
+       u16                     reserved;
+       u16                     size;
+       u16                     offset;
+       u16                     len;
+       u16                     cpu_tag[10];
+       /* software mangement and data part */
+       struct sk_buff          *skb;
+} __packed __aligned(1);
+
+struct rteth_tx {
+       int                     slot;
+       dma_addr_t              ring[RTETH_TX_RING_SIZE];
+       struct rteth_packet     packet[RTETH_TX_RING_SIZE];
+};
+
 struct p_hdr {
        u8      *buf;
        u16     reserved;
@@ -197,6 +220,10 @@ struct rteth_ctrl {
        u32 lastEvent;
        u16 rxrings;
        u16 rxringlen;
+       /* transmit handling */
+       dma_addr_t              tx_dma;
+       spinlock_t              tx_lock;
+       struct rteth_tx         *tx_data;
 };
 
 /* On the RTL93XX, the RTL93XX_DMA_IF_RX_RING_CNTR track the fill level of
@@ -662,6 +689,19 @@ static void rteth_setup_ring_buffer(struct rteth_ctrl *ctrl, struct ring_b *ring
                ring->tx_r[i][j - 1] |= WRAP;
                ring->c_tx[i] = 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;
+                       ctrl->tx_data[r].ring[i] = ctrl->tx_dma +
+                                                  sizeof(struct rteth_tx) * r +
+                                                  offsetof(struct rteth_tx, packet) +
+                                                  sizeof(struct rteth_packet) * i;
+               }
+
+               ctrl->tx_data[r].ring[RTETH_TX_RING_SIZE - 1] |= WRAP;
+               ctrl->tx_data[r].slot = 0;
+       }
 }
 
 static void rtl839x_setup_notify_ring_buffer(struct rteth_ctrl *ctrl)
@@ -1702,7 +1742,11 @@ 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->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->tx_lock);
 
        dev->ethtool_ops = &rteth_ethtool_ops;
        dev->min_mtu = ETH_ZLEN;
index d289f4c04640e6082fbf1de34095481f828c22e1..bb64b88d15b7d3a00bc7257ec6f37722e9f7c040 100644 (file)
@@ -403,6 +403,7 @@ inline u32 rtl931x_get_mac_tx_pause_sts(int p)
 struct p_hdr;
 struct dsa_tag;
 struct rteth_ctrl;
+struct rteth_packet;
 
 struct rteth_config {
        int family_id;