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 | ||
