Commit 1c557819 authored by Guo-Fu Tseng's avatar Guo-Fu Tseng Committed by David S. Miller

jme: Support WoL after shutdown

Adding shutdown function that setup wake if wol is enabled.
Add jme_phy_on in jme_set_100m_half in case it is shutting down
or suspending when interface is down(phy_off by default).

v2 updates:
Removed CONFIG_PM ifdef for jme_set_100m_half and jme_wait_link.
It would be nice if it can be applied to net-2.6 along with other patches
sent few days ago. If it is not appropriate, please ignore the net-2.6
request, and apply it to net-next-2.6 as previous patch. :)
Reported-and-helped-by: default avatarСtac <Taoga@yandex.ru>
Signed-off-by: default avatarGuo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b889416b
...@@ -1623,12 +1623,12 @@ jme_open(struct net_device *netdev) ...@@ -1623,12 +1623,12 @@ jme_open(struct net_device *netdev)
return rc; return rc;
} }
#ifdef CONFIG_PM
static void static void
jme_set_100m_half(struct jme_adapter *jme) jme_set_100m_half(struct jme_adapter *jme)
{ {
u32 bmcr, tmp; u32 bmcr, tmp;
jme_phy_on(jme);
bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
BMCR_SPEED1000 | BMCR_FULLDPLX); BMCR_SPEED1000 | BMCR_FULLDPLX);
...@@ -1656,7 +1656,6 @@ jme_wait_link(struct jme_adapter *jme) ...@@ -1656,7 +1656,6 @@ jme_wait_link(struct jme_adapter *jme)
phylink = jme_linkstat_from_phy(jme); phylink = jme_linkstat_from_phy(jme);
} }
} }
#endif
static inline void static inline void
jme_phy_off(struct jme_adapter *jme) jme_phy_off(struct jme_adapter *jme)
...@@ -1664,6 +1663,21 @@ jme_phy_off(struct jme_adapter *jme) ...@@ -1664,6 +1663,21 @@ jme_phy_off(struct jme_adapter *jme)
jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN); jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN);
} }
static void
jme_powersave_phy(struct jme_adapter *jme)
{
if (jme->reg_pmcs) {
jme_set_100m_half(jme);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
jwrite32(jme, JME_PMCS, jme->reg_pmcs);
} else {
jme_phy_off(jme);
}
}
static int static int
jme_close(struct net_device *netdev) jme_close(struct net_device *netdev)
{ {
...@@ -2991,6 +3005,16 @@ jme_remove_one(struct pci_dev *pdev) ...@@ -2991,6 +3005,16 @@ jme_remove_one(struct pci_dev *pdev)
} }
static void
jme_shutdown(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
jme_powersave_phy(jme);
pci_pme_active(pdev, true);
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int static int
jme_suspend(struct pci_dev *pdev, pm_message_t state) jme_suspend(struct pci_dev *pdev, pm_message_t state)
...@@ -3028,19 +3052,9 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3028,19 +3052,9 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
tasklet_hi_enable(&jme->rxempty_task); tasklet_hi_enable(&jme->rxempty_task);
pci_save_state(pdev); pci_save_state(pdev);
if (jme->reg_pmcs) { jme_powersave_phy(jme);
jme_set_100m_half(jme); pci_enable_wake(jme->pdev, PCI_D3hot, true);
pci_set_power_state(pdev, PCI_D3hot);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
jwrite32(jme, JME_PMCS, jme->reg_pmcs);
pci_enable_wake(pdev, PCI_D3cold, true);
} else {
jme_phy_off(jme);
}
pci_set_power_state(pdev, PCI_D3cold);
return 0; return 0;
} }
...@@ -3087,6 +3101,7 @@ static struct pci_driver jme_driver = { ...@@ -3087,6 +3101,7 @@ static struct pci_driver jme_driver = {
.suspend = jme_suspend, .suspend = jme_suspend,
.resume = jme_resume, .resume = jme_resume,
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
.shutdown = jme_shutdown,
}; };
static int __init static int __init
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment