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/net/e1000 | |
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/net/e1000')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 114 |
1 files changed, 113 insertions, 1 deletions
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 */ |