aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-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 */