be2net: fix be_close() to ensure all events are ack'ed
authorSathya Perla <sathya.perla@emulex.com>
Mon, 17 Dec 2012 19:38:50 +0000 (19:38 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Dec 2012 00:18:39 +0000 (16:18 -0800)
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>
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_main.c

index f2875aa4766170a100b7a21aeffac60e1b9c8d57..8a250c38fb82a4c070a98e529c76e42e05d92f28 100644 (file)
@@ -298,7 +298,12 @@ void be_async_mcc_enable(struct be_adapter *adapter)
 
 void be_async_mcc_disable(struct be_adapter *adapter)
 {
+       spin_lock_bh(&adapter->mcc_cq_lock);
+
        adapter->mcc_obj.rearm_cq = false;
+       be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
+
+       spin_unlock_bh(&adapter->mcc_cq_lock);
 }
 
 int be_process_mcc(struct be_adapter *adapter)
index f95612b907aea3a8341752f3e02f3446b432007e..bf50e73c1ec7fb6e3f9f0b677224ee9c502efe66 100644 (file)
@@ -2398,13 +2398,22 @@ static int be_close(struct net_device *netdev)
 
        be_roce_dev_close(adapter);
 
-       be_async_mcc_disable(adapter);
-
        if (!lancer_chip(adapter))
                be_intr_set(adapter, false);
 
-       for_all_evt_queues(adapter, eqo, i) {
+       for_all_evt_queues(adapter, eqo, i)
                napi_disable(&eqo->napi);
+
+       be_async_mcc_disable(adapter);
+
+       /* Wait for all pending tx completions to arrive so that
+        * all tx skbs are freed.
+        */
+       be_tx_compl_clean(adapter);
+
+       be_rx_qs_destroy(adapter);
+
+       for_all_evt_queues(adapter, eqo, i) {
                if (msix_enabled(adapter))
                        synchronize_irq(be_msix_vec_get(adapter, eqo));
                else
@@ -2414,12 +2423,6 @@ static int be_close(struct net_device *netdev)
 
        be_irq_unregister(adapter);
 
-       /* Wait for all pending tx completions to arrive so that
-        * all tx skbs are freed.
-        */
-       be_tx_compl_clean(adapter);
-
-       be_rx_qs_destroy(adapter);
        return 0;
 }