|
@@ -743,23 +743,6 @@ static int ibmvnic_open(struct net_device *netdev)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-static void disable_sub_crqs(struct ibmvnic_adapter *adapter)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- if (adapter->tx_scrq) {
|
|
|
- for (i = 0; i < adapter->req_tx_queues; i++)
|
|
|
- if (adapter->tx_scrq[i])
|
|
|
- disable_irq(adapter->tx_scrq[i]->irq);
|
|
|
- }
|
|
|
-
|
|
|
- if (adapter->rx_scrq) {
|
|
|
- for (i = 0; i < adapter->req_rx_queues; i++)
|
|
|
- if (adapter->rx_scrq[i])
|
|
|
- disable_irq(adapter->rx_scrq[i]->irq);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void clean_tx_pools(struct ibmvnic_adapter *adapter)
|
|
|
{
|
|
|
struct ibmvnic_tx_pool *tx_pool;
|
|
@@ -797,15 +780,39 @@ static int __ibmvnic_close(struct net_device *netdev)
|
|
|
adapter->state = VNIC_CLOSING;
|
|
|
netif_tx_stop_all_queues(netdev);
|
|
|
|
|
|
- clean_tx_pools(adapter);
|
|
|
- disable_sub_crqs(adapter);
|
|
|
-
|
|
|
if (adapter->napi) {
|
|
|
for (i = 0; i < adapter->req_rx_queues; i++)
|
|
|
napi_disable(&adapter->napi[i]);
|
|
|
}
|
|
|
|
|
|
+ clean_tx_pools(adapter);
|
|
|
+
|
|
|
+ if (adapter->tx_scrq) {
|
|
|
+ for (i = 0; i < adapter->req_tx_queues; i++)
|
|
|
+ if (adapter->tx_scrq[i]->irq)
|
|
|
+ disable_irq(adapter->tx_scrq[i]->irq);
|
|
|
+ }
|
|
|
+
|
|
|
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ if (adapter->rx_scrq) {
|
|
|
+ for (i = 0; i < adapter->req_rx_queues; i++) {
|
|
|
+ int retries = 10;
|
|
|
+
|
|
|
+ while (pending_scrq(adapter, adapter->rx_scrq[i])) {
|
|
|
+ retries--;
|
|
|
+ mdelay(100);
|
|
|
+
|
|
|
+ if (retries == 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (adapter->rx_scrq[i]->irq)
|
|
|
+ disable_irq(adapter->rx_scrq[i]->irq);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
adapter->state = VNIC_CLOSED;
|
|
|
return rc;
|