@@ -5076,6 +5076,108 @@ static void igc_shutdown(struct pci_dev *pdev)
5076
5076
}
5077
5077
}
5078
5078
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
+
5079
5181
#ifdef CONFIG_PM
5080
5182
static const struct dev_pm_ops igc_pm_ops = {
5081
5183
SET_SYSTEM_SLEEP_PM_OPS (igc_suspend , igc_resume )
@@ -5093,6 +5195,7 @@ static struct pci_driver igc_driver = {
5093
5195
.driver .pm = & igc_pm_ops ,
5094
5196
#endif
5095
5197
.shutdown = igc_shutdown ,
5198
+ .err_handler = & igc_err_handler ,
5096
5199
};
5097
5200
5098
5201
/**
0 commit comments