diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index 981224743c73..34c8565031f6 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -272,6 +272,8 @@ void i40evf_update_stats(struct i40evf_adapter *adapter); void i40evf_reset_interrupt_capability(struct i40evf_adapter *adapter); int i40evf_init_interrupt_scheme(struct i40evf_adapter *adapter); void i40evf_irq_enable_queues(struct i40evf_adapter *adapter, u32 mask); +void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter); +void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter); void i40e_napi_add_all(struct i40evf_adapter *adapter); void i40e_napi_del_all(struct i40evf_adapter *adapter); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 812b1200f35c..da901f4b9c18 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -28,8 +28,6 @@ #include "i40e_prototype.h" static int i40evf_setup_all_tx_resources(struct i40evf_adapter *adapter); static int i40evf_setup_all_rx_resources(struct i40evf_adapter *adapter); -static void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter); -static void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter); static int i40evf_close(struct net_device *netdev); char i40evf_driver_name[] = "i40evf"; @@ -1358,6 +1356,11 @@ static void i40evf_watchdog_task(struct work_struct *work) goto watchdog_done; } + if (adapter->aq_required & I40EVF_FLAG_AQ_DISABLE_QUEUES) { + i40evf_disable_queues(adapter); + goto watchdog_done; + } + if (adapter->aq_required & I40EVF_FLAG_AQ_MAP_VECTORS) { i40evf_map_queues(adapter); goto watchdog_done; @@ -1383,11 +1386,6 @@ static void i40evf_watchdog_task(struct work_struct *work) goto watchdog_done; } - if (adapter->aq_required & I40EVF_FLAG_AQ_DISABLE_QUEUES) { - i40evf_disable_queues(adapter); - goto watchdog_done; - } - if (adapter->aq_required & I40EVF_FLAG_AQ_CONFIGURE_QUEUES) { i40evf_configure_queues(adapter); goto watchdog_done; @@ -1724,7 +1722,7 @@ out: * * Free all transmit software resources **/ -static void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter) +void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter) { int i; @@ -1794,7 +1792,7 @@ static int i40evf_setup_all_rx_resources(struct i40evf_adapter *adapter) * * Free all receive software resources **/ -static void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter) +void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter) { int i; @@ -1824,7 +1822,7 @@ static int i40evf_open(struct net_device *netdev) dev_err(&adapter->pdev->dev, "Unable to open device due to PF driver failure.\n"); return -EIO; } - if (adapter->state != __I40EVF_DOWN) + if (adapter->state != __I40EVF_DOWN || adapter->aq_required) return -EBUSY; /* allocate transmit descriptors */ @@ -1888,9 +1886,6 @@ static int i40evf_close(struct net_device *netdev) adapter->state = __I40EVF_DOWN; i40evf_free_traffic_irqs(adapter); - i40evf_free_all_tx_resources(adapter); - i40evf_free_all_rx_resources(adapter); - return 0; } @@ -2504,6 +2499,8 @@ static void i40evf_remove(struct pci_dev *pdev) iounmap(hw->hw_addr); pci_release_regions(pdev); + i40evf_free_all_tx_resources(adapter); + i40evf_free_all_rx_resources(adapter); i40evf_free_queues(adapter); kfree(adapter->vf_res); /* If we got removed before an up/down sequence, we've got a filter diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index 3f0c85ecbca6..4240a496dc50 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -761,6 +761,8 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, break; case I40E_VIRTCHNL_OP_DISABLE_QUEUES: adapter->aq_pending &= ~(I40EVF_FLAG_AQ_DISABLE_QUEUES); + i40evf_free_all_tx_resources(adapter); + i40evf_free_all_rx_resources(adapter); break; case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES: adapter->aq_pending &= ~(I40EVF_FLAG_AQ_CONFIGURE_QUEUES);