aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2006-06-08 12:30:24 -0400
committerAuke Kok <juke-jan.h.kok@intel.com>2006-06-08 12:30:24 -0400
commit9026729bfeb4329a4edc01f427f01af7ee0a5273 (patch)
tree956f921b9511b87da6337a9f169b4b5d14590fc6 /drivers/net
parent2cc304923d87403abc103a741382b9af08b6decc (diff)
e1000: add PCI Error Recovery
Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel gigabit ethernet e1000 device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas <linas@linas.org> Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/e1000/e1000_main.c114
1 files changed, 113 insertions, 1 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index bd709e562778..564fab4914e1 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);
189static void e1000_netpoll (struct net_device *netdev); 189static void e1000_netpoll (struct net_device *netdev);
190#endif 190#endif
191 191
192static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
193 pci_channel_state_t state);
194static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
195static void e1000_io_resume(struct pci_dev *pdev);
196
197static 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
193static struct pci_driver e1000_driver = { 203static 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
206MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); 217MODULE_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,
@@ -4594,4 +4609,101 @@ e1000_netpoll(struct net_device *netdev)
4594} 4609}
4595#endif 4610#endif
4596 4611
4612/**
4613 * e1000_io_error_detected - called when PCI error is detected
4614 * @pdev: Pointer to PCI device
4615 * @state: The current pci conneection state
4616 *
4617 * This function is called after a PCI bus error affecting
4618 * this device has been detected.
4619 */
4620static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
4621{
4622 struct net_device *netdev = pci_get_drvdata(pdev);
4623 struct e1000_adapter *adapter = netdev->priv;
4624
4625 netif_device_detach(netdev);
4626
4627 if (netif_running(netdev))
4628 e1000_down(adapter);
4629
4630 /* Request a slot slot reset. */
4631 return PCI_ERS_RESULT_NEED_RESET;
4632}
4633
4634/**
4635 * e1000_io_slot_reset - called after the pci bus has been reset.
4636 * @pdev: Pointer to PCI device
4637 *
4638 * Restart the card from scratch, as if from a cold-boot. Implementation
4639 * resembles the first-half of the e1000_resume routine.
4640 */
4641static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4642{
4643 struct net_device *netdev = pci_get_drvdata(pdev);
4644 struct e1000_adapter *adapter = netdev->priv;
4645
4646 if (pci_enable_device(pdev)) {
4647 printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
4648 return PCI_ERS_RESULT_DISCONNECT;
4649 }
4650 pci_set_master(pdev);
4651
4652 pci_enable_wake(pdev, 3, 0);
4653 pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
4654
4655 /* Perform card reset only on one instance of the card */
4656 if (PCI_FUNC (pdev->devfn) != 0)
4657 return PCI_ERS_RESULT_RECOVERED;
4658
4659 e1000_reset(adapter);
4660 E1000_WRITE_REG(&adapter->hw, WUS, ~0);
4661
4662 return PCI_ERS_RESULT_RECOVERED;
4663}
4664
4665/**
4666 * e1000_io_resume - called when traffic can start flowing again.
4667 * @pdev: Pointer to PCI device
4668 *
4669 * This callback is called when the error recovery driver tells us that
4670 * its OK to resume normal operation. Implementation resembles the
4671 * second-half of the e1000_resume routine.
4672 */
4673static void e1000_io_resume(struct pci_dev *pdev)
4674{
4675 struct net_device *netdev = pci_get_drvdata(pdev);
4676 struct e1000_adapter *adapter = netdev->priv;
4677 uint32_t manc, swsm;
4678
4679 if (netif_running(netdev)) {
4680 if (e1000_up(adapter)) {
4681 printk("e1000: can't bring device back up after reset\n");
4682 return;
4683 }
4684 }
4685
4686 netif_device_attach(netdev);
4687
4688 if (adapter->hw.mac_type >= e1000_82540 &&
4689 adapter->hw.media_type == e1000_media_type_copper) {
4690 manc = E1000_READ_REG(&adapter->hw, MANC);
4691 manc &= ~(E1000_MANC_ARP_EN);
4692 E1000_WRITE_REG(&adapter->hw, MANC, manc);
4693 }
4694
4695 switch (adapter->hw.mac_type) {
4696 case e1000_82573:
4697 swsm = E1000_READ_REG(&adapter->hw, SWSM);
4698 E1000_WRITE_REG(&adapter->hw, SWSM,
4699 swsm | E1000_SWSM_DRV_LOAD);
4700 break;
4701 default:
4702 break;
4703 }
4704
4705 if (netif_running(netdev))
4706 mod_timer(&adapter->watchdog_timer, jiffies);
4707}
4708
4597/* e1000_main.c */ 4709/* e1000_main.c */