Commit 5c69e0b3 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'stmmac-stop-silently-dropping-bad-checksum-packets'

Oleksij Rempel says:

====================
stmmac: stop silently dropping bad checksum packets

this series reworks how stmmac handles receive checksum offload
(CoE) errors on dwmac4.

At present, when CoE is enabled, the hardware silently discards any
frame that fails checksum validation. These packets never reach the
driver and are not accounted in the generic drop statistics. They are
only visible in the stmmac-specific counters as "payload error" or
"header error" packets, which makes it harder to debug or monitor
network issues.

Following discussion [1], the driver is reworked to propagate checksum
error information up to the stack. With these changes, CoE stays
enabled, but frames that fail hardware validation are no longer dropped
in hardware. Instead, the driver marks them with CHECKSUM_NONE so the
network stack can validate, drop, and properly account them in the
standard drop statistics.

[1] https://lore.kernel.org/all/20250625132117.1b3264e8@kernel.org/
====================

Link: https://patch.msgid.link/20250818090217.2789521-1-o.rempel@pengutronix.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 8beead2d fe404279
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -341,6 +341,7 @@ static inline u32 mtl_chanx_base_addr(const struct dwmac4_addrs *addrs,
#define MTL_OP_MODE_RFA_SHIFT		8

#define MTL_OP_MODE_EHFC		BIT(7)
#define MTL_OP_MODE_DIS_TCP_EF		BIT(6)

#define MTL_OP_MODE_RTC_MASK		GENMASK(1, 0)
#define MTL_OP_MODE_RTC_SHIFT		0
+6 −2
Original line number Diff line number Diff line
@@ -110,16 +110,20 @@ static int dwmac4_wrback_get_rx_status(struct stmmac_extra_stats *x,

	message_type = (rdes1 & ERDES4_MSG_TYPE_MASK) >> 8;

	if (rdes1 & RDES1_IP_HDR_ERROR)
	if (rdes1 & RDES1_IP_HDR_ERROR) {
		x->ip_hdr_err++;
		ret |= csum_none;
	}
	if (rdes1 & RDES1_IP_CSUM_BYPASSED)
		x->ip_csum_bypassed++;
	if (rdes1 & RDES1_IPV4_HEADER)
		x->ipv4_pkt_rcvd++;
	if (rdes1 & RDES1_IPV6_HEADER)
		x->ipv6_pkt_rcvd++;
	if (rdes1 & RDES1_IP_PAYLOAD_ERROR)
	if (rdes1 & RDES1_IP_PAYLOAD_ERROR) {
		x->ip_payload_err++;
		ret |= csum_none;
	}

	if (message_type == RDES_EXT_NO_PTP)
		x->no_ptp_rx_msg_type_ext++;
+2 −0
Original line number Diff line number Diff line
@@ -268,6 +268,8 @@ static void dwmac4_dma_rx_chan_op_mode(struct stmmac_priv *priv,

	mtl_rx_op = readl(ioaddr + MTL_CHAN_RX_OP_MODE(dwmac4_addrs, channel));

	mtl_rx_op |= MTL_OP_MODE_DIS_TCP_EF;

	if (mode == SF_DMA_MODE) {
		pr_debug("GMAC: enable RX store and forward mode\n");
		mtl_rx_op |= MTL_OP_MODE_RSF;
+2 −1
Original line number Diff line number Diff line
@@ -5737,7 +5737,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)

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

		if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
		if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb) ||
		    (status & csum_none))
			skb_checksum_none_assert(skb);
		else
			skb->ip_summed = CHECKSUM_UNNECESSARY;