diff options
| author | Sathya Perla <sathya.perla@emulex.com> | 2012-12-17 14:38:50 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-12-18 19:18:39 -0500 |
| commit | a323d9bf835e27d5e72eae86b5a41747d98bd9d2 (patch) | |
| tree | 19595d569e8cae90ff3aae47a9a045869e0ddc35 | |
| parent | c39ba1c2bdc3f97839d9b9e6bf9ffd5c754b7f95 (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.c | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 21 |
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 f2875aa47661..8a250c38fb82 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 | ||
| 299 | void be_async_mcc_disable(struct be_adapter *adapter) | 299 | void 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 | ||
| 304 | int be_process_mcc(struct be_adapter *adapter) | 309 | int 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 f95612b907ae..bf50e73c1ec7 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 | ||
