diff options
author | Emil Tantilov <emil.s.tantilov@intel.com> | 2016-11-16 11:25:34 -0800 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2017-01-03 13:03:37 -0800 |
commit | b19cf6eea9e2a497e6475fd02c0703f0b3a6d083 (patch) | |
tree | d71eb00d3230a00e1ce417abb17fe0284c953702 /drivers/net/ethernet/intel | |
parent | 126db13fa0e6d05c9f94e0125f61e773bd5ab079 (diff) |
ixgbevf: fix AER error handling
Make sure that we free the IRQs in ixgbevf_io_error_detected() when
responding to an PCIe AER error and also restore them when the
interface recovers from it.
Previously it was possible to trigger BUG_ON() check in free_msix_irqs()
in the case where we call ixgbevf_remove() after a failed recovery from
AER error because the interrupts were not freed.
Also moved the down and free functions into ixgbevf_close_suspend()
same as with ixgbe.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 8574f212a67e..a78e4901118b 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -3228,6 +3228,21 @@ err_setup_reset: } /** + * ixgbevf_close_suspend - actions necessary to both suspend and close flows + * @adapter: the private adapter struct + * + * This function should contain the necessary work common to both suspending + * and closing of the device. + */ +static void ixgbevf_close_suspend(struct ixgbevf_adapter *adapter) +{ + ixgbevf_down(adapter); + ixgbevf_free_irq(adapter); + ixgbevf_free_all_tx_resources(adapter); + ixgbevf_free_all_rx_resources(adapter); +} + +/** * ixgbevf_close - Disables a network interface * @netdev: network interface device structure * @@ -3242,14 +3257,8 @@ int ixgbevf_close(struct net_device *netdev) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); - if (!netif_device_present(netdev)) - return 0; - - ixgbevf_down(adapter); - ixgbevf_free_irq(adapter); - - ixgbevf_free_all_tx_resources(adapter); - ixgbevf_free_all_rx_resources(adapter); + if (netif_device_present(netdev)) + ixgbevf_close_suspend(adapter); return 0; } @@ -3806,13 +3815,10 @@ static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state) rtnl_lock(); netif_device_detach(netdev); - if (netif_running(netdev)) { - ixgbevf_down(adapter); - ixgbevf_free_irq(adapter); - ixgbevf_free_all_tx_resources(adapter); - ixgbevf_free_all_rx_resources(adapter); - ixgbevf_clear_interrupt_scheme(adapter); - } + if (netif_running(netdev)) + ixgbevf_close_suspend(adapter); + + ixgbevf_clear_interrupt_scheme(adapter); rtnl_unlock(); #ifdef CONFIG_PM @@ -4251,7 +4257,7 @@ static pci_ers_result_t ixgbevf_io_error_detected(struct pci_dev *pdev, } if (netif_running(netdev)) - ixgbevf_down(adapter); + ixgbevf_close_suspend(adapter); if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) pci_disable_device(pdev); @@ -4299,12 +4305,13 @@ static pci_ers_result_t ixgbevf_io_slot_reset(struct pci_dev *pdev) static void ixgbevf_io_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbevf_adapter *adapter = netdev_priv(netdev); + rtnl_lock(); if (netif_running(netdev)) - ixgbevf_up(adapter); + ixgbevf_open(netdev); netif_device_attach(netdev); + rtnl_unlock(); } /* PCI Error Recovery (ERS) */ |