diff options
author | Nathan Fontenot <nfont@linux.vnet.ibm.com> | 2017-05-03 14:05:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-03 11:33:05 -0400 |
commit | 46293b940fede04f90aab18d4bfecc5bd942cf3a (patch) | |
tree | 7908f79db0c53e269a6f9de3b6745b5d4d55138c /drivers/net/ethernet | |
parent | b41b83e9a784576b2bcc33bce447f7ce78fb265d (diff) | |
download | linux-46293b940fede04f90aab18d4bfecc5bd942cf3a.tar.bz2 |
ibmvnic: Wait for any pending scrqs entries at driver close
When closing the ibmvnic driver we need to wait for any pending
sub crq entries to ensure they are handled.
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/ibm/ibmvnic.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 2297cf2390e1..a312bc1fee6d 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -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; |