Skip to content

Commit

Permalink
brcmfmac: reserve 2 credits for host tx control path
Browse files Browse the repository at this point in the history
It is observed that sometimes when sdiod is low in tx credits in low
rssi scenarios, the data path consumes all sdiod rx all credits and
there is no sdiod rx credit available for control path causing host
and card to go out of sync resulting in link loss between host and
card. So in order to prevent it some credits are reserved for control
path.

Note that TXCTL_CREDITS can't be larger than the firmware default
credit update threshold 2; otherwise there will be a deadlock for both
side waiting for each other.

Signed-off-by: Amar Shankar <[email protected]>
Signed-off-by: Jia-Shyr Chuang <[email protected]>
Signed-off-by: Chi-Hsien Lin <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
  • Loading branch information
Amar Shankar authored and Kalle Valo committed Jul 14, 2020
1 parent fc4aa12 commit b41c232
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
};

#define TXCTL_CREDITS 2

static void pkt_align(struct sk_buff *p, int len, int align)
{
uint datalign;
Expand All @@ -661,8 +663,16 @@ static void pkt_align(struct sk_buff *p, int len, int align)
/* To check if there's window offered */
static bool data_ok(struct brcmf_sdio *bus)
{
return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
/* Reserve TXCTL_CREDITS credits for txctl */
return (bus->tx_max - bus->tx_seq) > TXCTL_CREDITS &&
((bus->tx_max - bus->tx_seq) & 0x80) == 0;
}

/* To check if there's window offered */
static bool txctl_ok(struct brcmf_sdio *bus)
{
return (bus->tx_max - bus->tx_seq) != 0 &&
((bus->tx_max - bus->tx_seq) & 0x80) == 0;
}

static int
Expand Down Expand Up @@ -2668,14 +2678,17 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
brcmf_sdio_clrintr(bus);

if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
data_ok(bus)) {
txctl_ok(bus)) {
sdio_claim_host(bus->sdiodev->func1);
if (bus->ctrl_frame_stat) {
err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
bus->ctrl_frame_len);
bus->ctrl_frame_err = err;
wmb();
bus->ctrl_frame_stat = false;
if (err)
brcmf_err("sdio ctrlframe tx failed err=%d\n",
err);
}
sdio_release_host(bus->sdiodev->func1);
brcmf_sdio_wait_event_wakeup(bus);
Expand Down

0 comments on commit b41c232

Please sign in to comment.