|
@@ -44,6 +44,7 @@
|
|
|
#include <linux/cpu.h>
|
|
|
#include <linux/smp.h>
|
|
|
#include <linux/pm_qos_params.h>
|
|
|
+#include <linux/aer.h>
|
|
|
|
|
|
#include "e1000.h"
|
|
|
|
|
@@ -4521,6 +4522,14 @@ static int e1000_resume(struct pci_dev *pdev)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+ /* AER (Advanced Error Reporting) hooks */
|
|
|
+ err = pci_enable_pcie_error_reporting(pdev);
|
|
|
+ if (err) {
|
|
|
+ dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
|
|
|
+ "0x%x\n", err);
|
|
|
+ /* non-fatal, continue */
|
|
|
+ }
|
|
|
+
|
|
|
pci_set_master(pdev);
|
|
|
|
|
|
pci_enable_wake(pdev, PCI_D3hot, 0);
|
|
@@ -4615,24 +4624,29 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
int err;
|
|
|
+ pci_ers_result_t result;
|
|
|
|
|
|
e1000e_disable_l1aspm(pdev);
|
|
|
err = pci_enable_device_mem(pdev);
|
|
|
if (err) {
|
|
|
dev_err(&pdev->dev,
|
|
|
"Cannot re-enable PCI device after reset.\n");
|
|
|
- return PCI_ERS_RESULT_DISCONNECT;
|
|
|
- }
|
|
|
- pci_set_master(pdev);
|
|
|
- pci_restore_state(pdev);
|
|
|
+ result = PCI_ERS_RESULT_DISCONNECT;
|
|
|
+ } else {
|
|
|
+ pci_set_master(pdev);
|
|
|
+ pci_restore_state(pdev);
|
|
|
|
|
|
- pci_enable_wake(pdev, PCI_D3hot, 0);
|
|
|
- pci_enable_wake(pdev, PCI_D3cold, 0);
|
|
|
+ pci_enable_wake(pdev, PCI_D3hot, 0);
|
|
|
+ pci_enable_wake(pdev, PCI_D3cold, 0);
|
|
|
|
|
|
- e1000e_reset(adapter);
|
|
|
- ew32(WUS, ~0);
|
|
|
+ e1000e_reset(adapter);
|
|
|
+ ew32(WUS, ~0);
|
|
|
+ result = PCI_ERS_RESULT_RECOVERED;
|
|
|
+ }
|
|
|
|
|
|
- return PCI_ERS_RESULT_RECOVERED;
|
|
|
+ pci_cleanup_aer_uncorrect_error_status(pdev);
|
|
|
+
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -5063,6 +5077,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
|
|
|
{
|
|
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
+ int err;
|
|
|
|
|
|
/*
|
|
|
* flush_scheduled work may reschedule our watchdog task, so
|
|
@@ -5097,6 +5112,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
|
|
|
|
|
|
free_netdev(netdev);
|
|
|
|
|
|
+ /* AER disable */
|
|
|
+ err = pci_disable_pcie_error_reporting(pdev);
|
|
|
+ if (err)
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "pci_disable_pcie_error_reporting failed 0x%x\n", err);
|
|
|
+
|
|
|
pci_disable_device(pdev);
|
|
|
}
|
|
|
|