diff options
author | Tobias Diedrich <ranma+kernel@tdiedrich.de> | 2008-05-18 09:03:44 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-30 22:19:00 -0400 |
commit | 1a1ca86158eee303af5270338695f90bc7ae02b3 (patch) | |
tree | 424678c18134e5355bdb558519f45b35e2dbda73 /drivers/net/forcedeth.c | |
parent | f735a2a1a4f2a0f5cd823ce323e82675990469e2 (diff) |
[netdrvr] forcedeth: save/restore device configuration space
The memory mapped device configuration space is lost during hibernate.
Save and restore it (fixes 'swapped mac' problem).
Signed-off-by: TTobias Diedrich <ranma+kernel@tdiedrich.de>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r-- | drivers/net/forcedeth.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 215d27bbeffe..a5650ed4d481 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -426,6 +426,7 @@ union ring_type { | |||
426 | #define NV_PCI_REGSZ_VER1 0x270 | 426 | #define NV_PCI_REGSZ_VER1 0x270 |
427 | #define NV_PCI_REGSZ_VER2 0x2d4 | 427 | #define NV_PCI_REGSZ_VER2 0x2d4 |
428 | #define NV_PCI_REGSZ_VER3 0x604 | 428 | #define NV_PCI_REGSZ_VER3 0x604 |
429 | #define NV_PCI_REGSZ_MAX 0x604 | ||
429 | 430 | ||
430 | /* various timeout delays: all in usec */ | 431 | /* various timeout delays: all in usec */ |
431 | #define NV_TXRX_RESET_DELAY 4 | 432 | #define NV_TXRX_RESET_DELAY 4 |
@@ -784,6 +785,9 @@ struct fe_priv { | |||
784 | 785 | ||
785 | /* flow control */ | 786 | /* flow control */ |
786 | u32 pause_flags; | 787 | u32 pause_flags; |
788 | |||
789 | /* power saved state */ | ||
790 | u32 saved_config_space[NV_PCI_REGSZ_MAX/4]; | ||
787 | }; | 791 | }; |
788 | 792 | ||
789 | /* | 793 | /* |
@@ -5785,6 +5789,8 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5785 | { | 5789 | { |
5786 | struct net_device *dev = pci_get_drvdata(pdev); | 5790 | struct net_device *dev = pci_get_drvdata(pdev); |
5787 | struct fe_priv *np = netdev_priv(dev); | 5791 | struct fe_priv *np = netdev_priv(dev); |
5792 | u8 __iomem *base = get_hwbase(dev); | ||
5793 | int i; | ||
5788 | 5794 | ||
5789 | if (!netif_running(dev)) | 5795 | if (!netif_running(dev)) |
5790 | goto out; | 5796 | goto out; |
@@ -5794,6 +5800,10 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5794 | // Gross. | 5800 | // Gross. |
5795 | nv_close(dev); | 5801 | nv_close(dev); |
5796 | 5802 | ||
5803 | /* save non-pci configuration space */ | ||
5804 | for (i = 0;i <= np->register_size/sizeof(u32); i++) | ||
5805 | np->saved_config_space[i] = readl(base + i*sizeof(u32)); | ||
5806 | |||
5797 | pci_save_state(pdev); | 5807 | pci_save_state(pdev); |
5798 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); | 5808 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); |
5799 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 5809 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
@@ -5804,9 +5814,9 @@ out: | |||
5804 | static int nv_resume(struct pci_dev *pdev) | 5814 | static int nv_resume(struct pci_dev *pdev) |
5805 | { | 5815 | { |
5806 | struct net_device *dev = pci_get_drvdata(pdev); | 5816 | struct net_device *dev = pci_get_drvdata(pdev); |
5817 | struct fe_priv *np = netdev_priv(dev); | ||
5807 | u8 __iomem *base = get_hwbase(dev); | 5818 | u8 __iomem *base = get_hwbase(dev); |
5808 | int rc = 0; | 5819 | int i, rc = 0; |
5809 | u32 txreg; | ||
5810 | 5820 | ||
5811 | if (!netif_running(dev)) | 5821 | if (!netif_running(dev)) |
5812 | goto out; | 5822 | goto out; |
@@ -5817,10 +5827,9 @@ static int nv_resume(struct pci_dev *pdev) | |||
5817 | pci_restore_state(pdev); | 5827 | pci_restore_state(pdev); |
5818 | pci_enable_wake(pdev, PCI_D0, 0); | 5828 | pci_enable_wake(pdev, PCI_D0, 0); |
5819 | 5829 | ||
5820 | /* restore mac address reverse flag */ | 5830 | /* restore non-pci configuration space */ |
5821 | txreg = readl(base + NvRegTransmitPoll); | 5831 | for (i = 0;i <= np->register_size/sizeof(u32); i++) |
5822 | txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV; | 5832 | writel(np->saved_config_space[i], base+i*sizeof(u32)); |
5823 | writel(txreg, base + NvRegTransmitPoll); | ||
5824 | 5833 | ||
5825 | rc = nv_open(dev); | 5834 | rc = nv_open(dev); |
5826 | nv_set_multicast(dev); | 5835 | nv_set_multicast(dev); |