From 28660bdbd867c48a6e5377932ea4fb52651997fc Mon Sep 17 00:00:00 2001
From: Ian Lin <ian.lin@infineon.com>
Date: Thu, 25 Jan 2024 19:41:27 -0600
Subject: [PATCH 234/296] brcmfmac: separate 43022 sdio download function from
 common flow

After accommodate 43022 flow, the common flow become wrong
for some other chips, thus separate them to two function

Signed-off-by: Ian Lin <ian.lin@infineon.com>
---
 .../broadcom/brcm80211/brcmfmac/bcmsdh.c      |  6 +-
 .../broadcom/brcm80211/brcmfmac/sdio.c        | 86 ++++++++++++++-----
 2 files changed, 67 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 62b5e71c74ba..95696d2a17dd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -257,14 +257,14 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
 	if (retval)
 		goto out;
 
-	brcmf_dbg(TRACE, "reading from addr 0x%x bar0 0x%08x ", addr, sdiodev->sbwad);
+	brcmf_dbg(SDIO, "reading from addr 0x%x bar0 0x%08x ", addr, sdiodev->sbwad);
 
 	addr &= SBSDIO_SB_OFT_ADDR_MASK;
 	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
 	data = sdio_readl(sdiodev->func1, addr, &retval);
 
-	brcmf_dbg(TRACE, "data 0x%08x\n", data);
+	brcmf_dbg(SDIO, "data 0x%08x\n", data);
 out:
 	if (ret)
 		*ret = retval;
@@ -281,7 +281,7 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr,
 	if (retval)
 		goto out;
 
-	brcmf_dbg(TRACE, "writing 0x%08x to addr 0x%x bar0 0x%08x\n", data, addr, sdiodev->sbwad);
+	brcmf_dbg(SDIO, "writing 0x%08x to addr 0x%x bar0 0x%08x\n", data, addr, sdiodev->sbwad);
 
 	addr &= SBSDIO_SB_OFT_ADDR_MASK;
 	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index c896ffc93c97..c807f2f7c7de 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4029,7 +4029,7 @@ static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,
 	return err;
 }
 
-static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
+static int brcmf_sdio_download_firmware_43022(struct brcmf_sdio *bus,
 					const struct firmware *fw,
 					void *nvram, u32 nvlen)
 {
@@ -4042,7 +4042,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
 	rstvec = get_unaligned_le32(fw->data);
 	brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
 
-	if (bus->ci->blhs && bus->ci->chip == CY_CC_43022_CHIP_ID) {
+	if (bus->ci->blhs) {
 		bcmerror = bus->ci->blhs->pre_nvramdl(bus->ci);
 		if (bcmerror) {
 			brcmf_err("NVRAM download preparation failed\n");
@@ -4083,27 +4083,66 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
 			brcmf_fw_nvram_free(nvram);
 			goto err;
 		}
-	} else if (bus->ci->blhs) {
-		bcmerror = bus->ci->blhs->prep_fwdl(bus->ci);
+	} else {
+		bcmerror = brcmf_sdio_download_code_file(bus, fw);
+		release_firmware(fw);
 		if (bcmerror) {
-			brcmf_err("FW download preparation failed\n");
-			release_firmware(fw);
+			brcmf_err("dongle image file download failed\n");
 			brcmf_fw_nvram_free(nvram);
 			goto err;
 		}
+
+		bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen);
+		brcmf_fw_nvram_free(nvram);
+		if (bcmerror) {
+			brcmf_err("dongle nvram file download failed\n");
+			goto err;
+		}
+
+		/* Take arm out of reset */
+		if (!brcmf_chip_set_active(bus->ci, rstvec)) {
+			brcmf_err("error getting out of ARM core reset\n");
+			goto err;
+		}
 	}
+err:
+	brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
+	sdio_release_host(bus->sdiodev->func1);
+	return bcmerror;
+}
 
-	if (!(bus->ci->blhs)) {
-		bcmerror = brcmf_sdio_download_code_file(bus, fw);
-		release_firmware(fw);
+static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
+					const struct firmware *fw,
+					void *nvram, u32 nvlen)
+{
+	int bcmerror;
+	u32 rstvec;
+
+	sdio_claim_host(bus->sdiodev->func1);
+	brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
+
+	rstvec = get_unaligned_le32(fw->data);
+	brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
+
+	if (bus->ci->blhs) {
+		bcmerror = bus->ci->blhs->prep_fwdl(bus->ci);
 		if (bcmerror) {
-			brcmf_err("dongle image file download failed\n");
+			brcmf_err("FW download preparation failed\n");
+			release_firmware(fw);
 			brcmf_fw_nvram_free(nvram);
 			goto err;
 		}
 	}
 
-	if (bus->ci->blhs && (!(bus->ci->chip == CY_CC_43022_CHIP_ID))) {
+	bcmerror = brcmf_sdio_download_code_file(bus, fw);
+	release_firmware(fw);
+	if (bcmerror) {
+		brcmf_err("dongle image file download failed\n");
+		brcmf_fw_nvram_free(nvram);
+		goto err;
+	}
+
+	if (bus->ci->blhs) {
 		bcmerror = bus->ci->blhs->post_fwdl(bus->ci);
 		if (bcmerror) {
 			brcmf_err("FW download failed, err=%d\n", bcmerror);
@@ -4118,18 +4157,15 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
 			goto err;
 		}
 	}
-	if (!(bus->ci->blhs)) {
-		bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen);
-		brcmf_fw_nvram_free(nvram);
-		if (bcmerror) {
-			brcmf_err("dongle nvram file download failed\n");
-			goto err;
-		}
+
+	bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen);
+	brcmf_fw_nvram_free(nvram);
+	if (bcmerror) {
+		brcmf_err("dongle nvram file download failed\n");
+		goto err;
 	}
 
-	if (bus->ci->blhs && bus->ci->chip == CY_CC_43022_CHIP_ID) {
-		brcmf_err("Avoid resetting ARM in 43022 secured chip\n");
-	} else if (bus->ci->blhs && (!(bus->ci->chip == CY_CC_43022_CHIP_ID))) {
+	if (bus->ci->blhs) {
 		bus->ci->blhs->post_nvramdl(bus->ci);
 	} else {
 		/* Take arm out of reset */
@@ -4138,12 +4174,14 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
 			goto err;
 		}
 	}
+
 err:
 	brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
 	sdio_release_host(bus->sdiodev->func1);
 	return bcmerror;
 }
 
+
 static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
 {
 	if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
@@ -5235,7 +5273,11 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
 
 	/* try to download image and nvram to the dongle */
 	bus->alp_only = true;
-	err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
+	if (bus->ci->chip == CY_CC_43022_CHIP_ID) {
+		err = brcmf_sdio_download_firmware_43022(bus, code, nvram, nvram_len);
+	} else {
+		err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
+	}
 	if (err)
 		goto fail;
 	bus->alp_only = false;
-- 
2.25.1

