mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-02-21 04:42:25 +01:00
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@gmx.de> Link: https://github.com/openwrt/openwrt/pull/21999 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
parent
a36ab12454
commit
47d0773d7d
1 changed files with 7 additions and 13 deletions
|
|
@ -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?
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue