aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-04-14 13:41:42 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-14 13:41:42 -0400
commit677df2f4aefaf9a87f6a37cc38453515547f4bda (patch)
tree37889e4b5e71892beadcd3fcff25da9033d81c3a
parente1a5ddc5069a0c7589a139e0422200672d965581 (diff)
parente1ad8e33d2e57ca64d9862b63d986fc296a7b876 (diff)
downloadxhci-677df2f4aefaf9a87f6a37cc38453515547f4bda.tar.gz
Merge branch 'be2net'
Sathya Perla says: ==================== be2net: patch set Patch 1/2 is a v2 of a patch that was submitted earlier (as a part of a different patch-set). v2 incorporates a suggestion given by David Laight for how long to poll for pending TX completions while disabling a device. Patch 2/2 fixes a crash in be_remove()->be_close() path after be2net has aborted an EEH error recovery due to a permanant failure. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c17
2 files changed, 14 insertions, 4 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 8ccaa2520dc3e9..97db5a7179df1c 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -374,6 +374,7 @@ enum vf_state {
#define BE_FLAGS_NAPI_ENABLED (1 << 9)
#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11)
#define BE_FLAGS_VXLAN_OFFLOADS (1 << 12)
+#define BE_FLAGS_SETUP_DONE (1 << 13)
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 3e6df47b69735b..a18645407d2152 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2033,11 +2033,13 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
bool dummy_wrb;
int i, pending_txqs;
- /* Wait for a max of 200ms for all the tx-completions to arrive. */
+ /* Stop polling for compls when HW has been silent for 10ms */
do {
pending_txqs = adapter->num_tx_qs;
for_all_tx_queues(adapter, txo, i) {
+ cmpl = 0;
+ num_wrbs = 0;
txq = &txo->q;
while ((txcp = be_tx_compl_get(&txo->cq))) {
end_idx =
@@ -2050,14 +2052,13 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
if (cmpl) {
be_cq_notify(adapter, txo->cq.id, false, cmpl);
atomic_sub(num_wrbs, &txq->used);
- cmpl = 0;
- num_wrbs = 0;
+ timeo = 0;
}
if (atomic_read(&txq->used) == 0)
pending_txqs--;
}
- if (pending_txqs == 0 || ++timeo > 200)
+ if (pending_txqs == 0 || ++timeo > 10 || be_hw_error(adapter))
break;
mdelay(1);
@@ -2725,6 +2726,12 @@ static int be_close(struct net_device *netdev)
struct be_eq_obj *eqo;
int i;
+ /* This protection is needed as be_close() may be called even when the
+ * adapter is in cleared state (after eeh perm failure)
+ */
+ if (!(adapter->flags & BE_FLAGS_SETUP_DONE))
+ return 0;
+
be_roce_dev_close(adapter);
if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
@@ -3055,6 +3062,7 @@ static int be_clear(struct be_adapter *adapter)
be_clear_queues(adapter);
be_msix_disable(adapter);
+ adapter->flags &= ~BE_FLAGS_SETUP_DONE;
return 0;
}
@@ -3559,6 +3567,7 @@ static int be_setup(struct be_adapter *adapter)
adapter->phy.fc_autoneg = 1;
be_schedule_worker(adapter);
+ adapter->flags |= BE_FLAGS_SETUP_DONE;
return 0;
err:
be_clear(adapter);