wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to register
authorPing-Ke Shih <pkshih@realtek.com>
Wed, 30 Oct 2024 02:21:32 +0000 (10:21 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Wed, 6 Nov 2024 05:59:18 +0000 (13:59 +0800)
For WiFi 6 chips, firmware secure boot will run on a IDMEM mode specified
in firmware header. Retrieve the mode from firmware, and set to registers
accordingly.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20241030022135.11688-6-pkshih@realtek.com
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
drivers/net/wireless/realtek/rtw89/reg.h

index 3d36e17b2ff80d8eb46da928ea8217756e8544da..08e95c780982d23c3ce296b6f4bc303827736e3f 100644 (file)
@@ -141,6 +141,7 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
        info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_W6_SEC_NUM);
        base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
        info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR);
+       info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE);
 
        if (info->dynamic_hdr_en) {
                info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN);
@@ -366,6 +367,7 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
        info->dsp_checksum = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_DSP_CHKSUM);
        base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
        info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
+       info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE);
 
        if (info->dynamic_hdr_en) {
                info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
@@ -1455,6 +1457,8 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,
                return ret;
        }
 
+       rtw89_fwdl_secure_idmem_share_mode(rtwdev, info.idmem_share_mode);
+
        if (rtwdev->chip->chip_id == RTL8922A &&
            (fw_suit->type == RTW89_FW_NORMAL || fw_suit->type == RTW89_FW_WOWLAN))
                rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0x20248000);
index 83fcd5edc0575096cc8051f9b6f2411785624d0d..bd768026484928d9fded7a2076e993a5516e2740 100644 (file)
@@ -276,6 +276,7 @@ struct rtw89_fw_bin_info {
        u32 hdr_len;
        bool dynamic_hdr_en;
        u32 dynamic_hdr_len;
+       u8 idmem_share_mode;
        bool dsp_checksum;
        bool secure_section_exist;
        struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM];
@@ -564,6 +565,7 @@ struct rtw89_fw_hdr {
 #define FW_HDR_W6_SEC_NUM GENMASK(15, 8)
 #define FW_HDR_W7_PART_SIZE GENMASK(15, 0)
 #define FW_HDR_W7_DYN_HDR BIT(16)
+#define FW_HDR_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
 #define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24)
 
 struct rtw89_fw_hdr_section_v1 {
@@ -616,6 +618,7 @@ struct rtw89_fw_hdr_v1 {
 #define FW_HDR_V1_W6_DSP_CHKSUM BIT(24)
 #define FW_HDR_V1_W7_PART_SIZE GENMASK(15, 0)
 #define FW_HDR_V1_W7_DYN_HDR BIT(16)
+#define FW_HDR_V1_W7_IDMEM_SHARE_MODE GENMASK(21, 18)
 
 enum rtw89_fw_mss_pool_rmp_tbl_type {
        MSS_POOL_RMP_TBL_BITMASK = 0x0,
index 7ed29bc69009d0d47bdabded3bba03b18e285e98..8985bd8fa38f4946d89101a681abdf54206e3211 100644 (file)
@@ -6621,6 +6621,20 @@ int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev,
                                        rtwdev, R_AX_WCPU_FW_CTRL);
 }
 
+static
+void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode)
+{
+       struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+
+       if (!sec->secure_boot)
+               return;
+
+       rtw89_write32_mask(rtwdev, R_AX_WCPU_FW_CTRL,
+                          B_AX_IDMEM_SHARE_MODE_RECORD_MASK, mode);
+       rtw89_write32_set(rtwdev, R_AX_WCPU_FW_CTRL,
+                         B_AX_IDMEM_SHARE_MODE_RECORD_VALID);
+}
+
 const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
        .band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
        .filter_model_addr = R_AX_FILTER_MODEL_ADDR,
@@ -6674,6 +6688,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
        .fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax,
        .fwdl_get_status = rtw89_fw_get_rdy_ax,
        .fwdl_check_path_ready = rtw89_fwdl_check_path_ready_ax,
+       .fwdl_secure_idmem_share_mode = rtw89_fwdl_secure_idmem_share_mode_ax,
        .parse_efuse_map = rtw89_parse_efuse_map_ax,
        .parse_phycap_map = rtw89_parse_phycap_map_ax,
        .cnv_efuse_state = rtw89_cnv_efuse_state_ax,
index 4d4b505e3bc9b6a633e877cb8069a2cf969e6c86..18579c020548458f85d28e53ed0a1cc5d5d8de6b 100644 (file)
@@ -985,6 +985,7 @@ struct rtw89_mac_gen_def {
                                bool dlfw, bool include_bb);
        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);
+       void (*fwdl_secure_idmem_share_mode)(struct rtw89_dev *rtwdev, u8 mode);
        int (*parse_efuse_map)(struct rtw89_dev *rtwdev);
        int (*parse_phycap_map)(struct rtw89_dev *rtwdev);
        int (*cnv_efuse_state)(struct rtw89_dev *rtwdev, bool idle);
@@ -1495,4 +1496,14 @@ int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
                                  struct rtw89_mac_dle_rsvd_qt_cfg *cfg);
 int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable);
 
+static inline
+void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode)
+{
+       const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+       if (!mac->fwdl_secure_idmem_share_mode)
+               return;
+
+       return mac->fwdl_secure_idmem_share_mode(rtwdev, mode);
+}
 #endif
index e0d7cf9fd7eec32c16fcbb90e827d7d905a10914..f7a396c8a3cd50ecf398b4944bd4edd3788b035e 100644 (file)
@@ -2600,6 +2600,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
        .fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be,
        .fwdl_get_status = fwdl_get_status_be,
        .fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be,
+       .fwdl_secure_idmem_share_mode = NULL,
        .parse_efuse_map = rtw89_parse_efuse_map_be,
        .parse_phycap_map = rtw89_parse_phycap_map_be,
        .cnv_efuse_state = rtw89_cnv_efuse_state_be,
index 69678eab230939e4e463e9f16cc82a0c67eea894..18ec7c0252fb8e14fad850ec0b2d568e94e64d76 100644 (file)
 #define R_AX_HALT_C2H 0x016C
 
 #define R_AX_WCPU_FW_CTRL 0x01E0
+#define B_AX_IDMEM_SHARE_MODE_RECORD_MASK GENMASK(27, 24)
+#define B_AX_IDMEM_SHARE_MODE_RECORD_VALID BIT(23)
 #define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5)
 #define B_AX_FWDL_PATH_RDY BIT(2)
 #define B_AX_H2C_PATH_RDY BIT(1)