diff options
author | stephen hemminger <shemminger@vyatta.com> | 2010-02-12 01:57:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-12 19:21:00 -0500 |
commit | 5f8ae5c537d937bab9cfeb83a30a9b670c3cfb35 (patch) | |
tree | b40d8ce68c520bc2bef3213e20292aa3d0b45ac4 /drivers/net/sky2.c | |
parent | 8b05543129a5f216e08625e947a16b844bc4766d (diff) |
sky2: WoL changes
Change Wake On Lan code to be similar to vendor driver. The definition
of Y2_HW_WOL_ON is confusing; what it means is transition to firmware SPI
setting when doing power change.
Since same code is done for both shutdown and suspend, use common
code path.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 65 |
1 files changed, 9 insertions, 56 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 92f7ba0953ee..edf37aaf67f8 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -251,6 +251,8 @@ static void sky2_power_on(struct sky2_hw *hw) | |||
251 | 251 | ||
252 | sky2_pci_write32(hw, PCI_CFG_REG_1, 0); | 252 | sky2_pci_write32(hw, PCI_CFG_REG_1, 0); |
253 | 253 | ||
254 | sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); | ||
255 | |||
254 | /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */ | 256 | /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */ |
255 | reg = sky2_read32(hw, B2_GP_IO); | 257 | reg = sky2_read32(hw, B2_GP_IO); |
256 | reg |= GLB_GPIO_STAT_RACE_DIS; | 258 | reg |= GLB_GPIO_STAT_RACE_DIS; |
@@ -782,6 +784,9 @@ static void sky2_wol_init(struct sky2_port *sky2) | |||
782 | ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT; | 784 | ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT; |
783 | sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl); | 785 | sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl); |
784 | 786 | ||
787 | /* Disable PiG firmware */ | ||
788 | sky2_write16(hw, B0_CTST, Y2_HW_WOL_OFF); | ||
789 | |||
785 | /* Turn on legacy PCI-Express PME mode */ | 790 | /* Turn on legacy PCI-Express PME mode */ |
786 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | 791 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
787 | reg1 |= PCI_Y2_PME_LEGACY; | 792 | reg1 |= PCI_Y2_PME_LEGACY; |
@@ -789,7 +794,6 @@ static void sky2_wol_init(struct sky2_port *sky2) | |||
789 | 794 | ||
790 | /* block receiver */ | 795 | /* block receiver */ |
791 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 796 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
792 | |||
793 | } | 797 | } |
794 | 798 | ||
795 | static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) | 799 | static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) |
@@ -3272,27 +3276,6 @@ static inline u8 sky2_wol_supported(const struct sky2_hw *hw) | |||
3272 | return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0; | 3276 | return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0; |
3273 | } | 3277 | } |
3274 | 3278 | ||
3275 | static void sky2_hw_set_wol(struct sky2_hw *hw) | ||
3276 | { | ||
3277 | int wol = 0; | ||
3278 | int i; | ||
3279 | |||
3280 | for (i = 0; i < hw->ports; i++) { | ||
3281 | struct net_device *dev = hw->dev[i]; | ||
3282 | struct sky2_port *sky2 = netdev_priv(dev); | ||
3283 | |||
3284 | if (sky2->wol) | ||
3285 | wol = 1; | ||
3286 | } | ||
3287 | |||
3288 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || | ||
3289 | hw->chip_id == CHIP_ID_YUKON_EX || | ||
3290 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
3291 | sky2_write32(hw, B0_CTST, wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); | ||
3292 | |||
3293 | device_set_wakeup_enable(&hw->pdev->dev, wol); | ||
3294 | } | ||
3295 | |||
3296 | static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 3279 | static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
3297 | { | 3280 | { |
3298 | const struct sky2_port *sky2 = netdev_priv(dev); | 3281 | const struct sky2_port *sky2 = netdev_priv(dev); |
@@ -3311,11 +3294,6 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
3311 | return -EOPNOTSUPP; | 3294 | return -EOPNOTSUPP; |
3312 | 3295 | ||
3313 | sky2->wol = wol->wolopts; | 3296 | sky2->wol = wol->wolopts; |
3314 | |||
3315 | sky2_hw_set_wol(hw); | ||
3316 | |||
3317 | if (!netif_running(dev)) | ||
3318 | sky2_wol_init(sky2); | ||
3319 | return 0; | 3297 | return 0; |
3320 | } | 3298 | } |
3321 | 3299 | ||
@@ -4809,7 +4787,6 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
4809 | pci_set_drvdata(pdev, NULL); | 4787 | pci_set_drvdata(pdev, NULL); |
4810 | } | 4788 | } |
4811 | 4789 | ||
4812 | #ifdef CONFIG_PM | ||
4813 | static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | 4790 | static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) |
4814 | { | 4791 | { |
4815 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 4792 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
@@ -4834,6 +4811,8 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4834 | wol |= sky2->wol; | 4811 | wol |= sky2->wol; |
4835 | } | 4812 | } |
4836 | 4813 | ||
4814 | device_set_wakeup_enable(&pdev->dev, wol != 0); | ||
4815 | |||
4837 | sky2_write32(hw, B0_IMSK, 0); | 4816 | sky2_write32(hw, B0_IMSK, 0); |
4838 | napi_disable(&hw->napi); | 4817 | napi_disable(&hw->napi); |
4839 | sky2_power_aux(hw); | 4818 | sky2_power_aux(hw); |
@@ -4846,6 +4825,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4846 | return 0; | 4825 | return 0; |
4847 | } | 4826 | } |
4848 | 4827 | ||
4828 | #ifdef CONFIG_PM | ||
4849 | static int sky2_resume(struct pci_dev *pdev) | 4829 | static int sky2_resume(struct pci_dev *pdev) |
4850 | { | 4830 | { |
4851 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 4831 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
@@ -4895,34 +4875,7 @@ out: | |||
4895 | 4875 | ||
4896 | static void sky2_shutdown(struct pci_dev *pdev) | 4876 | static void sky2_shutdown(struct pci_dev *pdev) |
4897 | { | 4877 | { |
4898 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 4878 | sky2_suspend(pdev, PMSG_SUSPEND); |
4899 | int i, wol = 0; | ||
4900 | |||
4901 | if (!hw) | ||
4902 | return; | ||
4903 | |||
4904 | rtnl_lock(); | ||
4905 | del_timer_sync(&hw->watchdog_timer); | ||
4906 | |||
4907 | for (i = 0; i < hw->ports; i++) { | ||
4908 | struct net_device *dev = hw->dev[i]; | ||
4909 | struct sky2_port *sky2 = netdev_priv(dev); | ||
4910 | |||
4911 | if (sky2->wol) { | ||
4912 | wol = 1; | ||
4913 | sky2_wol_init(sky2); | ||
4914 | } | ||
4915 | } | ||
4916 | |||
4917 | if (wol) | ||
4918 | sky2_power_aux(hw); | ||
4919 | rtnl_unlock(); | ||
4920 | |||
4921 | pci_enable_wake(pdev, PCI_D3hot, wol); | ||
4922 | pci_enable_wake(pdev, PCI_D3cold, wol); | ||
4923 | |||
4924 | pci_disable_device(pdev); | ||
4925 | pci_set_power_state(pdev, PCI_D3hot); | ||
4926 | } | 4879 | } |
4927 | 4880 | ||
4928 | static struct pci_driver sky2_driver = { | 4881 | static struct pci_driver sky2_driver = { |