The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Nicolai Buchwitz <nb@tipi-net.de>
To: "Théo Lebrun" <theo.lebrun@bootlin.com>
Cc: Conor Dooley <conor.dooley@microchip.com>,
	Claudiu Beznea <claudiu.beznea@tuxon.dev>,
	Jonathan Bell <jonathan@raspberrypi.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Richard Cochran <richardcochran@gmail.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Nicolai Buchwitz <nb@tipi-net.de>
Subject: [PATCH net 2/2] net: macb: fix zero UDPv4 checksum on transmit
Date: Mon, 24 Aug 2026 15:47:03 +0200	[thread overview]
Message-ID: <20260824134703.766708-3-nb@tipi-net.de> (raw)
In-Reply-To: <20260824134703.766708-1-nb@tipi-net.de>

The GEM checksum engine writes its raw result into the UDP checksum
field, so a UDPv4 checksum that computes to zero goes out as 0x0000.
RFC 768 requires:

  If the computed checksum is zero, it is transmitted as all ones
  (the equivalent in one's complement arithmetic). An all zero
  transmitted checksum value means that the transmitter generated
  no checksum (for debugging or for higher level protocols that
  don't care).

Raspberry Pi confirmed in a simulation of the Cadence IP [1] that
the engine skips the final substitution exactly for UDP over IPv4.
UDPv6 and TCP come out correct. The IP changelog shows no related
change, so probably all GEM revisions have the same bug.

Clear the checksum offload features for UDPv4 frames in
macb_features_check(), the core then completes the checksum in
software. With ip_summed cleared, macb_pad_and_fcs() appends the
FCS and TX_NOCRC keeps the hardware off the frame. TCP and UDPv6
keep the offload.

One-step PTP sync packets stay on the hardware path, the MAC
rewrites their timestamp during transmit and would invalidate a
software checksum.

Link: https://github.com/raspberrypi/linux/issues/7550#issuecomment-5343018065 [1]
Fixes: 85ff3d87bf2e ("net/macb: add TX checksum offload feature")
Cc: Jonathan Bell <jonathan@raspberrypi.com>
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
---
 drivers/net/ethernet/cadence/macb_main.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 623d072a271d..f3548475f945 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -14,6 +14,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/if_vlan.h>
 #include <linux/inetdevice.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -2373,6 +2374,16 @@ static netdev_features_t macb_features_check(struct sk_buff *skb,
 	unsigned int nr_frags, f;
 	unsigned int hdrlen;
 
+	/* The GEM skips the RFC 768 substitution of 0xffff for a zero
+	 * UDPv4 checksum, do those in software. One-step PTP sync frames
+	 * stay on hardware, the MAC rewrites their timestamp in flight.
+	 */
+	if (skb->ip_summed == CHECKSUM_PARTIAL &&
+	    vlan_get_protocol(skb) == htons(ETH_P_IP) &&
+	    skb->csum_offset == offsetof(struct udphdr, check) &&
+	    !ptp_one_step_sync(skb))
+		features &= ~NETIF_F_CSUM_MASK;
+
 	/* Validate LSO compatibility */
 
 	/* there is only one buffer or protocol is not UDP */
-- 
2.53.0


      parent reply	other threads:[~2026-08-24 13:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-24 13:47 [PATCH net 0/2] net: macb: fix zero UDPv4 checksum on transmit Nicolai Buchwitz
2026-08-24 13:47 ` [PATCH net 1/2] net: macb: exclude software FCS from TX byte statistics Nicolai Buchwitz
2026-08-25 15:04   ` Nicolai Buchwitz
2026-08-24 13:47 ` Nicolai Buchwitz [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260824134703.766708-3-nb@tipi-net.de \
    --to=nb@tipi-net.de \
    --cc=andrew+netdev@lunn.ch \
    --cc=claudiu.beznea@tuxon.dev \
    --cc=conor.dooley@microchip.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=jonathan@raspberrypi.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=theo.lebrun@bootlin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox