realtek: Fix buffer length calculation on RTL8380 with CRC offload

Fixes the buffer and packet length calculations for Ethernet TX on
the RTL8380 SoC when CRC calculation offload is enabled.
CRC-offload is always done by the SoC, but additional CRC
calculation was previously done also by the kernel.
It also fixes detection of the DSA tag for packets on RTL8390
SoCs for ports > 28.

v2 has correct whitespace

Signed-off-by: Birger Koblitz <mail@birger-koblitz.de>
This commit is contained in:
Birger Koblitz 2021-06-06 16:20:59 +02:00 committed by Hauke Mehrtens
parent bf98faaac8
commit 76428494c3

View File

@ -1129,23 +1129,16 @@ static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev)
/* Check for DSA tagging at the end of the buffer */ /* Check for DSA tagging at the end of the buffer */
if (netdev_uses_dsa(dev) && skb->data[len-4] == 0x80 && skb->data[len-3] > 0 if (netdev_uses_dsa(dev) && skb->data[len-4] == 0x80 && skb->data[len-3] > 0
&& skb->data[len-3] < 28 && skb->data[len-2] == 0x10 && skb->data[len-3] < priv->cpu_port && skb->data[len-2] == 0x10
&& skb->data[len-1] == 0x00) { && skb->data[len-1] == 0x00) {
/* Reuse tag space for CRC if possible */ /* Reuse tag space for CRC if possible */
dest_port = skb->data[len-3]; dest_port = skb->data[len-3];
skb->data[len-4] = skb->data[len-3] = skb->data[len-2] = skb->data[len-1] = 0x00;
len -= 4; len -= 4;
} }
len += 4; // Add space for CRC len += 4; // Add space for CRC
// On RTL8380 SoCs, the packet needs extra padding
if (priv->family_id == RTL8380_FAMILY_ID) {
if (len < ETH_ZLEN)
len = ETH_ZLEN; // SoC not automatically padding to ETH_ZLEN
else
len += 4;
}
if (skb_padto(skb, len)) { if (skb_padto(skb, len)) {
ret = NETDEV_TX_OK; ret = NETDEV_TX_OK;
goto txdone; goto txdone;
@ -1158,6 +1151,11 @@ static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev)
h = &ring->tx_header[q][ring->c_tx[q]]; h = &ring->tx_header[q][ring->c_tx[q]];
h->size = len; h->size = len;
h->len = len; h->len = len;
// On RTL8380 SoCs, small packet lengths being sent need adjustments
if (priv->family_id == RTL8380_FAMILY_ID) {
if (len < ETH_ZLEN - 4)
h->len -= 4;
}
priv->r->create_tx_header(h, dest_port, skb->priority >> 1); priv->r->create_tx_header(h, dest_port, skb->priority >> 1);