Linux Documentation
 help / color / mirror / Atom feed
From: Subash Abhinov Kasiviswanathan <subash.a.kasiviswanathan@oss.qualcomm.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, andrew+netdev@lunn.ch, corbet@lwn.net
Cc: horms@kernel.org, skhan@linuxfoundation.org,
	rdunlap@infradead.org, netdev@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Subash Abhinov Kasiviswanathan
	<subash.a.kasiviswanathan@oss.qualcomm.com>,
	Sean Tranchetti <sean.tranchetti@oss.qualcomm.com>
Subject: [PATCH net-next 5/7] net: qualcomm: rmnet: Work around coalescing hardware quirks
Date: Tue, 29 Sep 2026 22:13:43 -0700	[thread overview]
Message-ID: <20260930051345.857443-6-subash.a.kasiviswanathan@oss.qualcomm.com> (raw)
In-Reply-To: <20260930051345.857443-1-subash.a.kasiviswanathan@oss.qualcomm.com>

On certain hardware, the checksum valid indication from the bitmap
inside a MAPv5 coalescing frame cannot be trusted when the frame contains
exactly one packet and hardware completes the coalescing due to a
TCP FIN or PSH flag, a packet count limit, a byte count limit or a time
limit.  The hardware sets CSUM_VALID incorrectly in these cases, causing
the driver to mark packets CHECKSUM_UNNECESSARY when the checksum may in
fact be wrong.

Instead, set ip_summed to CHECKSUM_NONE so that the network stack verifies
the checksum rather than trusting the hardware indication.

The single NLO, single packet determination this fix depends on cannot
be based on the num_nlos field declared in the coalescing header, since
on certain simulation hardware configurations that field can be reported
incorrectly even though the per-NLO num_packets fields are accurate.
Recompute the true NLO count from the actual nl_pairs[] content before
applying the fixup so the determination is reliable regardless of
whether num_nlos itself can be trusted.

Co-developed-by: Sean Tranchetti <sean.tranchetti@oss.qualcomm.com>
Signed-off-by: Sean Tranchetti <sean.tranchetti@oss.qualcomm.com>
Signed-off-by: Subash Abhinov Kasiviswanathan <subash.a.kasiviswanathan@oss.qualcomm.com>
---
 .../ethernet/qualcomm/rmnet/rmnet_map_data.c  | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
index bb88e19e28d8..1f9e592e24b6 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
@@ -593,6 +593,61 @@ static void rmnet_map_partial_csum(struct sk_buff *skb,
 	skb->csum_start = skb->data + coal_meta->ip_len - skb->head;
 }
 
+/* On some hardware, num_nlos in the coalescing header can be reported
+ * incorrectly under certain conditions even though the per-NLO num_packets
+ * fields it is meant to summarize are correct. Recompute the true NLO count
+ * directly from the nl_pairs[] content rather than trusting the declared
+ * value, so that rmnet_map_v5_csum_fixup()'s single NLO, single packet check
+ * is reliable.
+ */
+static void rmnet_map_v5_fixup_num_nlos(struct rmnet_map_v5_coal_header *coal_hdr)
+{
+	u8 nlos = 0;
+	int i;
+
+	for (i = 0; i < RMNET_MAP_V5_MAX_NLOS; i++) {
+		if (coal_hdr->nl_pairs[i].num_packets)
+			nlos++;
+	}
+
+	coal_hdr->coal_info = u8_encode_bits(nlos, MAPV5_COALINFO_NUM_NLOS_FMASK) |
+			      (coal_hdr->coal_info & MAPV5_COALINFO_CSUM_VALID_FLAG);
+}
+
+/* The checksum valid indication for a single NLO, single packet coalescing
+ * frame cannot be trusted when the close reason is a TCP FIN/PSH, a packet
+ * count limit, a byte count limit or a time limit.
+ */
+static bool rmnet_map_v5_csum_fixup(struct rmnet_map_v5_coal_header *coal_hdr)
+{
+	u8 close_value = u8_get_bits(coal_hdr->close_info,
+				     MAPV5_CLOSEINFO_CLOSE_VALUE_FMASK);
+	u8 close_type = u8_get_bits(coal_hdr->close_info,
+				    MAPV5_CLOSEINFO_CLOSE_TYPE_FMASK);
+	u8 num_nlos = u8_get_bits(coal_hdr->coal_info,
+				  MAPV5_COALINFO_NUM_NLOS_FMASK);
+
+	/* Only applies to single NLO, single packet frames */
+	if (num_nlos != 1 || coal_hdr->nl_pairs[0].num_packets != 1)
+		return false;
+
+	/* TCP FIN or PSH triggered the close */
+	if (close_type == RMNET_MAP_COAL_CLOSE_COAL)
+		return true;
+
+	/* Hit a hardware limit */
+	if (close_type == RMNET_MAP_COAL_CLOSE_HW) {
+		switch (close_value) {
+		case RMNET_MAP_COAL_CLOSE_HW_PKT:
+		case RMNET_MAP_COAL_CLOSE_HW_BYTE:
+		case RMNET_MAP_COAL_CLOSE_HW_TIME:
+			return true;
+		}
+	}
+
+	return false;
+}
+
 /* Carve one logical segment from a coalesced SKB and append it to the list.
  * Adjusts TCP sequence numbers, IP IDs/lengths, and checksum state.
  */
@@ -913,6 +968,7 @@ static int rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
 	skb_pull(coal_skb, sizeof(struct rmnet_map_header));
 	skb_trim(coal_skb, len);
 	coal_hdr = (struct rmnet_map_v5_coal_header *)coal_skb->data;
+	rmnet_map_v5_fixup_num_nlos(coal_hdr);
 	num_nlos = u8_get_bits(coal_hdr->coal_info, MAPV5_COALINFO_NUM_NLOS_FMASK);
 	skb_pull(coal_skb, sizeof(*coal_hdr));
 
@@ -927,6 +983,12 @@ static int rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
 	if (!rmnet_map_coal_validate_bounds(coal_skb, coal_hdr, num_nlos, hlen))
 		return -EINVAL;
 
+	if (rmnet_map_v5_csum_fixup(coal_hdr) && !coal_meta.zero_csum) {
+		coal_skb->ip_summed = CHECKSUM_NONE;
+		__skb_queue_tail(list, coal_skb);
+		return 0;
+	}
+
 	if (rmnet_map_coal_gro_fast_path(coal_skb, coal_hdr, &coal_meta, list,
 					 num_nlos, gro))
 		return 0;
-- 
2.34.1


  parent reply	other threads:[~2026-09-30  5:14 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30  5:13 [PATCH net-next 0/7] Add HW GRO handling in rmnet Subash Abhinov Kasiviswanathan
2026-09-30  5:13 ` [PATCH net-next 1/7] uapi: if_link: Add RMNET_FLAGS_INGRESS_COALESCE Subash Abhinov Kasiviswanathan
2026-10-04  6:05   ` netdev-bot+sashiko
2026-09-30  5:13 ` [PATCH net-next 2/7] net: qualcomm: rmnet: Process MAPv5 frames as a list Subash Abhinov Kasiviswanathan
2026-09-30  5:13 ` [PATCH net-next 3/7] net: qualcomm: rmnet: Restrict supported MAP checksum configurations Subash Abhinov Kasiviswanathan
2026-10-04  6:05   ` netdev-bot+sashiko
2026-09-30  5:13 ` [PATCH net-next 4/7] net: qualcomm: rmnet: Add DL packet coalescing support Subash Abhinov Kasiviswanathan
2026-10-04  6:05   ` netdev-bot+sashiko
2026-09-30  5:13 ` Subash Abhinov Kasiviswanathan [this message]
2026-10-04  6:05   ` [PATCH net-next 5/7] net: qualcomm: rmnet: Work around coalescing hardware quirks netdev-bot+sashiko
2026-09-30  5:13 ` [PATCH net-next 6/7] net: qualcomm: rmnet: Add ethtool stats for DL coalescing Subash Abhinov Kasiviswanathan
2026-10-04  6:05   ` netdev-bot+sashiko
2026-09-30  5:13 ` [PATCH net-next 7/7] docs: networking: Add documentation for the coalescing support in rmnet Subash Abhinov Kasiviswanathan
2026-10-04  6:05   ` netdev-bot+sashiko

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=20260930051345.857443-6-subash.a.kasiviswanathan@oss.qualcomm.com \
    --to=subash.a.kasiviswanathan@oss.qualcomm.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=rdunlap@infradead.org \
    --cc=sean.tranchetti@oss.qualcomm.com \
    --cc=skhan@linuxfoundation.org \
    /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