diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fb1d2c30c1bb..a6601e8d423c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -569,8 +569,8 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) | |||
569 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 569 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
570 | onoff = !onoff; | 570 | onoff = !onoff; |
571 | 571 | ||
572 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
572 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | 573 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
573 | |||
574 | if (onoff) | 574 | if (onoff) |
575 | /* Turn off phy power saving */ | 575 | /* Turn off phy power saving */ |
576 | reg1 &= ~phy_power[port]; | 576 | reg1 &= ~phy_power[port]; |
@@ -579,6 +579,7 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) | |||
579 | 579 | ||
580 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | 580 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
581 | sky2_pci_read32(hw, PCI_DEV_REG1); | 581 | sky2_pci_read32(hw, PCI_DEV_REG1); |
582 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
582 | udelay(100); | 583 | udelay(100); |
583 | } | 584 | } |
584 | 585 | ||
@@ -1511,6 +1512,13 @@ static int sky2_down(struct net_device *dev) | |||
1511 | imask &= ~portirq_msk[port]; | 1512 | imask &= ~portirq_msk[port]; |
1512 | sky2_write32(hw, B0_IMSK, imask); | 1513 | sky2_write32(hw, B0_IMSK, imask); |
1513 | 1514 | ||
1515 | /* | ||
1516 | * Both ports share the NAPI poll on port 0, so if necessary undo the | ||
1517 | * the disable that is done in dev_close. | ||
1518 | */ | ||
1519 | if (sky2->port == 0 && hw->ports > 1) | ||
1520 | netif_poll_enable(dev); | ||
1521 | |||
1514 | sky2_gmac_reset(hw, port); | 1522 | sky2_gmac_reset(hw, port); |
1515 | 1523 | ||
1516 | /* Stop transmitter */ | 1524 | /* Stop transmitter */ |
@@ -3631,6 +3639,29 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3631 | out: | 3639 | out: |
3632 | return err; | 3640 | return err; |
3633 | } | 3641 | } |
3642 | |||
3643 | /* BIOS resume runs after device (it's a bug in PM) | ||
3644 | * as a temporary workaround on suspend/resume leave MSI disabled | ||
3645 | */ | ||
3646 | static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state) | ||
3647 | { | ||
3648 | struct sky2_hw *hw = pci_get_drvdata(pdev); | ||
3649 | |||
3650 | free_irq(pdev->irq, hw); | ||
3651 | if (hw->msi) { | ||
3652 | pci_disable_msi(pdev); | ||
3653 | hw->msi = 0; | ||
3654 | } | ||
3655 | return 0; | ||
3656 | } | ||
3657 | |||
3658 | static int sky2_resume_early(struct pci_dev *pdev) | ||
3659 | { | ||
3660 | struct sky2_hw *hw = pci_get_drvdata(pdev); | ||
3661 | struct net_device *dev = hw->dev[0]; | ||
3662 | |||
3663 | return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw); | ||
3664 | } | ||
3634 | #endif | 3665 | #endif |
3635 | 3666 | ||
3636 | static struct pci_driver sky2_driver = { | 3667 | static struct pci_driver sky2_driver = { |
@@ -3641,6 +3672,8 @@ static struct pci_driver sky2_driver = { | |||
3641 | #ifdef CONFIG_PM | 3672 | #ifdef CONFIG_PM |
3642 | .suspend = sky2_suspend, | 3673 | .suspend = sky2_suspend, |
3643 | .resume = sky2_resume, | 3674 | .resume = sky2_resume, |
3675 | .suspend_late = sky2_suspend_late, | ||
3676 | .resume_early = sky2_resume_early, | ||
3644 | #endif | 3677 | #endif |
3645 | }; | 3678 | }; |
3646 | 3679 | ||