net: jme: keep RX MAC clock enabled for WoL

On the JMicron JMC250 revision 03, the MAC reset performed during
suspend leaves GPREG1_RXCLKOFF set. Although the driver enables Magic
Packet detection, the gated RX MAC clock prevents wake-up from ACPI S3.

Keep the RX MAC clock enabled while WoL is armed. Restore the gated
clock state immediately after disabling WoL during resume, preserving
the RX engine initialization ordering.

Prevent concurrent link-change work from gating the clock again after
WoL has been armed. Quiesce interrupt-driven link-change scheduling,
synchronize pending interrupts, and cancel outstanding link-change
work before programming WoL in suspend and shutdown paths.

Restore the deferred processing state before requesting link
reinitialization on resume.

Tested on an ASUS K42JE with JMC250 [197b:0250] rev 03 using a
Debian 6.12.111 kernel and an externally built module. ACPI S3 wake
with a Magic Packet completed in 19 seconds, while a control without
a Magic Packet resumed through the RTC alarm after 123 seconds.
Ethernet and SSH recovered after resume.

S4 and S5 wake behaviour has not been validated with this revision.

Fixes: 854a2e7c33 ("jme: Safer MAC processor reset sequence")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Franck Baur <franck.baur.67@gmail.com>
Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
This commit is contained in:
Franck Baur 2026-10-24 14:40:44 +02:00 committed by Dave Miller
parent 5838f10563
commit ed9179fc72
2 changed files with 33 additions and 5 deletions

View File

@ -1502,7 +1502,8 @@ jme_intr_msi(struct jme_adapter *jme, u32 intrstat)
* all other events are ignored
*/
jwrite32(jme, JME_IEVE, intrstat);
schedule_work(&jme->linkch_task);
if (!test_bit(JME_FLAG_WOL_QUIESCE, &jme->flags))
schedule_work(&jme->linkch_task);
goto out_reenable;
}
@ -1546,7 +1547,8 @@ jme_intr_msi(struct jme_adapter *jme, u32 intrstat)
/*
* Re-enable interrupt
*/
jwrite32f(jme, JME_IENS, INTR_ENABLE);
if (!test_bit(JME_FLAG_WOL_QUIESCE, &jme->flags))
jwrite32f(jme, JME_IENS, INTR_ENABLE);
}
static irqreturn_t
@ -1892,6 +1894,7 @@ jme_powersave_phy(struct jme_adapter *jme)
jme_set_100m_half(jme);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
jme_mac_rxclk_on(jme);
jme_clear_pm_enable_wol(jme);
} else {
jme_phy_off(jme);
@ -3158,6 +3161,21 @@ jme_shutdown(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
if (netif_running(netdev)) {
set_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
netif_device_detach(netdev);
netif_stop_queue(netdev);
jme_stop_irq(jme);
synchronize_irq(pdev->irq);
jme_stop_irq(jme);
cancel_work_sync(&jme->linkch_task);
tasklet_disable(&jme->pcc_task);
napi_disable(&jme->napi);
tasklet_disable(&jme->txclean_task);
tasklet_disable(&jme->rxclean_task);
tasklet_disable(&jme->rxempty_task);
}
jme_powersave_phy(jme);
pci_pme_active(pdev, true);
}
@ -3172,11 +3190,16 @@ jme_suspend(struct device *dev)
if (!netif_running(netdev))
return 0;
atomic_dec(&jme->link_changing);
set_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
netif_device_detach(netdev);
netif_stop_queue(netdev);
jme_stop_irq(jme);
synchronize_irq(jme->pdev->irq);
jme_stop_irq(jme);
cancel_work_sync(&jme->linkch_task);
tasklet_disable(&jme->pcc_task);
napi_disable(&jme->napi);
atomic_dec(&jme->link_changing);
tasklet_disable(&jme->txclean_task);
tasklet_disable(&jme->rxclean_task);
@ -3215,6 +3238,7 @@ jme_resume(struct device *dev)
return 0;
jme_clear_pm_disable_wol(jme);
jme_mac_rxclk_off(jme);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
jme_set_link_ksettings(netdev, &jme->old_cmd);
@ -3226,8 +3250,11 @@ jme_resume(struct device *dev)
atomic_inc(&jme->link_changing);
jme_reset_link(jme);
napi_enable(&jme->napi);
tasklet_enable(&jme->pcc_task);
clear_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
jme_reset_link(jme);
jme_start_irq(jme);
return 0;

View File

@ -450,6 +450,7 @@ enum jme_flags_bits {
JME_FLAG_SSET = 2,
JME_FLAG_POLL = 5,
JME_FLAG_SHUTDOWN = 6,
JME_FLAG_WOL_QUIESCE = 7,
};
#define TX_TIMEOUT (5 * HZ)