| From f96b08a7e6f69c0f0a576554df3df5b1b519c479 Mon Sep 17 00:00:00 2001 |
| From: Stanislaw Gruszka <sgruszka@redhat.com> |
| Date: Tue, 17 Jan 2012 12:38:50 +0100 |
| Subject: brcmsmac: fix tx queue flush infinite loop |
| |
| From: Stanislaw Gruszka <sgruszka@redhat.com> |
| |
| 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> |
| |
| --- |
| drivers/net/wireless/brcm80211/brcmsmac/main.c | 10 +++++++++- |
| 1 file changed, 9 insertions(+), 1 deletion(-) |
| |
| --- 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_i |
| |
| 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) |