aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c61
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));
5820out:
5821 return 0; 5829 return 0;
5822} 5830}
5823 5831
5824static int nv_resume(struct pci_dev *pdev) 5832static 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)) {
5847out: 5850 rc = nv_open(dev);
5851 nv_set_multicast(dev);
5852 }
5848 return rc; 5853 return rc;
5849} 5854}
5855
5856static 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
6024static int __init init_nic(void) 6045static int __init init_nic(void)