lkml.org 
[lkml]   [2022]   [Jul]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/6] brcmfmac: fix continuous 802.1x tx pending timeout error
    Date
    From: Wright Feng <wright.feng@cypress.com>

    The race condition in brcmf_msgbuf_txflow and brcmf_msgbuf_delete_flowring
    makes tx_msghdr writing after brcmf_msgbuf_remove_flowring. Host
    driver should delete flowring after txflow complete and all txstatus back,
    or pend_8021x_cnt will never be zero and cause every connection 950
    milliseconds(MAX_WAIT_FOR_8021X_TX) delay.

    Signed-off-by: Wright Feng <wright.feng@cypress.com>
    Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
    Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
    Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
    ---
    .../broadcom/brcm80211/brcmfmac/core.c | 4 +++-
    .../broadcom/brcm80211/brcmfmac/msgbuf.c | 23 ++++++++++++++++++-
    2 files changed, 25 insertions(+), 2 deletions(-)

    diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
    index 87aef211b35f..8ca259ace001 100644
    --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
    +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
    @@ -1484,8 +1484,10 @@ int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
    !brcmf_get_pend_8021x_cnt(ifp),
    MAX_WAIT_FOR_8021X_TX);

    - if (!err)
    + if (!err) {
    bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n");
    + atomic_set(&ifp->pend_8021x_cnt, 0);
    + }

    return !err;
    }
    diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
    index b2d0f7570aa9..174584b42972 100644
    --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
    +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
    @@ -71,6 +71,7 @@
    #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32
    #define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48

    +#define BRCMF_MAX_TXSTATUS_WAIT_RETRIES 10

    struct msgbuf_common_hdr {
    u8 msgtype;
    @@ -806,8 +807,12 @@ static int brcmf_msgbuf_tx_queue_data(struct brcmf_pub *drvr, int ifidx,
    flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx);
    if (flowid == BRCMF_FLOWRING_INVALID_ID) {
    flowid = brcmf_msgbuf_flowring_create(msgbuf, ifidx, skb);
    - if (flowid == BRCMF_FLOWRING_INVALID_ID)
    + if (flowid == BRCMF_FLOWRING_INVALID_ID) {
    return -ENOMEM;
    + } else {
    + brcmf_flowring_enqueue(flow, flowid, skb);
    + return 0;
    + }
    }
    queue_count = brcmf_flowring_enqueue(flow, flowid, skb);
    force = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0);
    @@ -1395,9 +1400,25 @@ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
    struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
    struct msgbuf_tx_flowring_delete_req *delete;
    struct brcmf_commonring *commonring;
    + struct brcmf_commonring *commonring_del;
    +
    void *ret_ptr;
    u8 ifidx;
    int err;
    + int retry = BRCMF_MAX_TXSTATUS_WAIT_RETRIES;
    +
    + /* wait for commonring txflow finished */
    + commonring_del = msgbuf->flowrings[flowid];
    + brcmf_commonring_lock(commonring_del);
    + while (retry && atomic_read(&commonring_del->outstanding_tx)) {
    + usleep_range(5000, 10000);
    + retry--;
    + }
    + brcmf_commonring_unlock(commonring_del);
    + if (!retry && atomic_read(&commonring_del->outstanding_tx)) {
    + brcmf_err("timed out waiting for txstatus\n");
    + atomic_set(&commonring_del->outstanding_tx, 0);
    + }

    /* no need to submit if firmware can not be reached */
    if (drvr->bus_if->state != BRCMF_BUS_UP) {
    --
    2.37.0
    \
     
     \ /
      Last update: 2022-07-22 13:59    [W:5.267 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site