Skip to content

Commit

Permalink
[PATCH] e1000: Added functions to save and restore config
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jesse Brandeburg authored and Jeff Garzik committed Jan 18, 2006
1 parent b92ff8e commit 2f82665
Showing 1 changed file with 58 additions and 2 deletions.
60 changes: 58 additions & 2 deletions drivers/net/e1000/e1000_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4437,6 +4437,54 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
}

#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)
{
Expand All @@ -4451,6 +4499,14 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
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;
Expand Down Expand Up @@ -4507,8 +4563,6 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
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);
Expand Down Expand Up @@ -4537,6 +4591,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}

#ifdef CONFIG_PM
static int
e1000_resume(struct pci_dev *pdev)
{
Expand All @@ -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);

Expand Down

0 comments on commit 2f82665

Please sign in to comment.