summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-07-22 15:31:51 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:31:43 +0300
commit7cec342ce65a02484b130e49e1903623ff6ac83a (patch)
tree3488af756734016eca5643719f024545fef9fe99
parent6f83bbb0e2136423511b8ffd22e765ddf4937ce9 (diff)
downloadlinux-7cec342ce65a02484b130e49e1903623ff6ac83a.tar.gz
linux-7cec342ce65a02484b130e49e1903623ff6ac83a.zip
net: stmmac: dwmac1000: Fix long-broken Rx Jumbo-frames support
As soon as the Jumbo frames with MTU over 2K/4K (for the Normal descriptors) and over 8K (for the chained Enhanced descriptors) enabled the frames exceeding these limits won't be delivered to the networking core and will be just discarded. This happens due to the driver not supporting the cross-descriptors data reception (see the stmmac_desc_ops::rx_status() callbacks handling the non-last segment descriptors). DW GMAC layer of the STMMAC driver currently supports the two types of the Rx DMA-descriptors which besides the different layout differ by the maximum buffers size: Normal Rx descriptor: 2K (chain), 2x2K (ring) Enhanced Rx descriptor: 8K (chain), 2x8K (ring) Since the cross-descriptor data reception is basically disabled the ringed Enhanced Rx-descriptors will only work for the 9K jumbo frames retrieval. The rest of the modes will cause the over the buffer-size frames dropping. This is definitely wrong seeing the driver unconditionally setups max 9K MTU constraint for any DW GMAC devices. Moreover the older non-GMAC IP-cores are supposed to work with the SKB_MAX_HEAD() MTUs which implies up to Page-sized frames reception. In that case depending on the system-wide page size the Jumbo frames reception won't properly work either. Let's fix the problem described above. In fact the driver code has already been prepared for that by the preceding fixes and the only what left to be done is to just return the "rx_not_ls" status from the DW GMAC-specific stmmac_desc_ops::rx_status() callback. The STMMAC core driver will handle the rest as is. Fixes: 286a83721720 ("stmmac: add CHAINED descriptor mode support (V4)") Fixes: 47dd7a540b8a ("net: add support for STMicroelectronics Ethernet controllers.") Signed-off-by: Serge Semin <fancer.lancer@gmail.com> --- Note the patch used to fix the stmmac_rx_buf1_len(). It must take into account that it's possible to have two buffers initialized in the Rx DMA-descriptors. So the very first buffer of the last segment could be not containing the tail of the Rx frame. It's specific for the DW GMAC4/XGMAC IP-cores supporting the split-headers and failing to split the retrieved frame for some reason.
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/enh_desc.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/norm_desc.c6
2 files changed, 4 insertions, 8 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index c11a06af7dbf..24ac1d2ff164 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -166,10 +166,8 @@ static int enh_desc_get_rx_basic_status(unsigned int rdes0,
if (unlikely(rdes0 & RDES0_OWN))
return dma_own;
- if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
- x->rx_length++;
- return discard_frame;
- }
+ if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR)))
+ return rx_not_ls;
if (unlikely(!(rdes0 & RDES0_FRAME_TYPE)))
ret = llc_snap;
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index e90184f3f136..389e07f35c6a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -67,10 +67,8 @@ static int ndesc_get_rx_basic_status(unsigned int rdes0,
if (unlikely(rdes0 & RDES0_OWN))
return dma_own;
- if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
- x->rx_length++;
- return discard_frame;
- }
+ if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR)))
+ return rx_not_ls;
if (unlikely(!(rdes0 & RDES0_FRAME_TYPE)))
ret = llc_snap;