Skip to content

Commit c2945c4

Browse files
rgantoisdavem330
authored andcommitted
net: stmmac: Prevent DSA tags from breaking COE
Some DSA tagging protocols change the EtherType field in the MAC header e.g. DSA_TAG_PROTO_(DSA/EDSA/BRCM/MTK/RTL4C_A/SJA1105). On TX these tagged frames are ignored by the checksum offload engine and IP header checker of some stmmac cores. On RX, the stmmac driver wrongly assumes that checksums have been computed for these tagged packets, and sets CHECKSUM_UNNECESSARY. Add an additional check in the stmmac TX and RX hotpaths so that COE is deactivated for packets with ethertypes that will not trigger the COE and IP header checks. Fixes: 6b2c6e4 ("net: stmmac: propagate feature flags to vlan") Cc: <[email protected]> Reported-by: Richard Tresidder <[email protected]> Link: https://lore.kernel.org/netdev/[email protected]/ Reported-by: Romain Gantois <[email protected]> Link: https://lore.kernel.org/netdev/[email protected]/ Reviewed-by: Vladimir Oltean <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Signed-off-by: Romain Gantois <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e9ce7ed commit c2945c4

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4435,6 +4435,28 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
44354435
return NETDEV_TX_OK;
44364436
}
44374437

4438+
/**
4439+
* stmmac_has_ip_ethertype() - Check if packet has IP ethertype
4440+
* @skb: socket buffer to check
4441+
*
4442+
* Check if a packet has an ethertype that will trigger the IP header checks
4443+
* and IP/TCP checksum engine of the stmmac core.
4444+
*
4445+
* Return: true if the ethertype can trigger the checksum engine, false
4446+
* otherwise
4447+
*/
4448+
static bool stmmac_has_ip_ethertype(struct sk_buff *skb)
4449+
{
4450+
int depth = 0;
4451+
__be16 proto;
4452+
4453+
proto = __vlan_get_protocol(skb, eth_header_parse_protocol(skb),
4454+
&depth);
4455+
4456+
return (depth <= ETH_HLEN) &&
4457+
(proto == htons(ETH_P_IP) || proto == htons(ETH_P_IPV6));
4458+
}
4459+
44384460
/**
44394461
* stmmac_xmit - Tx entry point of the driver
44404462
* @skb : the socket buffer
@@ -4499,9 +4521,13 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
44994521
/* DWMAC IPs can be synthesized to support tx coe only for a few tx
45004522
* queues. In that case, checksum offloading for those queues that don't
45014523
* support tx coe needs to fallback to software checksum calculation.
4524+
*
4525+
* Packets that won't trigger the COE e.g. most DSA-tagged packets will
4526+
* also have to be checksummed in software.
45024527
*/
45034528
if (csum_insertion &&
4504-
priv->plat->tx_queues_cfg[queue].coe_unsupported) {
4529+
(priv->plat->tx_queues_cfg[queue].coe_unsupported ||
4530+
!stmmac_has_ip_ethertype(skb))) {
45054531
if (unlikely(skb_checksum_help(skb)))
45064532
goto dma_map_err;
45074533
csum_insertion = !csum_insertion;
@@ -5066,7 +5092,7 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
50665092
stmmac_rx_vlan(priv->dev, skb);
50675093
skb->protocol = eth_type_trans(skb, priv->dev);
50685094

5069-
if (unlikely(!coe))
5095+
if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
50705096
skb_checksum_none_assert(skb);
50715097
else
50725098
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -5589,7 +5615,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
55895615

55905616
skb->protocol = eth_type_trans(skb, priv->dev);
55915617

5592-
if (unlikely(!coe))
5618+
if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
55935619
skb_checksum_none_assert(skb);
55945620
else
55955621
skb->ip_summed = CHECKSUM_UNNECESSARY;

0 commit comments

Comments
 (0)