diff options
author | Jiri Kosina <jkosina@suse.cz> | 2008-07-23 09:19:00 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-07-23 09:19:00 -0400 |
commit | 9063974cdbc5463528cb6aa60c91bc0267af7bbb (patch) | |
tree | 1dffc62d8b79b3d89459cf23aa59c553e186840a /drivers/net/forcedeth.c | |
parent | d6d6a86e14a6b5a26c785b45268874a8f7a52b4d (diff) | |
parent | c010b2f76c3032e48097a6eef291d8593d5d79a6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r-- | drivers/net/forcedeth.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 2cb244763292..4ed89fa9ae46 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 | /* |
@@ -2827,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
2827 | */ | 2831 | */ |
2828 | nv_disable_irq(dev); | 2832 | nv_disable_irq(dev); |
2829 | netif_tx_lock_bh(dev); | 2833 | netif_tx_lock_bh(dev); |
2834 | netif_addr_lock(dev); | ||
2830 | spin_lock(&np->lock); | 2835 | spin_lock(&np->lock); |
2831 | /* stop engines */ | 2836 | /* stop engines */ |
2832 | nv_stop_rxtx(dev); | 2837 | nv_stop_rxtx(dev); |
@@ -2851,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
2851 | /* restart rx engine */ | 2856 | /* restart rx engine */ |
2852 | nv_start_rxtx(dev); | 2857 | nv_start_rxtx(dev); |
2853 | spin_unlock(&np->lock); | 2858 | spin_unlock(&np->lock); |
2859 | netif_addr_unlock(dev); | ||
2854 | netif_tx_unlock_bh(dev); | 2860 | netif_tx_unlock_bh(dev); |
2855 | nv_enable_irq(dev); | 2861 | nv_enable_irq(dev); |
2856 | } | 2862 | } |
@@ -2887,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) | |||
2887 | 2893 | ||
2888 | if (netif_running(dev)) { | 2894 | if (netif_running(dev)) { |
2889 | netif_tx_lock_bh(dev); | 2895 | netif_tx_lock_bh(dev); |
2896 | netif_addr_lock(dev); | ||
2890 | spin_lock_irq(&np->lock); | 2897 | spin_lock_irq(&np->lock); |
2891 | 2898 | ||
2892 | /* stop rx engine */ | 2899 | /* stop rx engine */ |
@@ -2898,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) | |||
2898 | /* restart rx engine */ | 2905 | /* restart rx engine */ |
2899 | nv_start_rx(dev); | 2906 | nv_start_rx(dev); |
2900 | spin_unlock_irq(&np->lock); | 2907 | spin_unlock_irq(&np->lock); |
2908 | netif_addr_unlock(dev); | ||
2901 | netif_tx_unlock_bh(dev); | 2909 | netif_tx_unlock_bh(dev); |
2902 | } else { | 2910 | } else { |
2903 | nv_copy_mac_to_hw(dev); | 2911 | nv_copy_mac_to_hw(dev); |
@@ -3967,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
3967 | printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); | 3975 | printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); |
3968 | if (netif_running(dev)) { | 3976 | if (netif_running(dev)) { |
3969 | netif_tx_lock_bh(dev); | 3977 | netif_tx_lock_bh(dev); |
3978 | netif_addr_lock(dev); | ||
3970 | spin_lock(&np->lock); | 3979 | spin_lock(&np->lock); |
3971 | /* stop engines */ | 3980 | /* stop engines */ |
3972 | nv_stop_rxtx(dev); | 3981 | nv_stop_rxtx(dev); |
@@ -3991,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
3991 | /* restart rx engine */ | 4000 | /* restart rx engine */ |
3992 | nv_start_rxtx(dev); | 4001 | nv_start_rxtx(dev); |
3993 | spin_unlock(&np->lock); | 4002 | spin_unlock(&np->lock); |
4003 | netif_addr_unlock(dev); | ||
3994 | netif_tx_unlock_bh(dev); | 4004 | netif_tx_unlock_bh(dev); |
3995 | } | 4005 | } |
3996 | } | 4006 | } |
@@ -4194,12 +4204,25 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
4194 | 4204 | ||
4195 | netif_carrier_off(dev); | 4205 | netif_carrier_off(dev); |
4196 | if (netif_running(dev)) { | 4206 | if (netif_running(dev)) { |
4207 | unsigned long flags; | ||
4208 | |||
4197 | nv_disable_irq(dev); | 4209 | nv_disable_irq(dev); |
4198 | netif_tx_lock_bh(dev); | 4210 | netif_tx_lock_bh(dev); |
4199 | spin_lock(&np->lock); | 4211 | netif_addr_lock(dev); |
4212 | /* with plain spinlock lockdep complains */ | ||
4213 | spin_lock_irqsave(&np->lock, flags); | ||
4200 | /* stop engines */ | 4214 | /* stop engines */ |
4215 | /* FIXME: | ||
4216 | * this can take some time, and interrupts are disabled | ||
4217 | * due to spin_lock_irqsave, but let's hope no daemon | ||
4218 | * is going to change the settings very often... | ||
4219 | * Worst case: | ||
4220 | * NV_RXSTOP_DELAY1MAX + NV_TXSTOP_DELAY1MAX | ||
4221 | * + some minor delays, which is up to a second approximately | ||
4222 | */ | ||
4201 | nv_stop_rxtx(dev); | 4223 | nv_stop_rxtx(dev); |
4202 | spin_unlock(&np->lock); | 4224 | spin_unlock_irqrestore(&np->lock, flags); |
4225 | netif_addr_unlock(dev); | ||
4203 | netif_tx_unlock_bh(dev); | 4226 | netif_tx_unlock_bh(dev); |
4204 | } | 4227 | } |
4205 | 4228 | ||
@@ -4345,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev) | |||
4345 | if (netif_running(dev)) { | 4368 | if (netif_running(dev)) { |
4346 | nv_disable_irq(dev); | 4369 | nv_disable_irq(dev); |
4347 | netif_tx_lock_bh(dev); | 4370 | netif_tx_lock_bh(dev); |
4371 | netif_addr_lock(dev); | ||
4348 | spin_lock(&np->lock); | 4372 | spin_lock(&np->lock); |
4349 | /* stop engines */ | 4373 | /* stop engines */ |
4350 | nv_stop_rxtx(dev); | 4374 | nv_stop_rxtx(dev); |
4351 | spin_unlock(&np->lock); | 4375 | spin_unlock(&np->lock); |
4376 | netif_addr_unlock(dev); | ||
4352 | netif_tx_unlock_bh(dev); | 4377 | netif_tx_unlock_bh(dev); |
4353 | printk(KERN_INFO "%s: link down.\n", dev->name); | 4378 | printk(KERN_INFO "%s: link down.\n", dev->name); |
4354 | } | 4379 | } |
@@ -4456,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri | |||
4456 | if (netif_running(dev)) { | 4481 | if (netif_running(dev)) { |
4457 | nv_disable_irq(dev); | 4482 | nv_disable_irq(dev); |
4458 | netif_tx_lock_bh(dev); | 4483 | netif_tx_lock_bh(dev); |
4484 | netif_addr_lock(dev); | ||
4459 | spin_lock(&np->lock); | 4485 | spin_lock(&np->lock); |
4460 | /* stop engines */ | 4486 | /* stop engines */ |
4461 | nv_stop_rxtx(dev); | 4487 | nv_stop_rxtx(dev); |
@@ -4504,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri | |||
4504 | /* restart engines */ | 4530 | /* restart engines */ |
4505 | nv_start_rxtx(dev); | 4531 | nv_start_rxtx(dev); |
4506 | spin_unlock(&np->lock); | 4532 | spin_unlock(&np->lock); |
4533 | netif_addr_unlock(dev); | ||
4507 | netif_tx_unlock_bh(dev); | 4534 | netif_tx_unlock_bh(dev); |
4508 | nv_enable_irq(dev); | 4535 | nv_enable_irq(dev); |
4509 | } | 4536 | } |
@@ -4541,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* | |||
4541 | if (netif_running(dev)) { | 4568 | if (netif_running(dev)) { |
4542 | nv_disable_irq(dev); | 4569 | nv_disable_irq(dev); |
4543 | netif_tx_lock_bh(dev); | 4570 | netif_tx_lock_bh(dev); |
4571 | netif_addr_lock(dev); | ||
4544 | spin_lock(&np->lock); | 4572 | spin_lock(&np->lock); |
4545 | /* stop engines */ | 4573 | /* stop engines */ |
4546 | nv_stop_rxtx(dev); | 4574 | nv_stop_rxtx(dev); |
4547 | spin_unlock(&np->lock); | 4575 | spin_unlock(&np->lock); |
4576 | netif_addr_unlock(dev); | ||
4548 | netif_tx_unlock_bh(dev); | 4577 | netif_tx_unlock_bh(dev); |
4549 | } | 4578 | } |
4550 | 4579 | ||
@@ -4931,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 | |||
4931 | napi_disable(&np->napi); | 4960 | napi_disable(&np->napi); |
4932 | #endif | 4961 | #endif |
4933 | netif_tx_lock_bh(dev); | 4962 | netif_tx_lock_bh(dev); |
4963 | netif_addr_lock(dev); | ||
4934 | spin_lock_irq(&np->lock); | 4964 | spin_lock_irq(&np->lock); |
4935 | nv_disable_hw_interrupts(dev, np->irqmask); | 4965 | nv_disable_hw_interrupts(dev, np->irqmask); |
4936 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { | 4966 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { |
@@ -4944,6 +4974,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 | |||
4944 | /* drain rx queue */ | 4974 | /* drain rx queue */ |
4945 | nv_drain_rxtx(dev); | 4975 | nv_drain_rxtx(dev); |
4946 | spin_unlock_irq(&np->lock); | 4976 | spin_unlock_irq(&np->lock); |
4977 | netif_addr_unlock(dev); | ||
4947 | netif_tx_unlock_bh(dev); | 4978 | netif_tx_unlock_bh(dev); |
4948 | } | 4979 | } |
4949 | 4980 | ||
@@ -5555,6 +5586,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5555 | /* set mac address */ | 5586 | /* set mac address */ |
5556 | nv_copy_mac_to_hw(dev); | 5587 | nv_copy_mac_to_hw(dev); |
5557 | 5588 | ||
5589 | /* Workaround current PCI init glitch: wakeup bits aren't | ||
5590 | * being set from PCI PM capability. | ||
5591 | */ | ||
5592 | device_init_wakeup(&pci_dev->dev, 1); | ||
5593 | |||
5558 | /* disable WOL */ | 5594 | /* disable WOL */ |
5559 | writel(0, base + NvRegWakeUpFlags); | 5595 | writel(0, base + NvRegWakeUpFlags); |
5560 | np->wolenabled = 0; | 5596 | np->wolenabled = 0; |
@@ -5805,50 +5841,66 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5805 | { | 5841 | { |
5806 | struct net_device *dev = pci_get_drvdata(pdev); | 5842 | struct net_device *dev = pci_get_drvdata(pdev); |
5807 | struct fe_priv *np = netdev_priv(dev); | 5843 | struct fe_priv *np = netdev_priv(dev); |
5844 | u8 __iomem *base = get_hwbase(dev); | ||
5845 | int i; | ||
5808 | 5846 | ||
5809 | if (!netif_running(dev)) | 5847 | if (netif_running(dev)) { |
5810 | goto out; | 5848 | // Gross. |
5811 | 5849 | nv_close(dev); | |
5850 | } | ||
5812 | netif_device_detach(dev); | 5851 | netif_device_detach(dev); |
5813 | 5852 | ||
5814 | // Gross. | 5853 | /* save non-pci configuration space */ |
5815 | nv_close(dev); | 5854 | for (i = 0;i <= np->register_size/sizeof(u32); i++) |
5855 | np->saved_config_space[i] = readl(base + i*sizeof(u32)); | ||
5816 | 5856 | ||
5817 | pci_save_state(pdev); | 5857 | pci_save_state(pdev); |
5818 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); | 5858 | pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled); |
5859 | pci_disable_device(pdev); | ||
5819 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 5860 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
5820 | out: | ||
5821 | return 0; | 5861 | return 0; |
5822 | } | 5862 | } |
5823 | 5863 | ||
5824 | static int nv_resume(struct pci_dev *pdev) | 5864 | static int nv_resume(struct pci_dev *pdev) |
5825 | { | 5865 | { |
5826 | struct net_device *dev = pci_get_drvdata(pdev); | 5866 | struct net_device *dev = pci_get_drvdata(pdev); |
5867 | struct fe_priv *np = netdev_priv(dev); | ||
5827 | u8 __iomem *base = get_hwbase(dev); | 5868 | u8 __iomem *base = get_hwbase(dev); |
5828 | int rc = 0; | 5869 | int i, rc = 0; |
5829 | u32 txreg; | ||
5830 | |||
5831 | if (!netif_running(dev)) | ||
5832 | goto out; | ||
5833 | |||
5834 | netif_device_attach(dev); | ||
5835 | 5870 | ||
5836 | pci_set_power_state(pdev, PCI_D0); | 5871 | pci_set_power_state(pdev, PCI_D0); |
5837 | pci_restore_state(pdev); | 5872 | pci_restore_state(pdev); |
5873 | /* ack any pending wake events, disable PME */ | ||
5838 | pci_enable_wake(pdev, PCI_D0, 0); | 5874 | pci_enable_wake(pdev, PCI_D0, 0); |
5839 | 5875 | ||
5840 | /* restore mac address reverse flag */ | 5876 | /* restore non-pci configuration space */ |
5841 | txreg = readl(base + NvRegTransmitPoll); | 5877 | for (i = 0;i <= np->register_size/sizeof(u32); i++) |
5842 | txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV; | 5878 | writel(np->saved_config_space[i], base+i*sizeof(u32)); |
5843 | writel(txreg, base + NvRegTransmitPoll); | ||
5844 | 5879 | ||
5845 | rc = nv_open(dev); | 5880 | netif_device_attach(dev); |
5846 | nv_set_multicast(dev); | 5881 | if (netif_running(dev)) { |
5847 | out: | 5882 | rc = nv_open(dev); |
5883 | nv_set_multicast(dev); | ||
5884 | } | ||
5848 | return rc; | 5885 | return rc; |
5849 | } | 5886 | } |
5887 | |||
5888 | static void nv_shutdown(struct pci_dev *pdev) | ||
5889 | { | ||
5890 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5891 | struct fe_priv *np = netdev_priv(dev); | ||
5892 | |||
5893 | if (netif_running(dev)) | ||
5894 | nv_close(dev); | ||
5895 | |||
5896 | pci_enable_wake(pdev, PCI_D3hot, np->wolenabled); | ||
5897 | pci_enable_wake(pdev, PCI_D3cold, np->wolenabled); | ||
5898 | pci_disable_device(pdev); | ||
5899 | pci_set_power_state(pdev, PCI_D3hot); | ||
5900 | } | ||
5850 | #else | 5901 | #else |
5851 | #define nv_suspend NULL | 5902 | #define nv_suspend NULL |
5903 | #define nv_shutdown NULL | ||
5852 | #define nv_resume NULL | 5904 | #define nv_resume NULL |
5853 | #endif /* CONFIG_PM */ | 5905 | #endif /* CONFIG_PM */ |
5854 | 5906 | ||
@@ -6019,6 +6071,7 @@ static struct pci_driver driver = { | |||
6019 | .remove = __devexit_p(nv_remove), | 6071 | .remove = __devexit_p(nv_remove), |
6020 | .suspend = nv_suspend, | 6072 | .suspend = nv_suspend, |
6021 | .resume = nv_resume, | 6073 | .resume = nv_resume, |
6074 | .shutdown = nv_shutdown, | ||
6022 | }; | 6075 | }; |
6023 | 6076 | ||
6024 | static int __init init_nic(void) | 6077 | static int __init init_nic(void) |