From: Markus Stockhausen Date: Thu, 12 Feb 2026 13:53:11 +0000 (+0100) Subject: realtek: eth: cleanup packet length calculation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47d0773d7deb0f9d9670bdf0d9e13bd863cbdc4c;p=thirdparty%2Fopenwrt.git 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 Link: https://github.com/openwrt/openwrt/pull/21999 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 7a557afb64d..65843f822d8 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 #include #include +#include #include #include #include @@ -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?