From: Chin-Yen Lee timlee@realtek.com
[ Upstream commit 02a55c0009a55b204e1e5c17295431f0a9e7d3b6 ]
In current wow flow, driver calls rtw_wow_fw_start and sleep for 100ms, to wait firmware finish preliminary work and then update the value of WOWLAN_WAKE_REASON register to zero. But later firmware will start wow function with power-saving mode, in which mode the value of WOWLAN_WAKE_REASON register is 0xea. So driver may get 0xea value and return fail. We use read_poll_timeout instead to check the value to avoid this issue.
Signed-off-by: Chin-Yen Lee timlee@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210728014335.8785-2-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/wow.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/wow.c b/drivers/net/wireless/realtek/rtw88/wow.c index fc9544f4e5e4..bdccfa70dddc 100644 --- a/drivers/net/wireless/realtek/rtw88/wow.c +++ b/drivers/net/wireless/realtek/rtw88/wow.c @@ -283,15 +283,26 @@ static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev)
static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable) { - /* wait 100ms for wow firmware to finish work */ - msleep(100); + int ret; + u8 check; + u32 check_dis;
if (wow_enable) { - if (rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON)) + ret = read_poll_timeout(rtw_read8, check, !check, 1000, + 100000, true, rtwdev, + REG_WOWLAN_WAKE_REASON); + if (ret) goto wow_fail; } else { - if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) || - rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE)) + ret = read_poll_timeout(rtw_read32_mask, check_dis, + !check_dis, 1000, 100000, true, rtwdev, + REG_FE1IMR, BIT_FS_RXDONE); + if (ret) + goto wow_fail; + ret = read_poll_timeout(rtw_read32_mask, check_dis, + !check_dis, 1000, 100000, false, rtwdev, + REG_RXPKT_NUM, BIT_RW_RELEASE); + if (ret) goto wow_fail; }