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