wifi: rtw89: fw: add checking type for variant type of firmware
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 1 Sep 2023 07:39:52 +0000 (15:39 +0800)
committerKalle Valo <kvalo@kernel.org>
Thu, 7 Sep 2023 05:57:15 +0000 (08:57 +0300)
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
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac.h
drivers/net/wireless/realtek/rtw89/mac_be.c

index d782dc8397e070e481bac8144525a780fa14e4f7..62778d056653924dcb84756c8b8adce06e81f3ec 100644 (file)
@@ -3610,6 +3610,14 @@ struct rtw89_mac_info {
        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,
index 40442c409aedbb5cae1ecda0c501672cdd909606..68a9d81164cc4dce4d05b80515204b35025cd06d 100644 (file)
@@ -47,7 +47,7 @@ struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len)
        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;
@@ -55,7 +55,7 @@ int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)
 
        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:
@@ -837,13 +837,6 @@ static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw,
                section_info++;
        }
 
-       mdelay(5);
-
-       ret = rtw89_fw_check_rdy(rtwdev);
-       if (ret) {
-               rtw89_warn(rtwdev, "download firmware fail\n");
-               return ret;
-       }
 
        return 0;
 }
@@ -924,6 +917,14 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
        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:
index 430e5cff0510c8fc6fad70a9147ad96f44fec148..cba37315e3f92ec9c6d87ec4e4ea3d158c0ccfcb 100644 (file)
@@ -3620,7 +3620,7 @@ struct rtw89_fw_h2c_rf_get_mccch {
 
 #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 *
index fe8dbb2fe8e1e218a95a449f05e11cc5282cd5bb..f02828f295ced632b4d7840182f0097d0a95514f 100644 (file)
@@ -3505,7 +3505,7 @@ static int rtw89_mac_enable_cpu_ax(struct rtw89_dev *rtwdev, u8 boot_reason, boo
        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;
        }
@@ -5684,7 +5684,7 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
        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);
 
index ecf143a671c657e2496ab7acd1806c10e60460ae..0b772c37d56698e5f7b56530aa4390f01de4b55e 100644 (file)
@@ -861,7 +861,7 @@ struct rtw89_mac_gen_def {
 
        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);
 };
 
index 0b389eb656aceab2674362f2f87970054967f1ee..2a80d8bb4758af6bbb3b41b924b76f6b669c3004 100644 (file)
@@ -100,7 +100,7 @@ static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
        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;
        }
@@ -129,13 +129,34 @@ static const u8 fwdl_status_map[] = {
        [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];