Blob Blame History Raw
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 17594de..a86d689 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7518,7 +7518,7 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
 	return wlc->band->bandunit;
 }
 
-void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
+static int __brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
 {
 	int timeout = 20;
 	int i;
@@ -7536,9 +7536,25 @@ void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
 			break;
 	}
 
+	return timeout;
+}
+
+void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
+{
+	int timeout;
+
+	timeout = __brcms_c_wait_for_tx_completion(wlc, drop);
+	if (timeout != 0)
+		return;
+
+	/* Retry. */
+	printk(KERN_INFO "brcms_c_wait_for_tx_completion took > 20ms. Retrying.\n");
+	timeout = __brcms_c_wait_for_tx_completion(wlc, drop);
+
 	WARN_ON_ONCE(timeout == 0);
 }
 
+
 void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
 {
 	wlc->bcn_li_bcn = interval;