diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-05-11 04:33:32 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-07-21 19:03:47 -0400 |
commit | 9f19f31dd4903d9c6a7ce33740eadd2b6bdd8ce2 (patch) | |
tree | 09c4287ce589eb594f19d265da74c5d7c0ed0d4a /drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |
parent | 1c55ed768bb8b6aee0e1c88e963a429a3c14be07 (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.c | 80 |
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 | */ | ||
3200 | static 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 | */ | ||
3227 | static 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 | */ | ||
3253 | static 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) */ | ||
3265 | static 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 | |||
3192 | static struct pci_driver ixgbevf_driver = { | 3271 | static 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 | /** |