diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2025-09-22 14:43:16 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:36:53 +0300 |
| commit | a176b9aa714e180c333ca366d3a7b8dc4a9f087a (patch) | |
| tree | bb4be5e39e0063b1c34f48e623415fd30b5d2a73 | |
| parent | f5217b89a59fae16008e37532068e71b51bd2b5a (diff) | |
| download | linux-a176b9aa714e180c333ca366d3a7b8dc4a9f087a.tar.gz linux-a176b9aa714e180c333ca366d3a7b8dc4a9f087a.zip | |
net: stmmac: Enable LPI IRQs on the link up event
The MAC IRQs are enabled early on the NET-device open stage by means of
the stmmac_core_init() method execution. This also concerns the MAC LPI
IRQ. There is no point in handling the event while the link is down, since
the device won't track LPI events anyway. Moreover having the LPI IRQ
unmasked before the respective IRQ-handler is installed will cause the
early LPI IRQ being considered as spurious on the shared-IRQ case thus
force-converting the IRQ-line to being polled.
Considering all the above let's enable the LPI IRQ only on the MAC Link Up
event. Thus preventing the IRQ from happening before the respective
IRQ-handler is installed and the link is established.
This change is also required for the DW MAC GPI IRQs handling in the
shared IRQ-line manner.
Fixes: d765955d2ae0 ("stmmac: add the Energy Efficient Ethernet support")
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 11 |
6 files changed, 29 insertions, 17 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 6d69ec596fb9..809a09a2a4d4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -35,10 +35,12 @@ #define GMAC_INT_DISABLE_PCSAN BIT(2) #define GMAC_INT_DISABLE_PMT BIT(3) #define GMAC_INT_DISABLE_TIMESTAMP BIT(9) +#define GMAC_INT_DISABLE_LPI BIT(10) #define GMAC_INT_DEFAULT_MASK (GMAC_INT_DISABLE_RGMII | \ GMAC_INT_DISABLE_PCSLINK | \ GMAC_INT_DISABLE_PCSAN | \ - GMAC_INT_DISABLE_TIMESTAMP) + GMAC_INT_DISABLE_TIMESTAMP | \ + GMAC_INT_DISABLE_LPI) /* PMT Control and Status */ #define GMAC_PMT 0x0000002c diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 38032786b221..29fb465d8192 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -559,15 +559,18 @@ static int dwmac1000_set_lpi_mode(struct mac_device_info *hw, static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link) { void __iomem *ioaddr = hw->pcsr; - u32 value; + u32 value, intr_mask; value = readl(ioaddr + LPI_CTRL_STATUS); - - if (link) + intr_mask = readl(ioaddr + GMAC_INT_MASK); + if (link) { value |= LPI_CTRL_STATUS_PLS; - else + intr_mask &= ~GMAC_INT_DISABLE_LPI; + } else { + intr_mask |= GMAC_INT_DISABLE_LPI; value &= ~LPI_CTRL_STATUS_PLS; - + } + writel(intr_mask, ioaddr + GMAC_INT_MASK); writel(value, ioaddr + LPI_CTRL_STATUS); } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index 53ac45b50e22..a59fab217db2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -111,8 +111,7 @@ #define GMAC_INT_LPI_EN BIT(5) #define GMAC_INT_TSIE BIT(12) -#define GMAC_INT_DEFAULT_ENABLE (GMAC_INT_PMT_EN | GMAC_INT_LPI_EN | \ - GMAC_INT_TSIE) +#define GMAC_INT_DEFAULT_ENABLE (GMAC_INT_PMT_EN | GMAC_INT_TSIE) enum dwmac4_irq_status { time_stamp_irq = 0x00001000, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 5d95acfc748f..5ca647fe1c45 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -479,15 +479,18 @@ static int dwmac4_set_lpi_mode(struct mac_device_info *hw, static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link) { void __iomem *ioaddr = hw->pcsr; - u32 value; + u32 value, intr_enable; value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); - - if (link) + intr_enable = readl(ioaddr + GMAC_INT_EN); + if (link) { value |= LPI_CTRL_STATUS_PLS; - else + intr_enable |= GMAC_INT_LPI_EN; + } else { + intr_enable &= ~GMAC_INT_LPI_EN; value &= ~LPI_CTRL_STATUS_PLS; - + } + writel(intr_enable, ioaddr + GMAC_INT_EN); writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h index 1798289ef6ab..549574454a7d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h @@ -82,7 +82,7 @@ #define XGMAC_TSIE BIT(12) #define XGMAC_LPIIE BIT(5) #define XGMAC_PMTIE BIT(4) -#define XGMAC_INT_DEFAULT_EN (XGMAC_LPIIE | XGMAC_PMTIE) +#define XGMAC_INT_DEFAULT_EN (XGMAC_PMTIE) #define XGMAC_Qx_TX_FLOW_CTRL(x) (0x00000070 + (x) * 4) #define XGMAC_PT GENMASK(31, 16) #define XGMAC_TFE BIT(1) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c index 197e9d5dd6db..7e4457bfa86f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c @@ -526,13 +526,18 @@ static int dwxgmac2_set_lpi_mode(struct mac_device_info *hw, static void dwxgmac2_set_eee_pls(struct mac_device_info *hw, int link) { void __iomem *ioaddr = hw->pcsr; - u32 value; + u32 value, en; value = readl(ioaddr + XGMAC_LPI_CTRL); - if (link) + en = readl(ioaddr + XGMAC_INT_EN); + if (link) { value |= LPI_CTRL_STATUS_PLS; - else + en |= XGMAC_LPIIE; + } else { + en &= ~XGMAC_LPIIE; value &= ~LPI_CTRL_STATUS_PLS; + } + writel(en, ioaddr + XGMAC_INT_EN); writel(value, ioaddr + XGMAC_LPI_CTRL); } |
