[netdrvr] forcedeth: save/restore device configuration space
authorTobias Diedrich <ranma+kernel@tdiedrich.de>
Sun, 18 May 2008 13:03:44 +0000 (15:03 +0200)
committerJeff Garzik <jgarzik@redhat.com>
Sat, 31 May 2008 02:19:00 +0000 (22:19 -0400)
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>
drivers/net/forcedeth.c

index 215d27bbeffe8924db96cc9d766f3e19afe8b370..a5650ed4d481e742896fc61f001c8c865b01a799 100644 (file)
@@ -426,6 +426,7 @@ union ring_type {
 #define NV_PCI_REGSZ_VER1              0x270
 #define NV_PCI_REGSZ_VER2              0x2d4
 #define NV_PCI_REGSZ_VER3              0x604
+#define NV_PCI_REGSZ_MAX               0x604
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY    4
@@ -784,6 +785,9 @@ struct fe_priv {
 
        /* flow control */
        u32 pause_flags;
+
+       /* power saved state */
+       u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
 };
 
 /*
@@ -5785,6 +5789,8 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct fe_priv *np = netdev_priv(dev);
+       u8 __iomem *base = get_hwbase(dev);
+       int i;
 
        if (!netif_running(dev))
                goto out;
@@ -5794,6 +5800,10 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state)
        // Gross.
        nv_close(dev);
 
+       /* save non-pci configuration space */
+       for (i = 0;i <= np->register_size/sizeof(u32); i++)
+               np->saved_config_space[i] = readl(base + i*sizeof(u32));
+
        pci_save_state(pdev);
        pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled);
        pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -5804,9 +5814,9 @@ out:
 static int nv_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
+       struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
-       int rc = 0;
-       u32 txreg;
+       int i, rc = 0;
 
        if (!netif_running(dev))
                goto out;
@@ -5817,10 +5827,9 @@ static int nv_resume(struct pci_dev *pdev)
        pci_restore_state(pdev);
        pci_enable_wake(pdev, PCI_D0, 0);
 
-       /* restore mac address reverse flag */
-       txreg = readl(base + NvRegTransmitPoll);
-       txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV;
-       writel(txreg, base + NvRegTransmitPoll);
+       /* restore non-pci configuration space */
+       for (i = 0;i <= np->register_size/sizeof(u32); i++)
+               writel(np->saved_config_space[i], base+i*sizeof(u32));
 
        rc = nv_open(dev);
        nv_set_multicast(dev);