summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-09-22 14:43:16 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:36:53 +0300
commita176b9aa714e180c333ca366d3a7b8dc4a9f087a (patch)
treebb4be5e39e0063b1c34f48e623415fd30b5d2a73
parentf5217b89a59fae16008e37532068e71b51bd2b5a (diff)
downloadlinux-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.h4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4.h3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c11
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);
}