diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2006-01-18 16:01:34 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-18 16:17:57 -0500 |
commit | 2f82665fe51b65921e64d5ceb3a6db98f72c4d61 (patch) | |
tree | 2b179bb39363508ca188a0ade30e98e36a0bf601 /drivers/net/e1000/e1000_main.c | |
parent | b92ff8ee5763ee0b408f3cf2360f58dd7ea9c5da (diff) |
[PATCH] e1000: Added functions to save and restore config
These functions help restore the driver to active configuration when coming out of resume for power management.
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 53a9cca06905..501f5108254e 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -4437,6 +4437,54 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) | |||
4437 | } | 4437 | } |
4438 | 4438 | ||
4439 | #ifdef CONFIG_PM | 4439 | #ifdef CONFIG_PM |
4440 | /* these functions save and restore 16 or 64 dwords (64-256 bytes) of config | ||
4441 | * space versus the 64 bytes that pci_[save|restore]_state handle | ||
4442 | */ | ||
4443 | #define PCIE_CONFIG_SPACE_LEN 256 | ||
4444 | #define PCI_CONFIG_SPACE_LEN 64 | ||
4445 | static int | ||
4446 | e1000_pci_save_state(struct e1000_adapter *adapter) | ||
4447 | { | ||
4448 | struct pci_dev *dev = adapter->pdev; | ||
4449 | int size; | ||
4450 | int i; | ||
4451 | if (adapter->hw.mac_type >= e1000_82571) | ||
4452 | size = PCIE_CONFIG_SPACE_LEN; | ||
4453 | else | ||
4454 | size = PCI_CONFIG_SPACE_LEN; | ||
4455 | |||
4456 | WARN_ON(adapter->config_space != NULL); | ||
4457 | |||
4458 | adapter->config_space = kmalloc(size, GFP_KERNEL); | ||
4459 | if (!adapter->config_space) { | ||
4460 | DPRINTK(PROBE, ERR, "unable to allocate %d bytes\n", size); | ||
4461 | return -ENOMEM; | ||
4462 | } | ||
4463 | for (i = 0; i < (size / 4); i++) | ||
4464 | pci_read_config_dword(dev, i * 4, &adapter->config_space[i]); | ||
4465 | return 0; | ||
4466 | } | ||
4467 | |||
4468 | static void | ||
4469 | e1000_pci_restore_state(struct e1000_adapter *adapter) | ||
4470 | { | ||
4471 | struct pci_dev *dev = adapter->pdev; | ||
4472 | int size; | ||
4473 | int i; | ||
4474 | if (adapter->config_space == NULL) | ||
4475 | return; | ||
4476 | if (adapter->hw.mac_type >= e1000_82571) | ||
4477 | size = PCIE_CONFIG_SPACE_LEN; | ||
4478 | else | ||
4479 | size = PCI_CONFIG_SPACE_LEN; | ||
4480 | for (i = 0; i < (size / 4); i++) | ||
4481 | pci_write_config_dword(dev, i * 4, adapter->config_space[i]); | ||
4482 | kfree(adapter->config_space); | ||
4483 | adapter->config_space = NULL; | ||
4484 | return; | ||
4485 | } | ||
4486 | #endif /* CONFIG_PM */ | ||
4487 | |||
4440 | static int | 4488 | static int |
4441 | e1000_suspend(struct pci_dev *pdev, pm_message_t state) | 4489 | e1000_suspend(struct pci_dev *pdev, pm_message_t state) |
4442 | { | 4490 | { |
@@ -4451,6 +4499,14 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4451 | if(netif_running(netdev)) | 4499 | if(netif_running(netdev)) |
4452 | e1000_down(adapter); | 4500 | e1000_down(adapter); |
4453 | 4501 | ||
4502 | #ifdef CONFIG_PM | ||
4503 | /* implement our own version of pci_save_state(pdev) because pci | ||
4504 | * express adapters have larger 256 byte config spaces */ | ||
4505 | retval = e1000_pci_save_state(adapter); | ||
4506 | if (retval) | ||
4507 | return retval; | ||
4508 | #endif | ||
4509 | |||
4454 | status = E1000_READ_REG(&adapter->hw, STATUS); | 4510 | status = E1000_READ_REG(&adapter->hw, STATUS); |
4455 | if(status & E1000_STATUS_LU) | 4511 | if(status & E1000_STATUS_LU) |
4456 | wufc &= ~E1000_WUFC_LNKC; | 4512 | wufc &= ~E1000_WUFC_LNKC; |
@@ -4507,8 +4563,6 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4507 | DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); | 4563 | DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); |
4508 | } | 4564 | } |
4509 | 4565 | ||
4510 | pci_save_state(pdev); | ||
4511 | |||
4512 | if(adapter->hw.mac_type >= e1000_82540 && | 4566 | if(adapter->hw.mac_type >= e1000_82540 && |
4513 | adapter->hw.media_type == e1000_media_type_copper) { | 4567 | adapter->hw.media_type == e1000_media_type_copper) { |
4514 | manc = E1000_READ_REG(&adapter->hw, MANC); | 4568 | manc = E1000_READ_REG(&adapter->hw, MANC); |
@@ -4537,6 +4591,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4537 | return 0; | 4591 | return 0; |
4538 | } | 4592 | } |
4539 | 4593 | ||
4594 | #ifdef CONFIG_PM | ||
4540 | static int | 4595 | static int |
4541 | e1000_resume(struct pci_dev *pdev) | 4596 | e1000_resume(struct pci_dev *pdev) |
4542 | { | 4597 | { |
@@ -4548,6 +4603,7 @@ e1000_resume(struct pci_dev *pdev) | |||
4548 | retval = pci_set_power_state(pdev, PCI_D0); | 4603 | retval = pci_set_power_state(pdev, PCI_D0); |
4549 | if (retval) | 4604 | if (retval) |
4550 | DPRINTK(PROBE, ERR, "Error in setting power state\n"); | 4605 | DPRINTK(PROBE, ERR, "Error in setting power state\n"); |
4606 | e1000_pci_restore_state(adapter); | ||
4551 | ret_val = pci_enable_device(pdev); | 4607 | ret_val = pci_enable_device(pdev); |
4552 | pci_set_master(pdev); | 4608 | pci_set_master(pdev); |
4553 | 4609 | ||