diff options
author | Tony Lindgren <tony@atomide.com> | 2021-06-03 09:28:14 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2021-06-14 18:47:40 +0300 |
commit | 11ef6bc846dcdce838f0b00c5f6a562c57e5d43b (patch) | |
tree | 6c37c575e0a2d7b6aedf3f6558b0c4e45ab49ecd /drivers/net/wireless/ti/wl12xx | |
parent | 86f1ea9d645edb16358e4a3e1602e1cec81e5048 (diff) | |
download | linux-11ef6bc846dcdce838f0b00c5f6a562c57e5d43b.tar.bz2 |
wlcore/wl12xx: Fix wl12xx get_mac error if device is in ELP
At least on wl12xx, reading the MAC after boot can fail with a warning
at drivers/net/wireless/ti/wlcore/sdio.c:78 wl12xx_sdio_raw_read.
The failed call comes from wl12xx_get_mac() that wlcore_nvs_cb() calls
after request_firmware_work_func().
After the error, no wireless interface is created. Reloading the wl12xx
module makes the interface work.
Turns out the wlan controller can be in a low-power ELP state after the
boot from the bootloader or kexec, and needs to be woken up first.
Let's wake the hardware and add a sleep after that similar to
wl12xx_pre_boot() is already doing.
Note that a similar issue could exist for wl18xx, but I have not seen it
so far. And a search for wl18xx_get_mac and wl12xx_sdio_raw_read did not
produce similar errors.
Cc: Carl Philipp Klemm <philipp@uvos.xyz>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210603062814.19464-1-tony@atomide.com
Diffstat (limited to 'drivers/net/wireless/ti/wl12xx')
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/main.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 9d7dbfe7fe0c..c6da0cfb4afb 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1503,6 +1503,13 @@ static int wl12xx_get_fuse_mac(struct wl1271 *wl) u32 mac1, mac2; int ret; + /* Device may be in ELP from the bootloader or kexec */ + ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + if (ret < 0) + goto out; + + usleep_range(500000, 700000); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); if (ret < 0) goto out; |