diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2025-06-03 13:06:46 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:31:12 +0300 |
| commit | df01b42941eda1c8a2d1685f6e986df5490af762 (patch) | |
| tree | a38adc3c9c66ff9a947cf8f93f73c18fb01986e1 | |
| parent | 4b09925e77834b182aef2937871e0bf35df01a34 (diff) | |
| download | linux-df01b42941eda1c8a2d1685f6e986df5490af762.tar.gz linux-df01b42941eda1c8a2d1685f6e986df5490af762.zip | |
net: stmmac: dwmac4: Add csum Rx-descriptor status check
Currently the stmmac_desc_ops::rx_status() method always returns "Good
frame" status for the IP-packets with erroneous checksum. Here is what DW
QoS Eth databook says about the Rx COE flags in the Rx DMA-descriptor:
"RDES0.IPCE IP Payload Error ...
Bit 15 (ES) of RDES3 is not set when this bit is set." [1]
Thus the "Discard frame" status won't be returned from the
stmmac_desc_ops::rx_status() method for the frames failed to pass the
control-sum check. Instead such packets will be passed to the upper
software layers with the "checksum unnecessary" status, which makes the
upper layer being unaware of the packets inconsistency. This is definitely
a bug.
Moreover the "Good frame" is returned for the unverified frames too
(unsupported by the Rx Checksum Offload engine). This isn't that much
problematic as the bug but generally speaking this is also incorrect
because it doesn't give an opportunity for the upper software layer to
detect the IP csum status for sure. Instead the STMMAC core driver has to
implement an heuristic method like stmmac_has_ip_ethertype() which is not
only incomplete but also causes a false-positive CSUM verification status
passed up to the networking core.
Let's fix all of the problems above in the DW QoS Eth (GMAC4+) as a
preparation before a complete fix of the commit c2945c435c99 ("net:
stmmac: Prevent DSA tags from breaking COE") is provided.
Fixes: 753a71090f33 ("stmmac: add descriptors function for GMAC 4.xx")
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index 3ff30bc9f8c2..2c741bdae6fa 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -106,18 +106,22 @@ static int dwmac4_wrback_get_rx_status(struct stmmac_extra_stats *x, if (rdes1 & RDES1_IP_HDR_ERROR) { x->ip_hdr_err++; - ret |= csum_none; + ret = discard_frame; + } + if (rdes1 & RDES1_IP_PAYLOAD_ERROR) { + x->ip_payload_err++; + ret = discard_frame; } - if (rdes1 & RDES1_IP_CSUM_BYPASSED) + if (rdes1 & RDES1_IP_CSUM_BYPASSED) { x->ip_csum_bypassed++; + ret |= csum_none; + } if (rdes1 & RDES1_IPV4_HEADER) x->ipv4_pkt_rcvd++; - if (rdes1 & RDES1_IPV6_HEADER) + else if (rdes1 & RDES1_IPV6_HEADER) x->ipv6_pkt_rcvd++; - if (rdes1 & RDES1_IP_PAYLOAD_ERROR) { - x->ip_payload_err++; + else /* Not an IP packet or COE is disabled */ ret |= csum_none; - } if (message_type == RDES_EXT_NO_PTP) x->no_ptp_rx_msg_type_ext++; |
