diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-06-08 15:56:17 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-06-08 15:56:17 -0400 |
commit | cac925a4aab1b7233d3beb591f53498816058a08 (patch) | |
tree | a800537068aa05fd426ff44b8efd52d66e6d2051 /drivers | |
parent | bcd618e4eac6fbf82de05d23c15ecb694c62b8af (diff) | |
parent | 6224e01dccf2543a8f8b4d825baf1510c79c2878 (diff) |
Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into tmp
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e100.c | 75 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 114 |
2 files changed, 188 insertions, 1 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 31ac001f5517..f37170cc1a37 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2780,6 +2780,80 @@ static void e100_shutdown(struct pci_dev *pdev) | |||
2780 | DPRINTK(PROBE,ERR, "Error enabling wake\n"); | 2780 | DPRINTK(PROBE,ERR, "Error enabling wake\n"); |
2781 | } | 2781 | } |
2782 | 2782 | ||
2783 | /* ------------------ PCI Error Recovery infrastructure -------------- */ | ||
2784 | /** | ||
2785 | * e100_io_error_detected - called when PCI error is detected. | ||
2786 | * @pdev: Pointer to PCI device | ||
2787 | * @state: The current pci conneection state | ||
2788 | */ | ||
2789 | static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | ||
2790 | { | ||
2791 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
2792 | |||
2793 | /* Similar to calling e100_down(), but avoids adpater I/O. */ | ||
2794 | netdev->stop(netdev); | ||
2795 | |||
2796 | /* Detach; put netif into state similar to hotplug unplug. */ | ||
2797 | netif_poll_enable(netdev); | ||
2798 | netif_device_detach(netdev); | ||
2799 | |||
2800 | /* Request a slot reset. */ | ||
2801 | return PCI_ERS_RESULT_NEED_RESET; | ||
2802 | } | ||
2803 | |||
2804 | /** | ||
2805 | * e100_io_slot_reset - called after the pci bus has been reset. | ||
2806 | * @pdev: Pointer to PCI device | ||
2807 | * | ||
2808 | * Restart the card from scratch. | ||
2809 | */ | ||
2810 | static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev) | ||
2811 | { | ||
2812 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
2813 | struct nic *nic = netdev_priv(netdev); | ||
2814 | |||
2815 | if (pci_enable_device(pdev)) { | ||
2816 | printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n"); | ||
2817 | return PCI_ERS_RESULT_DISCONNECT; | ||
2818 | } | ||
2819 | pci_set_master(pdev); | ||
2820 | |||
2821 | /* Only one device per card can do a reset */ | ||
2822 | if (0 != PCI_FUNC(pdev->devfn)) | ||
2823 | return PCI_ERS_RESULT_RECOVERED; | ||
2824 | e100_hw_reset(nic); | ||
2825 | e100_phy_init(nic); | ||
2826 | |||
2827 | return PCI_ERS_RESULT_RECOVERED; | ||
2828 | } | ||
2829 | |||
2830 | /** | ||
2831 | * e100_io_resume - resume normal operations | ||
2832 | * @pdev: Pointer to PCI device | ||
2833 | * | ||
2834 | * Resume normal operations after an error recovery | ||
2835 | * sequence has been completed. | ||
2836 | */ | ||
2837 | static void e100_io_resume(struct pci_dev *pdev) | ||
2838 | { | ||
2839 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
2840 | struct nic *nic = netdev_priv(netdev); | ||
2841 | |||
2842 | /* ack any pending wake events, disable PME */ | ||
2843 | pci_enable_wake(pdev, 0, 0); | ||
2844 | |||
2845 | netif_device_attach(netdev); | ||
2846 | if (netif_running(netdev)) { | ||
2847 | e100_open(netdev); | ||
2848 | mod_timer(&nic->watchdog, jiffies); | ||
2849 | } | ||
2850 | } | ||
2851 | |||
2852 | static struct pci_error_handlers e100_err_handler = { | ||
2853 | .error_detected = e100_io_error_detected, | ||
2854 | .slot_reset = e100_io_slot_reset, | ||
2855 | .resume = e100_io_resume, | ||
2856 | }; | ||
2783 | 2857 | ||
2784 | static struct pci_driver e100_driver = { | 2858 | static struct pci_driver e100_driver = { |
2785 | .name = DRV_NAME, | 2859 | .name = DRV_NAME, |
@@ -2791,6 +2865,7 @@ static struct pci_driver e100_driver = { | |||
2791 | .resume = e100_resume, | 2865 | .resume = e100_resume, |
2792 | #endif | 2866 | #endif |
2793 | .shutdown = e100_shutdown, | 2867 | .shutdown = e100_shutdown, |
2868 | .err_handler = &e100_err_handler, | ||
2794 | }; | 2869 | }; |
2795 | 2870 | ||
2796 | static int __init e100_init_module(void) | 2871 | static int __init e100_init_module(void) |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 115eff25d8c1..56c7492e3e91 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -189,6 +189,16 @@ static void e1000_shutdown(struct pci_dev *pdev); | |||
189 | static void e1000_netpoll (struct net_device *netdev); | 189 | static void e1000_netpoll (struct net_device *netdev); |
190 | #endif | 190 | #endif |
191 | 191 | ||
192 | static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, | ||
193 | pci_channel_state_t state); | ||
194 | static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); | ||
195 | static void e1000_io_resume(struct pci_dev *pdev); | ||
196 | |||
197 | static struct pci_error_handlers e1000_err_handler = { | ||
198 | .error_detected = e1000_io_error_detected, | ||
199 | .slot_reset = e1000_io_slot_reset, | ||
200 | .resume = e1000_io_resume, | ||
201 | }; | ||
192 | 202 | ||
193 | static struct pci_driver e1000_driver = { | 203 | static struct pci_driver e1000_driver = { |
194 | .name = e1000_driver_name, | 204 | .name = e1000_driver_name, |
@@ -200,7 +210,8 @@ static struct pci_driver e1000_driver = { | |||
200 | .suspend = e1000_suspend, | 210 | .suspend = e1000_suspend, |
201 | .resume = e1000_resume, | 211 | .resume = e1000_resume, |
202 | #endif | 212 | #endif |
203 | .shutdown = e1000_shutdown | 213 | .shutdown = e1000_shutdown, |
214 | .err_handler = &e1000_err_handler | ||
204 | }; | 215 | }; |
205 | 216 | ||
206 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); | 217 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); |
@@ -3039,6 +3050,10 @@ e1000_update_stats(struct e1000_adapter *adapter) | |||
3039 | 3050 | ||
3040 | #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF | 3051 | #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF |
3041 | 3052 | ||
3053 | /* Prevent stats update while adapter is being reset */ | ||
3054 | if (adapter->link_speed == 0) | ||
3055 | return; | ||
3056 | |||
3042 | spin_lock_irqsave(&adapter->stats_lock, flags); | 3057 | spin_lock_irqsave(&adapter->stats_lock, flags); |
3043 | 3058 | ||
3044 | /* these counters are modified from e1000_adjust_tbi_stats, | 3059 | /* these counters are modified from e1000_adjust_tbi_stats, |
@@ -4590,4 +4605,101 @@ e1000_netpoll(struct net_device *netdev) | |||
4590 | } | 4605 | } |
4591 | #endif | 4606 | #endif |
4592 | 4607 | ||
4608 | /** | ||
4609 | * e1000_io_error_detected - called when PCI error is detected | ||
4610 | * @pdev: Pointer to PCI device | ||
4611 | * @state: The current pci conneection state | ||
4612 | * | ||
4613 | * This function is called after a PCI bus error affecting | ||
4614 | * this device has been detected. | ||
4615 | */ | ||
4616 | static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | ||
4617 | { | ||
4618 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
4619 | struct e1000_adapter *adapter = netdev->priv; | ||
4620 | |||
4621 | netif_device_detach(netdev); | ||
4622 | |||
4623 | if (netif_running(netdev)) | ||
4624 | e1000_down(adapter); | ||
4625 | |||
4626 | /* Request a slot slot reset. */ | ||
4627 | return PCI_ERS_RESULT_NEED_RESET; | ||
4628 | } | ||
4629 | |||
4630 | /** | ||
4631 | * e1000_io_slot_reset - called after the pci bus has been reset. | ||
4632 | * @pdev: Pointer to PCI device | ||
4633 | * | ||
4634 | * Restart the card from scratch, as if from a cold-boot. Implementation | ||
4635 | * resembles the first-half of the e1000_resume routine. | ||
4636 | */ | ||
4637 | static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) | ||
4638 | { | ||
4639 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
4640 | struct e1000_adapter *adapter = netdev->priv; | ||
4641 | |||
4642 | if (pci_enable_device(pdev)) { | ||
4643 | printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n"); | ||
4644 | return PCI_ERS_RESULT_DISCONNECT; | ||
4645 | } | ||
4646 | pci_set_master(pdev); | ||
4647 | |||
4648 | pci_enable_wake(pdev, 3, 0); | ||
4649 | pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ | ||
4650 | |||
4651 | /* Perform card reset only on one instance of the card */ | ||
4652 | if (PCI_FUNC (pdev->devfn) != 0) | ||
4653 | return PCI_ERS_RESULT_RECOVERED; | ||
4654 | |||
4655 | e1000_reset(adapter); | ||
4656 | E1000_WRITE_REG(&adapter->hw, WUS, ~0); | ||
4657 | |||
4658 | return PCI_ERS_RESULT_RECOVERED; | ||
4659 | } | ||
4660 | |||
4661 | /** | ||
4662 | * e1000_io_resume - called when traffic can start flowing again. | ||
4663 | * @pdev: Pointer to PCI device | ||
4664 | * | ||
4665 | * This callback is called when the error recovery driver tells us that | ||
4666 | * its OK to resume normal operation. Implementation resembles the | ||
4667 | * second-half of the e1000_resume routine. | ||
4668 | */ | ||
4669 | static void e1000_io_resume(struct pci_dev *pdev) | ||
4670 | { | ||
4671 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
4672 | struct e1000_adapter *adapter = netdev->priv; | ||
4673 | uint32_t manc, swsm; | ||
4674 | |||
4675 | if (netif_running(netdev)) { | ||
4676 | if (e1000_up(adapter)) { | ||
4677 | printk("e1000: can't bring device back up after reset\n"); | ||
4678 | return; | ||
4679 | } | ||
4680 | } | ||
4681 | |||
4682 | netif_device_attach(netdev); | ||
4683 | |||
4684 | if (adapter->hw.mac_type >= e1000_82540 && | ||
4685 | adapter->hw.media_type == e1000_media_type_copper) { | ||
4686 | manc = E1000_READ_REG(&adapter->hw, MANC); | ||
4687 | manc &= ~(E1000_MANC_ARP_EN); | ||
4688 | E1000_WRITE_REG(&adapter->hw, MANC, manc); | ||
4689 | } | ||
4690 | |||
4691 | switch (adapter->hw.mac_type) { | ||
4692 | case e1000_82573: | ||
4693 | swsm = E1000_READ_REG(&adapter->hw, SWSM); | ||
4694 | E1000_WRITE_REG(&adapter->hw, SWSM, | ||
4695 | swsm | E1000_SWSM_DRV_LOAD); | ||
4696 | break; | ||
4697 | default: | ||
4698 | break; | ||
4699 | } | ||
4700 | |||
4701 | if (netif_running(netdev)) | ||
4702 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
4703 | } | ||
4704 | |||
4593 | /* e1000_main.c */ | 4705 | /* e1000_main.c */ |