These functions help restore the driver to active configuration when coming out
of resume for power management.
Signed-off-by: Jeff Kirsher [EMAIL PROTECTED]
Signed-off-by: Jesse Brandeburg [EMAIL PROTECTED]
Signed-off-by: John Ronciak [EMAIL PROTECTED]
---
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 53a9cca..501f510 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
}
#ifdef CONFIG_PM
+/* these functions save and restore 16 or 64 dwords (64-256 bytes) of config
+ * space versus the 64 bytes that pci_[save|restore]_state handle
+ */
+#define PCIE_CONFIG_SPACE_LEN 256
+#define PCI_CONFIG_SPACE_LEN 64
+static int
+e1000_pci_save_state(struct e1000_adapter *adapter)
+{
+ struct pci_dev *dev = adapter-pdev;
+ int size;
+ int i;
+ if (adapter-hw.mac_type = e1000_82571)
+ size = PCIE_CONFIG_SPACE_LEN;
+ else
+ size = PCI_CONFIG_SPACE_LEN;
+
+ WARN_ON(adapter-config_space != NULL);
+
+ adapter-config_space = kmalloc(size, GFP_KERNEL);
+ if (!adapter-config_space) {
+ DPRINTK(PROBE, ERR, unable to allocate %d bytes\n, size);
+ return -ENOMEM;
+ }
+ for (i = 0; i (size / 4); i++)
+ pci_read_config_dword(dev, i * 4, adapter-config_space[i]);
+ return 0;
+}
+
+static void
+e1000_pci_restore_state(struct e1000_adapter *adapter)
+{
+ struct pci_dev *dev = adapter-pdev;
+ int size;
+ int i;
+ if (adapter-config_space == NULL)
+ return;
+ if (adapter-hw.mac_type = e1000_82571)
+ size = PCIE_CONFIG_SPACE_LEN;
+ else
+ size = PCI_CONFIG_SPACE_LEN;
+ for (i = 0; i (size / 4); i++)
+ pci_write_config_dword(dev, i * 4, adapter-config_space[i]);
+ kfree(adapter-config_space);
+ adapter-config_space = NULL;
+ return;
+}
+#endif /* CONFIG_PM */
+
static int
e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -4451,6 +4499,14 @@ e1000_suspend(struct pci_dev *pdev, pm_m
if(netif_running(netdev))
e1000_down(adapter);
+#ifdef CONFIG_PM
+ /* implement our own version of pci_save_state(pdev) because pci
+* express adapters have larger 256 byte config spaces */
+ retval = e1000_pci_save_state(adapter);
+ if (retval)
+ return retval;
+#endif
+
status = E1000_READ_REG(adapter-hw, STATUS);
if(status E1000_STATUS_LU)
wufc = ~E1000_WUFC_LNKC;
@@ -4507,8 +4563,6 @@ e1000_suspend(struct pci_dev *pdev, pm_m
DPRINTK(PROBE, ERR, Error enabling D3 cold wake\n);
}
- pci_save_state(pdev);
-
if(adapter-hw.mac_type = e1000_82540
adapter-hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(adapter-hw, MANC);
@@ -4537,6 +4591,7 @@ e1000_suspend(struct pci_dev *pdev, pm_m
return 0;
}
+#ifdef CONFIG_PM
static int
e1000_resume(struct pci_dev *pdev)
{
@@ -4548,6 +4603,7 @@ e1000_resume(struct pci_dev *pdev)
retval = pci_set_power_state(pdev, PCI_D0);
if (retval)
DPRINTK(PROBE, ERR, Error in setting power state\n);
+ e1000_pci_restore_state(adapter);
ret_val = pci_enable_device(pdev);
pci_set_master(pdev);
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html