aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2008-07-23 09:19:00 -0400
committerJiri Kosina <jkosina@suse.cz>2008-07-23 09:19:00 -0400
commit9063974cdbc5463528cb6aa60c91bc0267af7bbb (patch)
tree1dffc62d8b79b3d89459cf23aa59c553e186840a /drivers/net/forcedeth.c
parentd6d6a86e14a6b5a26c785b45268874a8f7a52b4d (diff)
parentc010b2f76c3032e48097a6eef291d8593d5d79a6 (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.c97
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));
5820out:
5821 return 0; 5861 return 0;
5822} 5862}
5823 5863
5824static int nv_resume(struct pci_dev *pdev) 5864static 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)) {
5847out: 5882 rc = nv_open(dev);
5883 nv_set_multicast(dev);
5884 }
5848 return rc; 5885 return rc;
5849} 5886}
5887
5888static 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
6024static int __init init_nic(void) 6077static int __init init_nic(void)