lkml.org 
[lkml]   [2019]   [Jun]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 5/5] brcmfmac: sdio: Don't tune while the card is off
    Date
    When Broadcom SDIO cards are idled they go to sleep and a whole
    separate subsystem takes over their SDIO communication. This is the
    Always-On-Subsystem (AOS) and it can't handle tuning requests.

    Specifically, as tested on rk3288-veyron-minnie (which reports having
    BCM4354/1 in dmesg), if I force a retune in brcmf_sdio_kso_control()
    when "on = 1" (aka we're transition from sleep to wake) by whacking:
    bus->sdiodev->func1->card->host->need_retune = 1
    ...then I can often see tuning fail. In this case dw_mmc reports "All
    phases bad!"). Note that I don't get 100% failure, presumably because
    sometimes the card itself has already transitioned away from the AOS
    itself by the time we try to wake it up. If I force retuning when "on
    = 0" (AKA force retuning right before sending the command to go to
    sleep) then retuning is always OK.

    NOTE: we need _both_ this patch and the patch to avoid triggering
    tuning due to CRC errors in the sleep/wake transition, AKA ("brcmfmac:
    sdio: Disable auto-tuning around commands expected to fail"). Though
    both patches handle issues with Broadcom's AOS, the problems are
    distinct:
    1. We want to defer (but not ignore) asynchronous (like
    timer-requested) tuning requests till the card is awake. However,
    we want to ignore CRC errors during the transition, we don't want
    to queue deferred tuning request.
    2. You could imagine that the AOS could implement retuning but we
    could still get errors while transitioning in and out of the AOS.
    Similarly you could imagine a seamless transition into and out of
    the AOS (with no CRC errors) even if the AOS couldn't handle
    tuning.

    ALSO NOTE: presumably there is never a desperate need to retune in
    order to wake up the card, since doing so is impossible. Luckily the
    only way the card can get into sleep state is if we had a good enough
    tuning to send it a sleep command, so presumably that "good enough"
    tuning is enough to wake us up, at least with a few retries.

    Signed-off-by: Douglas Anderson <dianders@chromium.org>
    ---

    Changes in v4:
    - Adjust to API rename (Adrian).

    Changes in v3:
    - ("brcmfmac: sdio: Don't tune while the card is off") new for v3.

    Changes in v2: None

    drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++++++
    1 file changed, 7 insertions(+)

    diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
    index ee76593259a7..629140b6d7e2 100644
    --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
    +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
    @@ -669,6 +669,10 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)

    sdio_retune_crc_disable(bus->sdiodev->func1);

    + /* Cannot re-tune if device is asleep; defer till we're awake */
    + if (on)
    + sdio_retune_hold_now(bus->sdiodev->func1);
    +
    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);
    @@ -729,6 +733,9 @@ 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 (on)
    + sdio_retune_release(bus->sdiodev->func1);
    +
    sdio_retune_crc_enable(bus->sdiodev->func1);

    return err;
    --
    2.22.0.rc2.383.gf4fbbf30c2-goog
    \
     
     \ /
      Last update: 2019-06-14 01:42    [W:2.293 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site