diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 9b6b49331639..ce51b9c22129 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1438,7 +1438,12 @@ static int stmmac_phylink_setup(struct stmmac_priv *priv) config->supported_interfaces, pcs->supported_interfaces); - if (priv->dma_cap.eee) { + /* Some platforms, e.g. iMX8MP, wire lpi_intr_o to the same interrupt + * used for stmmac's main interrupts, which leads to interrupt storms. + * STMMAC_FLAG_EEE_DISABLE allows EEE to be disabled on such platforms. + */ + if (priv->dma_cap.eee && + !(priv->plat->flags & STMMAC_FLAG_EEE_DISABLE)) { /* The GMAC 3.74a databook states that EEE is only supported * in MII, GMII, and RGMII interfaces. */ diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index eaaee329ef9d..4430b967abde 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -204,12 +204,13 @@ enum dwmac_core_type { #define STMMAC_FLAG_MULTI_MSI_EN BIT(7) #define STMMAC_FLAG_EXT_SNAPSHOT_EN BIT(8) #define STMMAC_FLAG_INT_SNAPSHOT_EN BIT(9) -#define STMMAC_FLAG_RX_CLK_RUNS_IN_LPI BIT(10) -#define STMMAC_FLAG_EN_TX_LPI_CLOCKGATING BIT(11) -#define STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP BIT(12) -#define STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY BIT(13) -#define STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD BIT(14) -#define STMMAC_FLAG_SERDES_SUPPORTS_2500M BIT(15) +#define STMMAC_FLAG_EEE_DISABLE BIT(10) +#define STMMAC_FLAG_RX_CLK_RUNS_IN_LPI BIT(11) +#define STMMAC_FLAG_EN_TX_LPI_CLOCKGATING BIT(12) +#define STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP BIT(13) +#define STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY BIT(14) +#define STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD BIT(15) +#define STMMAC_FLAG_SERDES_SUPPORTS_2500M BIT(16) struct mac_device_info; -- knotmirror 0.0.1 From 394863097e3603eafe819ab4085cbd0ddf371dd9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 25 Mar 2026 23:00:03 +0200 Subject: [PATCH 2/2] net: stmmac: imx: Disable EEE The i.MX8MP suffers from an interrupt storm related to the stmmac and EEE. A long and tedious analysis ([1]) concluded that the SoC wires the stmmac lpi_intr_o signal to an OR gate along with the main dwmac interrupts, which causes an interrupt storm for two reasons. First, there's a race condition due to the interrupt deassertion being synchronous to the RX clock domain: - When the PHY exits LPI mode, it restarts generating the RX clock (clk_rx_i input signal to the GMAC). - The MAC detects exit from LPI, and asserts lpi_intr_o. This triggers the ENET_EQOS interrupt. - Before the CPU has time to process the interrupt, the PHY enters LPI mode again, and stops generating the RX clock. - The CPU processes the interrupt and reads the GMAC4_LPI_CTRL_STATUS registers. This does not clear lpi_intr_o as there's no clk_rx_i. An attempt was made to fixing the issue by not stopping RX_CLK in Rx LPI state ([2]). This alleviates the symptoms but doesn't fix the issue. Since lpi_intr_o takes four RX_CLK cycles to clear, an interrupt storm can still occur during that window. In 1000T mode this is harder to notice, but slower receive clocks cause hundreds to thousands of spurious interrupts. Fix the issue by disabling EEE completely on i.MX8MP. [1] https://lore.kernel.org/all/20251026122905.29028-1-laurent.pinchart@ideasonboard.com/ [2] https://lore.kernel.org/all/20251123053518.8478-1-laurent.pinchart@ideasonboard.com/ Signed-off-by: Laurent Pinchart Reviewed-by: Russell King (Oracle) Link: https://patch.msgid.link/20260325210003.2752013-3-laurent.pinchart@ideasonboard.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c index 9d1bd72ffb73..01260dbbb698 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c @@ -325,11 +325,7 @@ static int imx_dwmac_probe(struct platform_device *pdev) return ret; } - if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) - plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; - - if (data->flags & STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD) - plat_dat->flags |= STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD; + plat_dat->flags |= data->flags; /* Default TX Q0 to use TSO and rest TXQ for TBS */ for (int i = 1; i < plat_dat->tx_queues_to_use; i++) @@ -366,7 +362,8 @@ static struct imx_dwmac_ops imx8mp_dwmac_data = { .addr_width = 34, .mac_rgmii_txclk_auto_adj = false, .set_intf_mode = imx8mp_set_intf_mode, - .flags = STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY | + .flags = STMMAC_FLAG_EEE_DISABLE | + STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY | STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD, };