* [PATCH net-next 1/2] net: stmmac: dwmac-sun8i: Fix the RX_TH threshold encoding
2026-11-10 6:03 [PATCH net-next 0/2] net: stmmac: dwmac-sun8i: Jumbo frames and an RX_TH fix Arun Iyengar via B4 Relay
@ 2026-11-10 6:03 ` Arun Iyengar via B4 Relay
2026-11-10 6:03 ` [PATCH net-next 2/2] net: stmmac: dwmac-sun8i: Enable jumbo frames up to MTU 2018 Arun Iyengar via B4 Relay
1 sibling, 0 replies; 3+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10 6:03 UTC (permalink / raw)
To: Maxime Chevallier, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Maxime Coquelin, Alexandre Torgue
Cc: netdev, linux-arm-kernel, linux-sunxi, linux-stm32, linux-kernel
From: Arun Iyengar <aiyengar1990@gmail.com>
The EMAC RX_CTL1 RX_TH field (bits 5:4) encodes 00 = 64 bytes and
01 = 32 bytes (H616 user manual v1.0, 6.5.10; 10 = 96 and 11 = 128 bytes
as in the driver). The driver has the first two swapped.
The values are only used in RX threshold mode, which dwmac-sun8i never
selects while RX checksum offload is on, so no current configuration is
affected.
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 47954537b29e..0c82662fbe6e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -198,8 +198,9 @@ static const struct emac_variant emac_variant_h616_emac1 = {
/* Used in RX_CTL1*/
#define EMAC_RX_MD BIT(1)
#define EMAC_RX_TH_MASK GENMASK(5, 4)
-#define EMAC_RX_TH_32 0
-#define EMAC_RX_TH_64 (0x1 << 4)
+/* RX_CTL1 RX_TH encoding (H616 UM 6.5.10): 00 = 64, 01 = 32 bytes */
+#define EMAC_RX_TH_32 (0x1 << 4)
+#define EMAC_RX_TH_64 0
#define EMAC_RX_TH_96 (0x2 << 4)
#define EMAC_RX_TH_128 (0x3 << 4)
#define EMAC_RX_DMA_EN BIT(30)
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH net-next 2/2] net: stmmac: dwmac-sun8i: Enable jumbo frames up to MTU 2018
2026-11-10 6:03 [PATCH net-next 0/2] net: stmmac: dwmac-sun8i: Jumbo frames and an RX_TH fix Arun Iyengar via B4 Relay
2026-11-10 6:03 ` [PATCH net-next 1/2] net: stmmac: dwmac-sun8i: Fix the RX_TH threshold encoding Arun Iyengar via B4 Relay
@ 2026-11-10 6:03 ` Arun Iyengar via B4 Relay
1 sibling, 0 replies; 3+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10 6:03 UTC (permalink / raw)
To: Maxime Chevallier, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Maxime Coquelin, Alexandre Torgue
Cc: netdev, linux-arm-kernel, linux-sunxi, linux-stm32, linux-kernel
From: Arun Iyengar <aiyengar1990@gmail.com>
The sun8i EMAC advertises a maximum MTU of 3712, but no frame larger
than the standard 1518 bytes is actually received: on an H616 board
(Orange Pi Zero2, RTL8211F over RGMII) every ping above 1472 bytes with
DF set is lost, and the rx_length counter goes up for each one.
There are two independent limits:
1. EMAC_RX_CTL0 bit 29 (JUMBO_FRM_EN) is never set, so the receiver
rejects frames longer than 1518 (1522 with a VLAN tag) bytes. The
Allwinner BSP driver (sunxi-gmac) sets this bit unconditionally at
init. Set it in core_init as well; core_init runs after every DMA
soft reset, including the one done by an MTU change.
2. The EMAC has no Synopsys HW feature register, so stmmac uses normal
descriptors in chain mode and, without enh_desc, sets max_mtu to
SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN), which is 3712 with 4K
pages. That value is not a hardware limit. The descriptor buffer
size field is 11 bits wide (the same in the BSP and the QEMU model),
so ndesc_init_rx_desc() caps each RX buffer at 2047 bytes, and
ndesc_get_rx_status() discards any frame that needs a second
descriptor. On TX, stmmac_xmit() only splits jumbo frames for
enh_desc, and norm_set_tx_desc_len_on_chain() masks the length to
11 bits, so a linear frame longer than 2047 bytes would be silently
truncated.
Moreover, the RX DMA only fills a multiple of 4 bytes of a buffer: on
the H616, with 2047 programmed, a 2044 byte frame (FCS included) is
received in one descriptor and a 2045 byte frame already spills into a
second one. The usable size is therefore 2044 bytes, the same value as
DESC_BUF_MAX in the original sun8i-emac submission and in the U-Boot
driver.
Limit max_mtu so that a frame with two VLAN tags and the FCS fits in
2044 bytes (MTU 2018). A device tree max-frame-size can still lower it.
Longer frames from the wire span two descriptors and are dropped as a
whole by stmmac_rx(), which drains the descriptors of a split frame
since commit 834ec9530832 ("net: stmmac: drop split frames on AF_XDP
zero-copy RX").
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 24 +++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 0c82662fbe6e..a18d3daf6a3f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk.h>
+#include <linux/if_vlan.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mdio-mux.h>
@@ -219,12 +220,25 @@ static const struct emac_variant emac_variant_h616_emac1 = {
/* Used in RX_CTL0 */
#define EMAC_RX_RECEIVER_EN BIT(31)
+#define EMAC_RX_JUMBO_FRM_EN BIT(29)
#define EMAC_RX_DO_CRC BIT(27)
#define EMAC_RX_FLOW_CTL_EN BIT(16)
/* Used in TX_CTL0 */
#define EMAC_TX_TRANSMITTER_EN BIT(31)
+/* The buffer size field of the EMAC DMA descriptors is 11 bits wide, and
+ * the RX DMA only fills a multiple of 4 bytes of a buffer: with 2047
+ * programmed, frames longer than 2044 bytes spill into a second
+ * descriptor. The stmmac normal descriptor code used for this EMAC only
+ * handles frames that fit in a single RX descriptor and a single TX
+ * descriptor buffer. Bound the MTU so that a frame, including two VLAN
+ * tags and the FCS, always fits in 2044 bytes.
+ */
+#define EMAC_MAX_FRAME_LEN 2044
+#define EMAC_MAX_MTU (EMAC_MAX_FRAME_LEN - ETH_HLEN - \
+ 2 * VLAN_HLEN - ETH_FCS_LEN)
+
/* Used in EMAC_TX_FLOW_CTL */
#define EMAC_TX_FLOW_CTL_EN BIT(0)
@@ -645,6 +659,15 @@ static void sun8i_dwmac_core_init(struct mac_device_info *hw,
v = (8 << EMAC_BURSTLEN_SHIFT); /* burst len */
writel(v, ioaddr + EMAC_BASIC_CTL1);
+
+ /* Without JUMBO_FRM_EN the receiver flags every frame longer than
+ * 1518 bytes (1522 with a VLAN tag) as a length error, so any MTU
+ * above 1500 is unusable. Frames are still bounded by the RX
+ * descriptor buffer size, see EMAC_MAX_MTU.
+ */
+ v = readl(ioaddr + EMAC_RX_CTL0);
+ v |= EMAC_RX_JUMBO_FRM_EN;
+ writel(v, ioaddr + EMAC_RX_CTL0);
}
static void sun8i_dwmac_set_mac(void __iomem *ioaddr, bool enable)
@@ -1209,6 +1232,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
plat_dat->mac_setup = sun8i_dwmac_setup;
plat_dat->tx_fifo_size = 4096;
plat_dat->rx_fifo_size = 16384;
+ plat_dat->maxmtu = min(plat_dat->maxmtu, EMAC_MAX_MTU);
ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat);
if (ret)
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread