wifi: rtw89: download firmware with five times retry

[ Upstream commit a9e1b0ec5bdeedcf062416af4081aa005f8bf1e7 ]

After firmware boots, it reads keys info from efuse and checks secure
checksum, but suddenly failed to access efuse resulting in probe failure,
and driver throws messages:

  rtw89_8852be 0000:03:00.0: fw security fail
  rtw89_8852be 0000:03:00.0: download firmware fail
  rtw89_8852be 0000:03:00.0: [ERR]fwdl 0x1E0 = 0xe2
  rtw89_8852be 0000:03:00.0: [ERR]fwdl 0x83F0 = 0x210090

Retry five times to resolve rare abnormal hardware state.

Signed-off-by: Chia-Yuan Li <leo.li@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/20240329015251.22762-2-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Chia-Yuan Li 2024-03-29 09:52:48 +08:00 committed by Greg Kroah-Hartman
parent 5e4f25091e
commit 3edfa2a38c

View File

@ -1349,13 +1349,12 @@ dump:
static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
{
u32 val32;
u16 val16;
val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2);
rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16);
val32 = rtw89_read32(rtwdev, R_AX_BOOT_DBG);
rtw89_err(rtwdev, "[ERR]fwdl 0x83F0 = 0x%x\n", val32);
rtw89_fw_prog_cnt_dump(rtwdev);
}
@ -1394,8 +1393,9 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
return 0;
}
int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
bool include_bb)
static
int __rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
bool include_bb)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_fw_info *fw_info = &rtwdev->fw;
@ -1433,7 +1433,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
if (ret) {
rtw89_warn(rtwdev, "download firmware fail\n");
return ret;
goto fwdl_err;
}
return ret;
@ -1443,6 +1443,21 @@ fwdl_err:
return ret;
}
int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
bool include_bb)
{
int retry;
int ret;
for (retry = 0; retry < 5; retry++) {
ret = __rtw89_fw_download(rtwdev, type, include_bb);
if (!ret)
return 0;
}
return ret;
}
int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_info *fw = &rtwdev->fw;