For WiFi 6 chips, there is only single one firmware i.e. WiFi CPU firmware,
so no need an argument to discriminate them. For WiFi 7 chips, BB MCU
firmware is introduced, and we need to check it ready after downloading.
For each type of firmware, we need to check corresponding hardware ready
bit. After downloading all firmware, check status code to determine if
all things are ready.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230901073956.54203-5-pkshih@realtek.com
struct rtw89_wait_info fw_ofld_wait;
};
+enum rtw89_fwdl_check_type {
+ RTW89_FWDL_CHECK_FREERTOS_DONE,
+ RTW89_FWDL_CHECK_WCPU_FWDL_DONE,
+ RTW89_FWDL_CHECK_DCPU_FWDL_DONE,
+ RTW89_FWDL_CHECK_BB0_FWDL_DONE,
+ RTW89_FWDL_CHECK_BB1_FWDL_DONE,
+};
+
enum rtw89_fw_type {
RTW89_FW_NORMAL = 1,
RTW89_FW_WOWLAN = 3,
return rtw89_fw_h2c_alloc_skb(rtwdev, len, false);
}
-int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)
+int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u8 val;
ret = read_poll_timeout_atomic(mac->fwdl_get_status, val,
val == RTW89_FWDL_WCPU_FW_INIT_RDY,
- 1, FWDL_WAIT_CNT, false, rtwdev);
+ 1, FWDL_WAIT_CNT, false, rtwdev, type);
if (ret) {
switch (val) {
case RTW89_FWDL_CHECKSUM_FAIL:
section_info++;
}
- mdelay(5);
-
- ret = rtw89_fw_check_rdy(rtwdev);
- if (ret) {
- rtw89_warn(rtwdev, "download firmware fail\n");
- return ret;
- }
return 0;
}
rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX;
rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX;
+ mdelay(5);
+
+ ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
+ if (ret) {
+ rtw89_warn(rtwdev, "download firmware fail\n");
+ return ret;
+ }
+
return ret;
fwdl_err:
#define FWDL_WAIT_CNT 400000
-int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev);
+int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type);
int rtw89_fw_recognize(struct rtw89_dev *rtwdev);
int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev);
const struct firmware *
if (!dlfw) {
mdelay(5);
- ret = rtw89_fw_check_rdy(rtwdev);
+ ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
if (ret)
return ret;
}
return ret;
}
-static u8 rtw89_fw_get_rdy_ax(struct rtw89_dev *rtwdev)
+static u8 rtw89_fw_get_rdy_ax(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
{
u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL);
void (*disable_cpu)(struct rtw89_dev *rtwdev);
int (*fwdl_enable_wcpu)(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw);
- u8 (*fwdl_get_status)(struct rtw89_dev *rtwdev);
+ u8 (*fwdl_get_status)(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type);
int (*fwdl_check_path_ready)(struct rtw89_dev *rtwdev, bool h2c_or_fwdl);
};
rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN);
if (!dlfw) {
- ret = rtw89_fw_check_rdy(rtwdev);
+ ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
if (ret)
return ret;
}
[9] = RTW89_FWDL_RSVD0,
};
-static u8 fwdl_get_status_be(struct rtw89_dev *rtwdev)
+static u8 fwdl_get_status_be(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
{
+ bool check_pass = false;
u32 val32;
u8 st;
val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL);
+ switch (type) {
+ case RTW89_FWDL_CHECK_WCPU_FWDL_DONE:
+ check_pass = !(val32 & B_BE_WLANCPU_FWDL_EN);
+ break;
+ case RTW89_FWDL_CHECK_DCPU_FWDL_DONE:
+ check_pass = !(val32 & B_BE_DATACPU_FWDL_EN);
+ break;
+ case RTW89_FWDL_CHECK_BB0_FWDL_DONE:
+ check_pass = !(val32 & B_BE_BBMCU0_FWDL_EN);
+ break;
+ case RTW89_FWDL_CHECK_BB1_FWDL_DONE:
+ check_pass = !(val32 & B_BE_BBMCU1_FWDL_EN);
+ break;
+ default:
+ break;
+ }
+
+ if (check_pass)
+ return RTW89_FWDL_WCPU_FW_INIT_RDY;
+
st = u32_get_bits(val32, B_BE_WCPU_FWDL_STATUS_MASK);
if (st < ARRAY_SIZE(fwdl_status_map))
return fwdl_status_map[st];