Skip to content

Commit bc23aa9

Browse files
aneftinJeff Kirsher
authored andcommitted
igc: Add pcie error handler support
Add pcie error detection, slot reset and resume capability Signed-off-by: Sasha Neftin <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent a5136f7 commit bc23aa9

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5076,6 +5076,108 @@ static void igc_shutdown(struct pci_dev *pdev)
50765076
}
50775077
}
50785078

5079+
/**
5080+
* igc_io_error_detected - called when PCI error is detected
5081+
* @pdev: Pointer to PCI device
5082+
* @state: The current PCI connection state
5083+
*
5084+
* This function is called after a PCI bus error affecting
5085+
* this device has been detected.
5086+
**/
5087+
static pci_ers_result_t igc_io_error_detected(struct pci_dev *pdev,
5088+
pci_channel_state_t state)
5089+
{
5090+
struct net_device *netdev = pci_get_drvdata(pdev);
5091+
struct igc_adapter *adapter = netdev_priv(netdev);
5092+
5093+
netif_device_detach(netdev);
5094+
5095+
if (state == pci_channel_io_perm_failure)
5096+
return PCI_ERS_RESULT_DISCONNECT;
5097+
5098+
if (netif_running(netdev))
5099+
igc_down(adapter);
5100+
pci_disable_device(pdev);
5101+
5102+
/* Request a slot reset. */
5103+
return PCI_ERS_RESULT_NEED_RESET;
5104+
}
5105+
5106+
/**
5107+
* igc_io_slot_reset - called after the PCI bus has been reset.
5108+
* @pdev: Pointer to PCI device
5109+
*
5110+
* Restart the card from scratch, as if from a cold-boot. Implementation
5111+
* resembles the first-half of the igc_resume routine.
5112+
**/
5113+
static pci_ers_result_t igc_io_slot_reset(struct pci_dev *pdev)
5114+
{
5115+
struct net_device *netdev = pci_get_drvdata(pdev);
5116+
struct igc_adapter *adapter = netdev_priv(netdev);
5117+
struct igc_hw *hw = &adapter->hw;
5118+
pci_ers_result_t result;
5119+
5120+
if (pci_enable_device_mem(pdev)) {
5121+
dev_err(&pdev->dev,
5122+
"Could not re-enable PCI device after reset.\n");
5123+
result = PCI_ERS_RESULT_DISCONNECT;
5124+
} else {
5125+
pci_set_master(pdev);
5126+
pci_restore_state(pdev);
5127+
pci_save_state(pdev);
5128+
5129+
pci_enable_wake(pdev, PCI_D3hot, 0);
5130+
pci_enable_wake(pdev, PCI_D3cold, 0);
5131+
5132+
/* In case of PCI error, adapter loses its HW address
5133+
* so we should re-assign it here.
5134+
*/
5135+
hw->hw_addr = adapter->io_addr;
5136+
5137+
igc_reset(adapter);
5138+
wr32(IGC_WUS, ~0);
5139+
result = PCI_ERS_RESULT_RECOVERED;
5140+
}
5141+
5142+
return result;
5143+
}
5144+
5145+
/**
5146+
* igc_io_resume - called when traffic can start to flow again.
5147+
* @pdev: Pointer to PCI device
5148+
*
5149+
* This callback is called when the error recovery driver tells us that
5150+
* its OK to resume normal operation. Implementation resembles the
5151+
* second-half of the igc_resume routine.
5152+
*/
5153+
static void igc_io_resume(struct pci_dev *pdev)
5154+
{
5155+
struct net_device *netdev = pci_get_drvdata(pdev);
5156+
struct igc_adapter *adapter = netdev_priv(netdev);
5157+
5158+
rtnl_lock();
5159+
if (netif_running(netdev)) {
5160+
if (igc_open(netdev)) {
5161+
dev_err(&pdev->dev, "igc_open failed after reset\n");
5162+
return;
5163+
}
5164+
}
5165+
5166+
netif_device_attach(netdev);
5167+
5168+
/* let the f/w know that the h/w is now under the control of the
5169+
* driver.
5170+
*/
5171+
igc_get_hw_control(adapter);
5172+
rtnl_unlock();
5173+
}
5174+
5175+
static const struct pci_error_handlers igc_err_handler = {
5176+
.error_detected = igc_io_error_detected,
5177+
.slot_reset = igc_io_slot_reset,
5178+
.resume = igc_io_resume,
5179+
};
5180+
50795181
#ifdef CONFIG_PM
50805182
static const struct dev_pm_ops igc_pm_ops = {
50815183
SET_SYSTEM_SLEEP_PM_OPS(igc_suspend, igc_resume)
@@ -5093,6 +5195,7 @@ static struct pci_driver igc_driver = {
50935195
.driver.pm = &igc_pm_ops,
50945196
#endif
50955197
.shutdown = igc_shutdown,
5198+
.err_handler = &igc_err_handler,
50965199
};
50975200

50985201
/**

0 commit comments

Comments
 (0)