From 8d7cea6c4c18644a95da3f195c18787cfeb7e836 Mon Sep 17 00:00:00 2001 From: Carter Chen Date: Tue, 1 Aug 2023 20:30:00 -0500 Subject: [PATCH 171/296] non-upstream: to prevent rx interrupt comes too early to have a allocated drvr the brcmf_pub data structure is allocated after firmware has downloaded. but if the rx interrupt comes early than strcture allocation. a null pointer crash happen dues to feature judgement. crash log like this: brcmfmac: brcmf_sdio_isr Enter --> interrupt comes brcmfmac: brcmf_alloc Enter --> brcmf_pub allocation brcmfmac: brcmf_sdio_readshared sdpcm_shared address 0x001B7F2C* Unable to handle kernel paging request at virtual address 0000000000003090 Mem abort info: ESR = 0x96000006 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 Signed-off-by: Carter Chen --- .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 5 ++++- .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 12 ++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index d425b6b53ec6..8cf56f044ecb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -391,5 +391,8 @@ bool brcmf_feat_is_6ghz_enabled(struct brcmf_if *ifp) bool brcmf_feat_is_sdio_rxf_in_kthread(struct brcmf_pub *drvr) { - return drvr->settings->sdio_rxf_in_kthread_enabled; + if (drvr) + return drvr->settings->sdio_rxf_in_kthread_enabled; + else + return false; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index cdefb0a68e0e..ddfc29949f73 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -1683,10 +1683,10 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) u16 sublen; struct sk_buff *pfirst, *pnext; struct sk_buff *skb_head = NULL, *skb_prev = NULL, *skb_to_rxfq = NULL; - struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); int errcode; u8 doff; struct brcmf_sdio_hdrinfo rd_new; + struct brcmf_mp_device *settings = bus->sdiodev->settings; /* If packets, issue read(s) and send up packet chain */ /* Return sequence numbers consumed? */ @@ -1887,7 +1887,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) false, false); } - if (brcmf_feat_is_sdio_rxf_in_kthread(bus_if->drvr) && skb_to_rxfq) { + if (settings && settings->sdio_rxf_in_kthread_enabled && skb_to_rxfq) { if (!skb_head) skb_head = skb_to_rxfq; else @@ -1901,7 +1901,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) bus->sdcnt.rxglomframes++; } - if (brcmf_feat_is_sdio_rxf_in_kthread(bus_if->drvr) && skb_head) + if (settings && settings->sdio_rxf_in_kthread_enabled && skb_head) brcmf_sched_rxf(bus, skb_head); return num; @@ -2055,7 +2055,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) struct brcmf_sdio_hdrinfo *rd = &bus->cur_read, rd_new; u8 head_read = 0; struct sk_buff *skb_to_rxfq = NULL, *skb_head = NULL, *skb_prev = NULL; - struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); + struct brcmf_mp_device *settings = bus->sdiodev->settings; brcmf_dbg(SDIO, "Enter\n"); @@ -2249,7 +2249,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) false, false); } - if (brcmf_feat_is_sdio_rxf_in_kthread(bus_if->drvr) && skb_to_rxfq) { + if (settings && settings->sdio_rxf_in_kthread_enabled && skb_to_rxfq) { if (!skb_head) skb_head = skb_to_rxfq; else @@ -2265,7 +2265,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->channel = SDPCM_EVENT_CHANNEL; } - if (brcmf_feat_is_sdio_rxf_in_kthread(bus_if->drvr) && skb_head) + if (settings && settings->sdio_rxf_in_kthread_enabled && skb_head) brcmf_sched_rxf(bus, skb_head); rxcount = maxframes - rxleft; -- 2.25.1