From: Markus Stockhausen Date: Wed, 28 Jan 2026 17:51:31 +0000 (+0100) Subject: realtek: eth: add new transmit structures X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=2d84c5222cbc68bf3a0cf470afb5839115738a09;p=openwrt%2Fstaging%2Fstintel.git realtek: eth: add new transmit structures 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 Link: https://github.com/openwrt/openwrt/pull/21778 Signed-off-by: Robert Marko --- 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 39bf092a8e..3f5621179a 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 @@ -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; diff --git a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h index d289f4c046..bb64b88d15 100644 --- a/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h +++ b/target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h @@ -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;