From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AC5BC28EB3 for ; Thu, 6 Jun 2019 14:00:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7D80420652 for ; Thu, 6 Jun 2019 14:00:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728709AbfFFOAj (ORCPT ); Thu, 6 Jun 2019 10:00:39 -0400 Received: from mga05.intel.com ([192.55.52.43]:6023 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726924AbfFFOAj (ORCPT ); Thu, 6 Jun 2019 10:00:39 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jun 2019 07:00:38 -0700 X-ExtLoop1: 1 Received: from ahunter-desktop.fi.intel.com (HELO [10.237.72.198]) ([10.237.72.198]) by fmsmga005.fm.intel.com with ESMTP; 06 Jun 2019 07:00:30 -0700 Subject: Re: [PATCH v2 3/3] brcmfmac: sdio: Disable auto-tuning around commands expected to fail To: Douglas Anderson , Ulf Hansson , Kalle Valo , Arend van Spriel Cc: brcm80211-dev-list.pdl@broadcom.com, linux-rockchip@lists.infradead.org, Double Lo , briannorris@chromium.org, linux-wireless@vger.kernel.org, Naveen Gupta , Madhan Mohan R , mka@chromium.org, Wright Feng , Chi-Hsien Lin , netdev@vger.kernel.org, brcm80211-dev-list@cypress.com, "David S. Miller" , Franky Lin , linux-kernel@vger.kernel.org, Hante Meuleman , YueHaibing , Michael Trimarchi References: <20190603183740.239031-1-dianders@chromium.org> <20190603183740.239031-4-dianders@chromium.org> From: Adrian Hunter Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Message-ID: <42fc30b1-adab-7fa8-104c-cbb7855f2032@intel.com> Date: Thu, 6 Jun 2019 16:59:17 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 In-Reply-To: <20190603183740.239031-4-dianders@chromium.org> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org On 3/06/19 9:37 PM, Douglas Anderson wrote: > There are certain cases, notably when transitioning between sleep and > active state, when Broadcom SDIO WiFi cards will produce errors on the > SDIO bus. This is evident from the source code where you can see that > we try commands in a loop until we either get success or we've tried > too many times. The comment in the code reinforces this by saying > "just one write attempt may fail" > > Unfortunately these failures sometimes end up causing an "-EILSEQ" > back to the core which triggers a retuning of the SDIO card and that > blocks all traffic to the card until it's done. > > Let's disable retuning around the commands we expect might fail. It seems to me that re-tuning needs to be prevented before the first access otherwise it might be attempted there, and it needs to continue to be prevented during the transition when it might reasonably be expected to fail. What about something along these lines: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 4e15ea57d4f5..d932780ef56e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -664,9 +664,18 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) int err = 0; int err_cnt = 0; int try_cnt = 0; + int need_retune = 0; + bool retune_release = false; brcmf_dbg(TRACE, "Enter: on=%d\n", on); + /* Cannot re-tune if device is asleep */ + if (on) { + need_retune = sdio_retune_get_needed(bus->sdiodev->func1); // TODO: host->can_retune ? host->need_retune : 0 + sdio_retune_hold_now(bus->sdiodev->func1); // TODO: add sdio_retune_hold_now() + retune_release = true; + } + wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); /* 1st KSO write goes to AOS wake up core if device is asleep */ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); @@ -711,8 +720,16 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) err_cnt = 0; } /* bail out upon subsequent access errors */ - if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) - break; + if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) { + if (!retune_release) + break; + /* + * Allow one more retry with re-tuning released in case + * it helps. + */ + sdio_retune_release(bus->sdiodev->func1); + retune_release = false; + } udelay(KSO_WAIT_US); brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, @@ -727,6 +744,18 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) if (try_cnt > MAX_KSO_ATTEMPTS) brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err); + if (retune_release) { + /* + * CRC errors are not unexpected during the transition but they + * also trigger re-tuning. Clear that here to avoid an + * unnecessary re-tune if it wasn't already triggered to start + * with. + */ + if (!need_retune) + sdio_retune_clear_needed(bus->sdiodev->func1); // TODO: host->need_retune = 0 + sdio_retune_release(bus->sdiodev->func1); // TODO: add sdio_retune_release() + } + return err; }