diff options
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r-- | drivers/net/forcedeth.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 2cb244763292..c980ce9719af 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 | /* |
@@ -5805,50 +5809,66 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5805 | { | 5809 | { |
5806 | struct net_device *dev = pci_get_drvdata(pdev); | 5810 | struct net_device *dev = pci_get_drvdata(pdev); |
5807 | struct fe_priv *np = netdev_priv(dev); | 5811 | struct fe_priv *np = netdev_priv(dev); |
5812 | u8 __iomem *base = get_hwbase(dev); | ||
5813 | int i; | ||
5808 | 5814 | ||
5809 | if (!netif_running(dev)) | 5815 | if (netif_running(dev)) { |
5810 | goto out; | 5816 | // Gross. |
5811 | 5817 | nv_close(dev); | |
5818 | } | ||
5812 | netif_device_detach(dev); | 5819 | netif_device_detach(dev); |
5813 | 5820 | ||
5814 | // Gross. | 5821 | /* save non-pci configuration space */ |
5815 | nv_close(dev); | 5822 | for (i = 0;i <= np->register_size/sizeof(u32); i++) |
5823 | np->saved_config_space[i] = readl(base + i*sizeof(u32)); | ||
5816 | 5824 | ||
5817 | pci_save_state(pdev); | 5825 | pci_save_state(pdev); |
5818 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); | 5826 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); |
5827 | pci_disable_device(pdev); | ||
5819 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 5828 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
5820 | out: | ||
5821 | return 0; | 5829 | return 0; |
5822 | } | 5830 | } |
5823 | 5831 | ||
5824 | static int nv_resume(struct pci_dev *pdev) | 5832 | static int nv_resume(struct pci_dev *pdev) |
5825 | { | 5833 | { |
5826 | struct net_device *dev = pci_get_drvdata(pdev); | 5834 | struct net_device *dev = pci_get_drvdata(pdev); |
5835 | struct fe_priv *np = netdev_priv(dev); | ||
5827 | u8 __iomem *base = get_hwbase(dev); | 5836 | u8 __iomem *base = get_hwbase(dev); |
5828 | int rc = 0; | 5837 | int i, rc = 0; |
5829 | u32 txreg; | ||
5830 | |||
5831 | if (!netif_running(dev)) | ||
5832 | goto out; | ||
5833 | |||
5834 | netif_device_attach(dev); | ||
5835 | 5838 | ||
5836 | pci_set_power_state(pdev, PCI_D0); | 5839 | pci_set_power_state(pdev, PCI_D0); |
5837 | pci_restore_state(pdev); | 5840 | pci_restore_state(pdev); |
5841 | /* ack any pending wake events, disable PME */ | ||
5838 | pci_enable_wake(pdev, PCI_D0, 0); | 5842 | pci_enable_wake(pdev, PCI_D0, 0); |
5839 | 5843 | ||
5840 | /* restore mac address reverse flag */ | 5844 | /* restore non-pci configuration space */ |
5841 | txreg = readl(base + NvRegTransmitPoll); | 5845 | for (i = 0;i <= np->register_size/sizeof(u32); i++) |
5842 | txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV; | 5846 | writel(np->saved_config_space[i], base+i*sizeof(u32)); |
5843 | writel(txreg, base + NvRegTransmitPoll); | ||
5844 | 5847 | ||
5845 | rc = nv_open(dev); | 5848 | netif_device_attach(dev); |
5846 | nv_set_multicast(dev); | 5849 | if (netif_running(dev)) { |
5847 | out: | 5850 | rc = nv_open(dev); |
5851 | nv_set_multicast(dev); | ||
5852 | } | ||
5848 | return rc; | 5853 | return rc; |
5849 | } | 5854 | } |
5855 | |||
5856 | static void nv_shutdown(struct pci_dev *pdev) | ||
5857 | { | ||
5858 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5859 | struct fe_priv *np = netdev_priv(dev); | ||
5860 | |||
5861 | if (netif_running(dev)) | ||
5862 | nv_close(dev); | ||
5863 | |||
5864 | pci_enable_wake(pdev, PCI_D3hot, np->wolenabled); | ||
5865 | pci_enable_wake(pdev, PCI_D3cold, np->wolenabled); | ||
5866 | pci_disable_device(pdev); | ||
5867 | pci_set_power_state(pdev, PCI_D3hot); | ||
5868 | } | ||
5850 | #else | 5869 | #else |
5851 | #define nv_suspend NULL | 5870 | #define nv_suspend NULL |
5871 | #define nv_shutdown NULL | ||
5852 | #define nv_resume NULL | 5872 | #define nv_resume NULL |
5853 | #endif /* CONFIG_PM */ | 5873 | #endif /* CONFIG_PM */ |
5854 | 5874 | ||
@@ -6019,6 +6039,7 @@ static struct pci_driver driver = { | |||
6019 | .remove = __devexit_p(nv_remove), | 6039 | .remove = __devexit_p(nv_remove), |
6020 | .suspend = nv_suspend, | 6040 | .suspend = nv_suspend, |
6021 | .resume = nv_resume, | 6041 | .resume = nv_resume, |
6042 | .shutdown = nv_shutdown, | ||
6022 | }; | 6043 | }; |
6023 | 6044 | ||
6024 | static int __init init_nic(void) | 6045 | static int __init init_nic(void) |