aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sky2.c65
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
795static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) 799static 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
3275static 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
3296static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 3279static 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
4813static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) 4790static 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
4849static int sky2_resume(struct pci_dev *pdev) 4829static 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
4896static void sky2_shutdown(struct pci_dev *pdev) 4876static 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
4928static struct pci_driver sky2_driver = { 4881static struct pci_driver sky2_driver = {