aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-05-11 04:33:32 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-07-21 19:03:47 -0400
commit9f19f31dd4903d9c6a7ce33740eadd2b6bdd8ce2 (patch)
tree09c4287ce589eb594f19d265da74c5d7c0ed0d4a /drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
parent1c55ed768bb8b6aee0e1c88e963a429a3c14be07 (diff)
ixgbevf: Add support for PCI error handling
This change adds support for handling IO errors and slot resets. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 7cb678d2d2a2..ccc801e99610 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3189,12 +3189,92 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev)
3189 pci_disable_device(pdev); 3189 pci_disable_device(pdev);
3190} 3190}
3191 3191
3192/**
3193 * ixgbevf_io_error_detected - called when PCI error is detected
3194 * @pdev: Pointer to PCI device
3195 * @state: The current pci connection state
3196 *
3197 * This function is called after a PCI bus error affecting
3198 * this device has been detected.
3199 */
3200static pci_ers_result_t ixgbevf_io_error_detected(struct pci_dev *pdev,
3201 pci_channel_state_t state)
3202{
3203 struct net_device *netdev = pci_get_drvdata(pdev);
3204 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3205
3206 netif_device_detach(netdev);
3207
3208 if (state == pci_channel_io_perm_failure)
3209 return PCI_ERS_RESULT_DISCONNECT;
3210
3211 if (netif_running(netdev))
3212 ixgbevf_down(adapter);
3213
3214 pci_disable_device(pdev);
3215
3216 /* Request a slot slot reset. */
3217 return PCI_ERS_RESULT_NEED_RESET;
3218}
3219
3220/**
3221 * ixgbevf_io_slot_reset - called after the pci bus has been reset.
3222 * @pdev: Pointer to PCI device
3223 *
3224 * Restart the card from scratch, as if from a cold-boot. Implementation
3225 * resembles the first-half of the ixgbevf_resume routine.
3226 */
3227static pci_ers_result_t ixgbevf_io_slot_reset(struct pci_dev *pdev)
3228{
3229 struct net_device *netdev = pci_get_drvdata(pdev);
3230 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3231
3232 if (pci_enable_device_mem(pdev)) {
3233 dev_err(&pdev->dev,
3234 "Cannot re-enable PCI device after reset.\n");
3235 return PCI_ERS_RESULT_DISCONNECT;
3236 }
3237
3238 pci_set_master(pdev);
3239
3240 ixgbevf_reset(adapter);
3241
3242 return PCI_ERS_RESULT_RECOVERED;
3243}
3244
3245/**
3246 * ixgbevf_io_resume - called when traffic can start flowing again.
3247 * @pdev: Pointer to PCI device
3248 *
3249 * This callback is called when the error recovery driver tells us that
3250 * its OK to resume normal operation. Implementation resembles the
3251 * second-half of the ixgbevf_resume routine.
3252 */
3253static void ixgbevf_io_resume(struct pci_dev *pdev)
3254{
3255 struct net_device *netdev = pci_get_drvdata(pdev);
3256 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3257
3258 if (netif_running(netdev))
3259 ixgbevf_up(adapter);
3260
3261 netif_device_attach(netdev);
3262}
3263
3264/* PCI Error Recovery (ERS) */
3265static struct pci_error_handlers ixgbevf_err_handler = {
3266 .error_detected = ixgbevf_io_error_detected,
3267 .slot_reset = ixgbevf_io_slot_reset,
3268 .resume = ixgbevf_io_resume,
3269};
3270
3192static struct pci_driver ixgbevf_driver = { 3271static struct pci_driver ixgbevf_driver = {
3193 .name = ixgbevf_driver_name, 3272 .name = ixgbevf_driver_name,
3194 .id_table = ixgbevf_pci_tbl, 3273 .id_table = ixgbevf_pci_tbl,
3195 .probe = ixgbevf_probe, 3274 .probe = ixgbevf_probe,
3196 .remove = __devexit_p(ixgbevf_remove), 3275 .remove = __devexit_p(ixgbevf_remove),
3197 .shutdown = ixgbevf_shutdown, 3276 .shutdown = ixgbevf_shutdown,
3277 .err_handler = &ixgbevf_err_handler
3198}; 3278};
3199 3279
3200/** 3280/**