Here's the correspondig patch fo the e1000
--linas

> Hi,
> 
> The following patch to the e100 device driver is in the current
> 2.6.15-mm1 tree, and is being pushed to the mainline 2.6.15 tree.
> 
> I wrote this patch, and I believe I've cc'ed you on previous
> versions, but certainly not recently. Please review, comment,
> ACK or NAK as appropriate.
> 
> Background: Newer PCI controllers can detect and respond to
> serious PCI bus errors, typically by isolating the PCI slot
> (cutting off i/o to the failing card). An arch-specific
> framework can report these errors back to the device driver,
> and coordinate the recovery of the card. Detailed documentation
> for this is in the kernel tree, at Documentation/pci-error-recovery.txt
> 
> This patch adds the detection and recovery callbacks to the
> e100 driver. A version of this patch has been shipping as
> a part of SUSE SLES9 for about a year, and so has been
> tested in the field.
> 
> Similar patches to follow for the e1000 and the ixgb.
> 
> --linas

----- Forwarded message from Greg KH <[EMAIL PROTECTED]> -----

Subject: [PATCH] PCI Error Recovery: e1000 network device driver
To: [EMAIL PROTECTED]
From: Greg KH <[EMAIL PROTECTED]>

[PATCH] PCI Error Recovery: e1000 network device driver

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 <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>

---
commit 113cc803a20d72ee5e3c92302ac5a06e0c651d01
tree aae6aa3b20f14a36eba84867c2406cbe385affad
parent 5a02e3abf1e74c159deca91d6af01297379eede7
author linas <[EMAIL PROTECTED]> Fri, 18 Nov 2005 16:23:54 -0600
committer Greg Kroah-Hartman <[EMAIL PROTECTED]> Thu, 05 Jan 2006 21:54:55 -0800

 drivers/net/e1000/e1000_main.c |  101 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 438a931..76352fe 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -206,6 +206,16 @@ static void e1000_netpoll (struct net_de
 void e1000_rx_schedule(void *data);
 #endif
 
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, 
pci_channel_state_t state);
+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
+static void e1000_io_resume(struct pci_dev *pdev);
+
+static struct pci_error_handlers e1000_err_handler = {
+       .error_detected = e1000_io_error_detected,
+       .slot_reset = e1000_io_slot_reset,
+       .resume = e1000_io_resume,
+};
+
 /* Exported from other modules */
 
 extern void e1000_check_options(struct e1000_adapter *adapter);
@@ -218,8 +228,9 @@ static struct pci_driver e1000_driver = 
        /* Power Managment Hooks */
 #ifdef CONFIG_PM
        .suspend  = e1000_suspend,
-       .resume   = e1000_resume
+       .resume   = e1000_resume,
 #endif
+       .err_handler = &e1000_err_handler,
 };
 
 MODULE_AUTHOR("Intel Corporation, <[EMAIL PROTECTED]>");
@@ -2941,6 +2952,10 @@ e1000_update_stats(struct e1000_adapter 
 
 #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
 
+       /* Prevent stats update while adapter is being reset */
+       if (adapter->link_speed == 0)
+               return;
+
        spin_lock_irqsave(&adapter->stats_lock, flags);
 
        /* these counters are modified from e1000_adjust_tbi_stats,
@@ -4331,4 +4346,88 @@ e1000_netpoll(struct net_device *netdev)
 }
 #endif
 
+/* --------------- PCI Error Recovery infrastructure ------------ */
+/** e1000_io_error_detected() is called when PCI error is detected */
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, 
pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct e1000_adapter *adapter = netdev->priv;
+
+       if (netif_running(netdev))
+               e1000_down(adapter);
+
+       /* Request a slot slot reset. */
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/** e1000_io_slot_reset is called after the pci bus has been reset.
+ *  Restart the card from scratch.
+ *  Implementation resembles the first-half of the
+ *  e1000_resume routine.
+ */
+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct e1000_adapter *adapter = netdev->priv;
+
+       if (pci_enable_device(pdev)) {
+               printk(KERN_ERR "e1000: Cannot re-enable PCI device after 
reset.\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, 3, 0);
+       pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+
+       /* Perform card reset only on one instance of the card */
+       if(0 != PCI_FUNC (pdev->devfn))
+               return PCI_ERS_RESULT_RECOVERED;
+
+       e1000_reset(adapter);
+       E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/** e1000_io_resume is called when the error recovery driver
+ *  tells us that its OK to resume normal operation.
+ *  Implementation resembles the second-half of the
+ *  e1000_resume routine.
+ */
+static void e1000_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct e1000_adapter *adapter = netdev->priv;
+       uint32_t manc, swsm;
+
+       if(netif_running(netdev)) {
+               if (e1000_up(adapter)) {
+                       printk("e1000: can't bring device back up after 
reset\n");
+                       return;
+               }
+       }
+
+       netif_device_attach(netdev);
+
+       if(adapter->hw.mac_type >= e1000_82540 &&
+           adapter->hw.media_type == e1000_media_type_copper) {
+               manc = E1000_READ_REG(&adapter->hw, MANC);
+               manc &= ~(E1000_MANC_ARP_EN);
+               E1000_WRITE_REG(&adapter->hw, MANC, manc);
+       }
+
+       switch(adapter->hw.mac_type) {
+       case e1000_82573:
+               swsm = E1000_READ_REG(&adapter->hw, SWSM);
+               E1000_WRITE_REG(&adapter->hw, SWSM,
+                               swsm | E1000_SWSM_DRV_LOAD);
+               break;
+       default:
+               break;
+       }
+
+       if(netif_running(netdev))
+               mod_timer(&adapter->watchdog_timer, jiffies);
+}
+
 /* e1000_main.c */



----- End forwarded message -----
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to