diff options
author | Guo-Fu Tseng <cooldavid@cooldavid.org> | 2010-10-24 19:18:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-24 19:18:25 -0400 |
commit | 1c5578194abde100c089855cce72e87c047d8530 (patch) | |
tree | a61bc9675d0c9db2db770367f24d5ac55b98d68a /drivers/net/jme.c | |
parent | b889416b54c90f59276537debd92cb4e84b5f550 (diff) |
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: Сtac <Taoga@yandex.ru>
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/jme.c')
-rw-r--r-- | drivers/net/jme.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d7a975ee2add..d85edf3119c2 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
@@ -1623,12 +1623,12 @@ err_out: | |||
1623 | return rc; | 1623 | return rc; |
1624 | } | 1624 | } |
1625 | 1625 | ||
1626 | #ifdef CONFIG_PM | ||
1627 | static void | 1626 | static void |
1628 | jme_set_100m_half(struct jme_adapter *jme) | 1627 | jme_set_100m_half(struct jme_adapter *jme) |
1629 | { | 1628 | { |
1630 | u32 bmcr, tmp; | 1629 | u32 bmcr, tmp; |
1631 | 1630 | ||
1631 | jme_phy_on(jme); | ||
1632 | bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); | 1632 | bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); |
1633 | tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | | 1633 | tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | |
1634 | BMCR_SPEED1000 | BMCR_FULLDPLX); | 1634 | BMCR_SPEED1000 | BMCR_FULLDPLX); |
@@ -1656,7 +1656,6 @@ jme_wait_link(struct jme_adapter *jme) | |||
1656 | phylink = jme_linkstat_from_phy(jme); | 1656 | phylink = jme_linkstat_from_phy(jme); |
1657 | } | 1657 | } |
1658 | } | 1658 | } |
1659 | #endif | ||
1660 | 1659 | ||
1661 | static inline void | 1660 | static inline void |
1662 | jme_phy_off(struct jme_adapter *jme) | 1661 | jme_phy_off(struct jme_adapter *jme) |
@@ -1664,6 +1663,21 @@ jme_phy_off(struct jme_adapter *jme) | |||
1664 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN); | 1663 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN); |
1665 | } | 1664 | } |
1666 | 1665 | ||
1666 | static void | ||
1667 | jme_powersave_phy(struct jme_adapter *jme) | ||
1668 | { | ||
1669 | if (jme->reg_pmcs) { | ||
1670 | jme_set_100m_half(jme); | ||
1671 | |||
1672 | if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN)) | ||
1673 | jme_wait_link(jme); | ||
1674 | |||
1675 | jwrite32(jme, JME_PMCS, jme->reg_pmcs); | ||
1676 | } else { | ||
1677 | jme_phy_off(jme); | ||
1678 | } | ||
1679 | } | ||
1680 | |||
1667 | static int | 1681 | static int |
1668 | jme_close(struct net_device *netdev) | 1682 | jme_close(struct net_device *netdev) |
1669 | { | 1683 | { |
@@ -2991,6 +3005,16 @@ jme_remove_one(struct pci_dev *pdev) | |||
2991 | 3005 | ||
2992 | } | 3006 | } |
2993 | 3007 | ||
3008 | static void | ||
3009 | jme_shutdown(struct pci_dev *pdev) | ||
3010 | { | ||
3011 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
3012 | struct jme_adapter *jme = netdev_priv(netdev); | ||
3013 | |||
3014 | jme_powersave_phy(jme); | ||
3015 | pci_pme_active(pdev, true); | ||
3016 | } | ||
3017 | |||
2994 | #ifdef CONFIG_PM | 3018 | #ifdef CONFIG_PM |
2995 | static int | 3019 | static int |
2996 | jme_suspend(struct pci_dev *pdev, pm_message_t state) | 3020 | 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 | tasklet_hi_enable(&jme->rxempty_task); | 3052 | tasklet_hi_enable(&jme->rxempty_task); |
3029 | 3053 | ||
3030 | pci_save_state(pdev); | 3054 | pci_save_state(pdev); |
3031 | if (jme->reg_pmcs) { | 3055 | jme_powersave_phy(jme); |
3032 | jme_set_100m_half(jme); | 3056 | pci_enable_wake(jme->pdev, PCI_D3hot, true); |
3033 | 3057 | pci_set_power_state(pdev, PCI_D3hot); | |
3034 | if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN)) | ||
3035 | jme_wait_link(jme); | ||
3036 | |||
3037 | jwrite32(jme, JME_PMCS, jme->reg_pmcs); | ||
3038 | |||
3039 | pci_enable_wake(pdev, PCI_D3cold, true); | ||
3040 | } else { | ||
3041 | jme_phy_off(jme); | ||
3042 | } | ||
3043 | pci_set_power_state(pdev, PCI_D3cold); | ||
3044 | 3058 | ||
3045 | return 0; | 3059 | return 0; |
3046 | } | 3060 | } |
@@ -3087,6 +3101,7 @@ static struct pci_driver jme_driver = { | |||
3087 | .suspend = jme_suspend, | 3101 | .suspend = jme_suspend, |
3088 | .resume = jme_resume, | 3102 | .resume = jme_resume, |
3089 | #endif /* CONFIG_PM */ | 3103 | #endif /* CONFIG_PM */ |
3104 | .shutdown = jme_shutdown, | ||
3090 | }; | 3105 | }; |
3091 | 3106 | ||
3092 | static int __init | 3107 | static int __init |