Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f82665f authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Garzik
Browse files

[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: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJohn Ronciak <john.ronciak@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent b92ff8ee
Loading
Loading
Loading
Loading
+58 −2
Original line number Diff line number Diff line
@@ -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)
{
@@ -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;
@@ -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);
@@ -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)
{
@@ -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);