diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3b0f08773800..1693ed116b16 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -4346,7 +4346,7 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
4346 | } | 4346 | } |
4347 | } | 4347 | } |
4348 | 4348 | ||
4349 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | 4349 | static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) |
4350 | { | 4350 | { |
4351 | struct net_device *netdev = pci_get_drvdata(pdev); | 4351 | struct net_device *netdev = pci_get_drvdata(pdev); |
4352 | struct e1000_adapter *adapter = netdev_priv(netdev); | 4352 | struct e1000_adapter *adapter = netdev_priv(netdev); |
@@ -4409,20 +4409,16 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4409 | 4409 | ||
4410 | ew32(WUC, E1000_WUC_PME_EN); | 4410 | ew32(WUC, E1000_WUC_PME_EN); |
4411 | ew32(WUFC, wufc); | 4411 | ew32(WUFC, wufc); |
4412 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
4413 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
4414 | } else { | 4412 | } else { |
4415 | ew32(WUC, 0); | 4413 | ew32(WUC, 0); |
4416 | ew32(WUFC, 0); | 4414 | ew32(WUFC, 0); |
4417 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
4418 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
4419 | } | 4415 | } |
4420 | 4416 | ||
4417 | *enable_wake = !!wufc; | ||
4418 | |||
4421 | /* make sure adapter isn't asleep if manageability is enabled */ | 4419 | /* make sure adapter isn't asleep if manageability is enabled */ |
4422 | if (adapter->flags & FLAG_MNG_PT_ENABLED) { | 4420 | if (adapter->flags & FLAG_MNG_PT_ENABLED) |
4423 | pci_enable_wake(pdev, PCI_D3hot, 1); | 4421 | *enable_wake = true; |
4424 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
4425 | } | ||
4426 | 4422 | ||
4427 | if (adapter->hw.phy.type == e1000_phy_igp_3) | 4423 | if (adapter->hw.phy.type == e1000_phy_igp_3) |
4428 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); | 4424 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); |
@@ -4435,6 +4431,26 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4435 | 4431 | ||
4436 | pci_disable_device(pdev); | 4432 | pci_disable_device(pdev); |
4437 | 4433 | ||
4434 | return 0; | ||
4435 | } | ||
4436 | |||
4437 | static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) | ||
4438 | { | ||
4439 | if (sleep && wake) { | ||
4440 | pci_prepare_to_sleep(pdev); | ||
4441 | return; | ||
4442 | } | ||
4443 | |||
4444 | pci_wake_from_d3(pdev, wake); | ||
4445 | pci_set_power_state(pdev, PCI_D3hot); | ||
4446 | } | ||
4447 | |||
4448 | static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, | ||
4449 | bool wake) | ||
4450 | { | ||
4451 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
4452 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
4453 | |||
4438 | /* | 4454 | /* |
4439 | * The pci-e switch on some quad port adapters will report a | 4455 | * The pci-e switch on some quad port adapters will report a |
4440 | * correctable error when the MAC transitions from D0 to D3. To | 4456 | * correctable error when the MAC transitions from D0 to D3. To |
@@ -4450,14 +4466,12 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4450 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, | 4466 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, |
4451 | (devctl & ~PCI_EXP_DEVCTL_CERE)); | 4467 | (devctl & ~PCI_EXP_DEVCTL_CERE)); |
4452 | 4468 | ||
4453 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 4469 | e1000_power_off(pdev, sleep, wake); |
4454 | 4470 | ||
4455 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl); | 4471 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl); |
4456 | } else { | 4472 | } else { |
4457 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 4473 | e1000_power_off(pdev, sleep, wake); |
4458 | } | 4474 | } |
4459 | |||
4460 | return 0; | ||
4461 | } | 4475 | } |
4462 | 4476 | ||
4463 | static void e1000e_disable_l1aspm(struct pci_dev *pdev) | 4477 | static void e1000e_disable_l1aspm(struct pci_dev *pdev) |
@@ -4486,6 +4500,18 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev) | |||
4486 | } | 4500 | } |
4487 | 4501 | ||
4488 | #ifdef CONFIG_PM | 4502 | #ifdef CONFIG_PM |
4503 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | ||
4504 | { | ||
4505 | int retval; | ||
4506 | bool wake; | ||
4507 | |||
4508 | retval = __e1000_shutdown(pdev, &wake); | ||
4509 | if (!retval) | ||
4510 | e1000_complete_shutdown(pdev, true, wake); | ||
4511 | |||
4512 | return retval; | ||
4513 | } | ||
4514 | |||
4489 | static int e1000_resume(struct pci_dev *pdev) | 4515 | static int e1000_resume(struct pci_dev *pdev) |
4490 | { | 4516 | { |
4491 | struct net_device *netdev = pci_get_drvdata(pdev); | 4517 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -4549,7 +4575,12 @@ static int e1000_resume(struct pci_dev *pdev) | |||
4549 | 4575 | ||
4550 | static void e1000_shutdown(struct pci_dev *pdev) | 4576 | static void e1000_shutdown(struct pci_dev *pdev) |
4551 | { | 4577 | { |
4552 | e1000_suspend(pdev, PMSG_SUSPEND); | 4578 | bool wake = false; |
4579 | |||
4580 | __e1000_shutdown(pdev, &wake); | ||
4581 | |||
4582 | if (system_state == SYSTEM_POWER_OFF) | ||
4583 | e1000_complete_shutdown(pdev, false, wake); | ||
4553 | } | 4584 | } |
4554 | 4585 | ||
4555 | #ifdef CONFIG_NET_POLL_CONTROLLER | 4586 | #ifdef CONFIG_NET_POLL_CONTROLLER |