From patchwork Tue Jan 22 21:47:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arend van Spriel X-Patchwork-Id: 2020861 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 75F2FDF2EB for ; Tue, 22 Jan 2013 21:48:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752400Ab3AVVsp (ORCPT ); Tue, 22 Jan 2013 16:48:45 -0500 Received: from mms3.broadcom.com ([216.31.210.19]:4508 "EHLO mms3.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751513Ab3AVVso (ORCPT ); Tue, 22 Jan 2013 16:48:44 -0500 Received: from [10.9.208.55] by mms3.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.5)); Tue, 22 Jan 2013 13:43:17 -0800 X-Server-Uuid: B86B6450-0931-4310-942E-F00ED04CA7AF Received: from IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) by IRVEXCHCAS07.corp.ad.broadcom.com (10.9.208.55) with Microsoft SMTP Server (TLS) id 14.1.355.2; Tue, 22 Jan 2013 13:47:50 -0800 Received: from mail-sj1-12.sj.broadcom.com (10.10.10.20) by IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) with Microsoft SMTP Server id 14.1.355.2; Tue, 22 Jan 2013 13:47:50 -0800 Received: from arend-vb-linux (unknown [10.177.252.8]) by mail-sj1-12.sj.broadcom.com (Postfix) with ESMTP id 20641207C0; Tue, 22 Jan 2013 13:47:50 -0800 (PST) Received: from arend by arend-vb-linux with local (Exim 4.80) ( envelope-from ) id 1Txlh6-0001r6-Ax; Tue, 22 Jan 2013 22:47:48 +0100 From: "Arend van Spriel" To: "John W. Linville" cc: "Linux Wireless List" , "Arend van Spriel" Subject: [PATCH for 3.8] brcmsmac: fix tx status processing Date: Tue, 22 Jan 2013 22:47:40 +0100 Message-ID: <1358891260-7100-1-git-send-email-arend@broadcom.com> X-Mailer: git-send-email 1.7.10.4 MIME-Version: 1.0 X-WSS-ID: 7CE1D87E3Q45081379-14-01 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org This issue was reported on the wireless list (see [1]) in which brcmsmac ran into a fatal error: [ 588.284074] brcmsmac bcma0:0: frameid != txh->TxFrameID [ 588.284098] brcmsmac bcma0:0: MI_TFS: fatal [ 588.284103] brcmsmac bcma0:0: wl0: fatal error, reinitializing [ 588.286208] ieee80211 phy0: Hardware restart was requested The tx status feedback is processed in a loop limiting the number of frames processed in one run. The code terminate processing when the limit is reached regardless the txstatus value read from the device register. When that status is is flagged as being valid it must be processed as the hardware will clear it after is has been read. Bisecting was done by Seth Forshee and showed following commit as the culprit: commit 57fe504817ccec9b6ac23e973d2925343bf1e3b6 Author: Piotr Haber Date: Wed Nov 28 21:44:07 2012 +0100 brcmsmac: fix bounds checking in tx/rx [1] http://www.spinics.net/lists/linux-wireless/msg101293.html Reported-by: Linus Torvalds Tested-by: Seth Forshee Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 25 +++++++++--------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 17594de..9f3d7e9 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) static bool brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) { - bool morepending = false; struct bcma_device *core; struct tx_status txstatus, *txs; u32 s1, s2; @@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) txs = &txstatus; core = wlc_hw->d11core; *fatal = false; - s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); - while (!(*fatal) - && (s1 & TXS_V)) { - /* !give others some time to run! */ - if (n >= max_tx_num) { - morepending = true; - break; - } + while (n < max_tx_num) { + s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); if (s1 == 0xffffffff) { brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); *fatal = true; return false; } - s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); + /* only process when valid */ + if (!(s1 & TXS_V)) + break; + s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); txs->status = s1 & TXS_STATUS_MASK; txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; txs->sequence = s2 & TXS_SEQ_MASK; @@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) txs->lasttxtime = 0; *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); - - s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); + if (*fatal == true) + return false; n++; } - if (*fatal) - return false; - - return morepending; + return n >= max_tx_num; } static void brcms_c_tbtt(struct brcms_c_info *wlc)