5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lin yu-hao.lin@nxp.com
[ Upstream commit 1c5d463c0770c6fa2037511a24fb17966fd07d97 ]
For SDIO IW416, due to a bug, FW may return ready before complete full initialization. Command timeout may occur at driver load after reboot. Workaround by adding 100ms delay at checking FW status.
Signed-off-by: David Lin yu-hao.lin@nxp.com Cc: stable@vger.kernel.org Reviewed-by: Francesco Dolcini francesco.dolcini@toradex.com Acked-by: Brian Norris briannorris@chromium.org Tested-by: Marcel Ziswiler marcel.ziswiler@toradex.com # Verdin AM62 (IW416) Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://msgid.link/20231208234029.2197-1-yu-hao.lin@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/sdio.c | 19 +++++++++++++++++++ drivers/net/wireless/marvell/mwifiex/sdio.h | 2 ++ 2 files changed, 21 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 919f1bae61dc..dd4bfb7d71ee 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -343,6 +343,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = false, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { @@ -358,6 +359,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { @@ -373,6 +375,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { @@ -388,6 +391,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { .can_dump_fw = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { @@ -404,6 +408,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { @@ -420,6 +425,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = true, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { @@ -436,6 +442,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { @@ -451,6 +458,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { .can_dump_fw = false, .can_auto_tdls = true, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { @@ -467,6 +475,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { .fw_dump_enh = true, .can_auto_tdls = true, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { @@ -482,6 +491,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, };
static struct memory_type_mapping generic_mem_type_map[] = { @@ -574,6 +584,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) card->fw_dump_enh = data->fw_dump_enh; card->can_auto_tdls = data->can_auto_tdls; card->can_ext_scan = data->can_ext_scan; + card->fw_ready_extra_delay = data->fw_ready_extra_delay; INIT_WORK(&card->work, mwifiex_sdio_work); }
@@ -777,6 +788,7 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) { + struct sdio_mmc_card *card = adapter->card; int ret = 0; u16 firmware_stat; u32 tries; @@ -794,6 +806,13 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, ret = -1; }
+ if (card->fw_ready_extra_delay && + firmware_stat == FIRMWARE_READY_SDIO) + /* firmware might pretend to be ready, when it's not. + * Wait a little bit more as a workaround. + */ + msleep(100); + return ret; }
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h index 4ed3988fa7d1..5fef84da4cbd 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.h +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -271,6 +271,7 @@ struct sdio_mmc_card { bool fw_dump_enh; bool can_auto_tdls; bool can_ext_scan; + bool fw_ready_extra_delay;
struct mwifiex_sdio_mpa_tx mpa_tx; struct mwifiex_sdio_mpa_rx mpa_rx; @@ -294,6 +295,7 @@ struct mwifiex_sdio_device { bool fw_dump_enh; bool can_auto_tdls; bool can_ext_scan; + bool fw_ready_extra_delay; };
/*