|
@@ -958,6 +958,12 @@ void i40evf_down(struct i40evf_adapter *adapter)
|
|
|
if (adapter->state == __I40EVF_DOWN)
|
|
if (adapter->state == __I40EVF_DOWN)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
|
|
+ while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
|
|
|
|
+ &adapter->crit_section))
|
|
|
|
|
+ usleep_range(500, 1000);
|
|
|
|
|
+
|
|
|
|
|
+ i40evf_irq_disable(adapter);
|
|
|
|
|
+
|
|
|
/* remove all MAC filters */
|
|
/* remove all MAC filters */
|
|
|
list_for_each_entry(f, &adapter->mac_filter_list, list) {
|
|
list_for_each_entry(f, &adapter->mac_filter_list, list) {
|
|
|
f->remove = true;
|
|
f->remove = true;
|
|
@@ -968,22 +974,27 @@ void i40evf_down(struct i40evf_adapter *adapter)
|
|
|
}
|
|
}
|
|
|
if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) &&
|
|
if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) &&
|
|
|
adapter->state != __I40EVF_RESETTING) {
|
|
adapter->state != __I40EVF_RESETTING) {
|
|
|
- adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
|
|
|
|
|
|
|
+ /* cancel any current operation */
|
|
|
|
|
+ adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
|
|
|
|
|
+ adapter->aq_pending = 0;
|
|
|
|
|
+ /* Schedule operations to close down the HW. Don't wait
|
|
|
|
|
+ * here for this to complete. The watchdog is still running
|
|
|
|
|
+ * and it will take care of this.
|
|
|
|
|
+ */
|
|
|
|
|
+ adapter->aq_required = I40EVF_FLAG_AQ_DEL_MAC_FILTER;
|
|
|
adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
|
|
adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
|
|
|
- /* disable receives */
|
|
|
|
|
adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
|
|
adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
|
|
|
- mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
|
|
|
|
|
- msleep(20);
|
|
|
|
|
}
|
|
}
|
|
|
netif_tx_disable(netdev);
|
|
netif_tx_disable(netdev);
|
|
|
|
|
|
|
|
netif_tx_stop_all_queues(netdev);
|
|
netif_tx_stop_all_queues(netdev);
|
|
|
|
|
|
|
|
- i40evf_irq_disable(adapter);
|
|
|
|
|
-
|
|
|
|
|
i40evf_napi_disable_all(adapter);
|
|
i40evf_napi_disable_all(adapter);
|
|
|
|
|
|
|
|
|
|
+ msleep(20);
|
|
|
|
|
+
|
|
|
netif_carrier_off(netdev);
|
|
netif_carrier_off(netdev);
|
|
|
|
|
+ clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -2408,6 +2419,7 @@ static void i40evf_remove(struct pci_dev *pdev)
|
|
|
struct i40evf_adapter *adapter = netdev_priv(netdev);
|
|
struct i40evf_adapter *adapter = netdev_priv(netdev);
|
|
|
struct i40evf_mac_filter *f, *ftmp;
|
|
struct i40evf_mac_filter *f, *ftmp;
|
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
|
|
|
+ int count = 50;
|
|
|
|
|
|
|
|
cancel_delayed_work_sync(&adapter->init_task);
|
|
cancel_delayed_work_sync(&adapter->init_task);
|
|
|
cancel_work_sync(&adapter->reset_task);
|
|
cancel_work_sync(&adapter->reset_task);
|
|
@@ -2416,6 +2428,11 @@ static void i40evf_remove(struct pci_dev *pdev)
|
|
|
unregister_netdev(netdev);
|
|
unregister_netdev(netdev);
|
|
|
adapter->netdev_registered = false;
|
|
adapter->netdev_registered = false;
|
|
|
}
|
|
}
|
|
|
|
|
+ while (count-- && adapter->aq_required)
|
|
|
|
|
+ msleep(50);
|
|
|
|
|
+
|
|
|
|
|
+ if (count < 0)
|
|
|
|
|
+ dev_err(&pdev->dev, "Timed out waiting for PF driver.\n");
|
|
|
adapter->state = __I40EVF_REMOVE;
|
|
adapter->state = __I40EVF_REMOVE;
|
|
|
|
|
|
|
|
if (adapter->msix_entries) {
|
|
if (adapter->msix_entries) {
|