[openwrt/openwrt] realtek: eth: cleanup packet length calculation

LEDE Commits lede-commits at lists.infradead.org
Thu Feb 19 01:47:58 PST 2026


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/47d0773d7deb0f9d9670bdf0d9e13bd863cbdc4c

commit 47d0773d7deb0f9d9670bdf0d9e13bd863cbdc4c
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Thu Feb 12 14:53:11 2026 +0100

    realtek: eth: cleanup packet length calculation
    
    During transmit the driver must adapt the packet length. The
    hardware requires at least a memory space of ETH_ZLEN bytes
    data plus four bytes for layer 2 FCS. This was calculated
    (somehow) but skb->len never got updated and for the minimum
    length a RTL838x specific workaround was in place. Clean up
    the code and use skb_put_padto() so the length change gets
    reflected in skb->len.
    
    While we are here drop zeroing DSA tag because it will be
    overwritten by hardware for FCS.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/21999
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../files-6.12/drivers/net/ethernet/rtl838x_eth.c    | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 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 7a557afb64..65843f822d 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
@@ -8,6 +8,7 @@
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/minmax.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -977,16 +978,15 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 	    skb->data[len - 3] < ctrl->r->cpu_port &&
 	    skb->data[len - 2] == 0x10 &&
 	    skb->data[len - 1] == 0x00) {
-		/* DSA tag, reuse space for CRC */
 		dest_port = skb->data[len - 3];
-		skb->data[len - 4] = skb->data[len - 3] = 0;
-		skb->data[len - 2] = skb->data[len - 1] = 0;
+		/* space will be reused for 4 byte layer 2 FCS */
 	} else {
-		/* No DSA tag, add space for CRC */
-		len += 4;
+		/* No DSA tag, add space for 4 byte layer 2 FCS */
+		len += ETH_FCS_LEN;
 	}
 
-	if (unlikely(skb_padto(skb, len))) {
+	len = max(ETH_ZLEN + ETH_FCS_LEN, len);
+	if (unlikely(skb_put_padto(skb, len))) {
 		netdev->stats.tx_errors++;
 		dev_warn(dev, "skb pad failed\n");
 
@@ -1005,7 +1005,7 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		return NETDEV_TX_BUSY;
 	}
 
-	packet->dma = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
+	packet->dma = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(dev, packet->dma))) {
 		dev_kfree_skb_any(skb);
 		netdev->stats.tx_errors++;
@@ -1019,12 +1019,6 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		dev_kfree_skb_any(packet->skb);
 	}
 
-	if (ctrl->r->family_id == RTL8380_FAMILY_ID) {
-		/* On RTL8380 SoCs, small packet lengths being sent need adjustments */
-		if (len < ETH_ZLEN - 4)
-			len -= 4;
-	}
-
 	if (dest_port >= 0)
 		ctrl->r->create_tx_header(packet, dest_port, 0); // TODO ok to set prio to 0?
 




More information about the lede-commits mailing list