From 8d7cea6c4c18644a95da3f195c18787cfeb7e836 Mon Sep 17 00:00:00 2001
From: Carter Chen <carter.chen@infineon.com>
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 <carter.chen@infineon.com>
---
 .../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

