diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2012-01-17 12:38:50 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-02-03 09:21:31 -0800 |
commit | 4bc34a5c5c4e8015f24c97da3876374e5a610e79 (patch) | |
tree | 0412ab7e37e3ca9b66df804997b37ac037746d51 /drivers/net | |
parent | 7f7158eb11fafcac8a2a50235366c6ffc9c62cf7 (diff) |
brcmsmac: fix tx queue flush infinite loop
commit f96b08a7e6f69c0f0a576554df3df5b1b519c479 upstream.
This patch workaround live deadlock problem caused by infinite loop
in brcms_c_wait_for_tx_completion(). I do not consider the patch as
the proper fix, which should fix the real reason of tx queue flush
failure, but patch helps with system lockup.
Reference:
https://bugzilla.kernel.org/show_bug.cgi?id=42576
Reported-and-tested-by: Patrick <ragamuffin@datacomm.ch>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/main.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 510e9bb5228..453f58e5667 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -8217,13 +8217,21 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) { + int timeout = 20; + /* flush packet queue when requested */ if (drop) brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); /* wait for queue and DMA fifos to run dry */ - while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) + while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { brcms_msleep(wlc->wl, 1); + + if (--timeout == 0) + break; + } + + WARN_ON_ONCE(timeout == 0); } void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) |