wifi: rtw89: download firmware with five times retry
authorChia-Yuan Li <leo.li@realtek.com>
Fri, 29 Mar 2024 01:52:48 +0000 (09:52 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Wed, 3 Apr 2024 02:41:31 +0000 (10:41 +0800)
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
drivers/net/wireless/realtek/rtw89/fw.c

index e8a270b417e1fd8fb495fd2eedea55e488272b21..74d0d515ada0e5decfb44825d648478aa59aabc9 100644 (file)
@@ -1350,13 +1350,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);
 }
@@ -1395,8 +1394,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;
@@ -1434,7 +1434,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;
@@ -1444,6 +1444,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;