diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 25ec5f757c68..acb4d41f56e1 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -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; diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h index 860494ff3714..ec5dfddf7322 100644 --- a/drivers/net/ethernet/jme.h +++ b/drivers/net/ethernet/jme.h @@ -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)