From f607b10eb4eda4aed12760ee39bfbc1a18b64a32 Mon Sep 17 00:00:00 2001 From: Carter Chen Date: Thu, 25 Sep 2025 22:57:37 -0500 Subject: [PATCH] brcmfmac: re-download fw while encounter failure on fw download supporting re-download fw while encounter failure on fw download. Fixes SWLINUX-5347 Signed-off-by: Carter Chen --- .../broadcom/brcm80211/brcmfmac/sdio.c | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 5942d4c16bd3..aba018c34960 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -154,6 +154,9 @@ struct rte_console { #define BRCMF_FIRSTREAD (1 << 6) +#define MAX_INIT_RETRY_CNT 3 +static unsigned char global_init_retry = 0; + /* SBSDIO_DEVICE_CTL */ /* 1: device will assert busy signal when receiving CMD53 */ @@ -5673,6 +5676,25 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, return; free: + + if (global_init_retry < MAX_INIT_RETRY_CNT) { + global_init_retry++; + brcmf_err("global_init_retry:%d\n", global_init_retry); + + /* start by unregistering irqs */ + brcmf_sdiod_intr_unregister(bus->sdiodev); + + brcmf_sdiod_remove(bus->sdiodev); + + /* reset the adapter */ + sdio_claim_host(bus->sdiodev->func1); + mmc_hw_reset(bus->sdiodev->func1->card); + sdio_release_host(bus->sdiodev->func1); + + brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN); + return; + } + brcmf_free(sdiod->dev); claim: sdio_claim_host(sdiod->func1); @@ -5682,6 +5704,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, sdio_release_host(sdiod->func1); fail: brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); + device_release_driver(&sdiod->func2->dev); device_release_driver(dev); }