aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSathya Perla <sathya.perla@emulex.com>2012-12-17 14:38:50 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-18 19:18:39 -0500
commita323d9bf835e27d5e72eae86b5a41747d98bd9d2 (patch)
tree19595d569e8cae90ff3aae47a9a045869e0ddc35
parentc39ba1c2bdc3f97839d9b9e6bf9ffd5c754b7f95 (diff)
be2net: fix be_close() to ensure all events are ack'ed
In be_close(), be_eq_clean() must be called after all RX/TX/MCC queues have been cleaned to ensure that any events caused while cleaning up completions are notified/acked. Not clearing all events can cause upredictable behaviour when RX rings are re-created in the subsequent be_open(). Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c5
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c21
2 files changed, 17 insertions, 9 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index f2875aa4766..8a250c38fb8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -298,7 +298,12 @@ void be_async_mcc_enable(struct be_adapter *adapter)
298 298
299void be_async_mcc_disable(struct be_adapter *adapter) 299void be_async_mcc_disable(struct be_adapter *adapter)
300{ 300{
301 spin_lock_bh(&adapter->mcc_cq_lock);
302
301 adapter->mcc_obj.rearm_cq = false; 303 adapter->mcc_obj.rearm_cq = false;
304 be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
305
306 spin_unlock_bh(&adapter->mcc_cq_lock);
302} 307}
303 308
304int be_process_mcc(struct be_adapter *adapter) 309int be_process_mcc(struct be_adapter *adapter)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index f95612b907a..bf50e73c1ec 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2398,13 +2398,22 @@ static int be_close(struct net_device *netdev)
2398 2398
2399 be_roce_dev_close(adapter); 2399 be_roce_dev_close(adapter);
2400 2400
2401 be_async_mcc_disable(adapter);
2402
2403 if (!lancer_chip(adapter)) 2401 if (!lancer_chip(adapter))
2404 be_intr_set(adapter, false); 2402 be_intr_set(adapter, false);
2405 2403
2406 for_all_evt_queues(adapter, eqo, i) { 2404 for_all_evt_queues(adapter, eqo, i)
2407 napi_disable(&eqo->napi); 2405 napi_disable(&eqo->napi);
2406
2407 be_async_mcc_disable(adapter);
2408
2409 /* Wait for all pending tx completions to arrive so that
2410 * all tx skbs are freed.
2411 */
2412 be_tx_compl_clean(adapter);
2413
2414 be_rx_qs_destroy(adapter);
2415
2416 for_all_evt_queues(adapter, eqo, i) {
2408 if (msix_enabled(adapter)) 2417 if (msix_enabled(adapter))
2409 synchronize_irq(be_msix_vec_get(adapter, eqo)); 2418 synchronize_irq(be_msix_vec_get(adapter, eqo));
2410 else 2419 else
@@ -2414,12 +2423,6 @@ static int be_close(struct net_device *netdev)
2414 2423
2415 be_irq_unregister(adapter); 2424 be_irq_unregister(adapter);
2416 2425
2417 /* Wait for all pending tx completions to arrive so that
2418 * all tx skbs are freed.
2419 */
2420 be_tx_compl_clean(adapter);
2421
2422 be_rx_qs_destroy(adapter);
2423 return 0; 2426 return 0;
2424} 2427}
2425 2428