wifi: rtw89: generalize download firmware flow to support WiFi 7 chips
Ping-Ke Shih
maintainerv2 cover wifi: rtw89: generalize download firmware flow to support WiFi 7 chips
WiFi 7 chips can download BB MCU firmware via the same path as existing WiFi CPU firmware, and we need to check them successful after downloading, so use a corresponding hardware bit to confirm certain firmware is ready.
To reuse the flow, uses mac_gen pointers to adapt WiFi 6/7 chips with different settings and checking rules. Also, refine flow to support download firmware one by one. Then, changes of flow look like
1. initial setup --> no logic change
2. download WiFi CPU firmware --> 2. for all firmware suits
2.1. download WiFi CPU firmware &
check ready
2.2. download BB MCU firmware &
check ready
3. check ready by status code --> no logic change
v2:
- correct patch 3/8 that I miss a change from internal commit
Ping-Ke Shih (8):
wifi: rtw89: fw: move polling function of firmware path ready to an
individual function
wifi: rtw89: fw: generalize download firmware flow by mac_gen pointers
wifi: rtw89: fw: implement supported functions of download firmware
for WiFi 7 chips
wifi: rtw89: fw: add checking type for variant type of firmware
wifi: rtw89: fw: propagate an argument include_bb for BB MCU firmware
wifi: rtw89: 8922a: add chip_ops::bb_preinit to enable BB before
downloading firmware
wifi: rtw89: fw: refine download flow to support variant firmware
suits
wifi: rtw89: 8922a: set memory heap address for secure firmware
drivers/net/wireless/realtek/rtw89/core.c | 2 +- drivers/net/wireless/realtek/rtw89/core.h | 19 +++ drivers/net/wireless/realtek/rtw89/fw.c | 122 +++++++++----- drivers/net/wireless/realtek/rtw89/fw.h | 7 +- drivers/net/wireless/realtek/rtw89/mac.c | 45 ++++- drivers/net/wireless/realtek/rtw89/mac.h | 10 +- drivers/net/wireless/realtek/rtw89/mac_be.c | 156 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 109 ++++++++++++ drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + drivers/net/wireless/realtek/rtw89/wow.c | 4 +- 13 files changed, 429 insertions(+), 53 deletions(-)
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 1/8 wifi: rtw89: fw: move polling function of firmware path ready to an individual function
To download firmware, we need to check path is ready. There are two kinds of path -- one is to download firmware header, and the other is to download firmware body.
Since the polling method is different from WiFi 7 chips, make it to be an individual function, and then we can reuse the download flow.
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/fw.c | 11 ++--------- drivers/net/wireless/realtek/rtw89/fw.h | 2 ++ drivers/net/wireless/realtek/rtw89/mac.c | 11 +++++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ 4 files changed, 17 insertions(+), 9 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +2 -9
@@ -54,7 +54,6 @@ static u8 _fw_get_rdy(struct rtw89_dev *rtwdev)return FIELD_GET (B_AX_WCPU_FWDL_STS_MASK , val); } -#define FWDL_WAIT_CNT 400000int rtw89_fw_check_rdy (struct rtw89_dev *rtwdev) {u8 val;
@@ -768,7 +767,6 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 lstatic int rtw89_fw_download_hdr (struct rtw89_dev *rtwdev,const u8 *fw,u32 len) { -u8 val;int ret; ret =__rtw89_fw_download_hdr (rtwdev, fw, len);
@@ -777,9 +775,7 @@ static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 lenreturn ret; } - ret =read_poll_timeout_atomic (rtw89_read8, val, val &B_AX_FWDL_PATH_RDY , -1 ,FWDL_WAIT_CNT , false, - rtwdev,R_AX_WCPU_FW_CTRL ); + ret =rtw89_fwdl_check_path_ready_ax (rtwdev, false);if (ret) {rtw89_err (rtwdev,"[ERR]FWDL path ready\n" );return ret;
@@ -892,7 +888,6 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)struct rtw89_fw_info *fw_info = &rtwdev->fw;struct rtw89_fw_suit *fw_suit =rtw89_fw_suit_get (rtwdev, type);struct rtw89_fw_bin_info info; -u8 val;int ret;rtw89_mac_disable_cpu (rtwdev);
@@ -906,9 +901,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) goto fwdl_err; } - ret =read_poll_timeout_atomic (rtw89_read8, val, val &B_AX_H2C_PATH_RDY , -1 ,FWDL_WAIT_CNT , false, - rtwdev,R_AX_WCPU_FW_CTRL ); + ret =rtw89_fwdl_check_path_ready_ax (rtwdev, true);if (ret) {rtw89_err (rtwdev,"[ERR]H2C path ready\n" ); goto fwdl_err;
drivers/net/wireless/realtek/rtw89/fw.h +2 -0
@@ -3618,6 +3618,8 @@ struct rtw89_fw_h2c_rf_get_mccch {#define RTW89_FW_BACKTRACE_MAX_SIZE 512/* 8 * 64 (entries) */ #define RTW89_FW_BACKTRACE_KEY 0xBACEBACE +#define FWDL_WAIT_CNT 400000 +int rtw89_fw_check_rdy (struct rtw89_dev *rtwdev);int rtw89_fw_recognize (struct rtw89_dev *rtwdev);int rtw89_fw_recognize_elements (struct rtw89_dev *rtwdev);
drivers/net/wireless/realtek/rtw89/mac.c +11 -0
@@ -5684,6 +5684,17 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,return ret; } +int rtw89_fwdl_check_path_ready_ax (struct rtw89_dev *rtwdev, +bool h2c_or_fwdl) +{ +u8 check = h2c_or_fwdl ?B_AX_H2C_PATH_RDY :B_AX_FWDL_PATH_RDY ; +u8 val; + +return read_poll_timeout_atomic (rtw89_read8, val, val & check, +1 ,FWDL_WAIT_CNT , false, + rtwdev,R_AX_WCPU_FW_CTRL ); +} +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 ,
drivers/net/wireless/realtek/rtw89/mac.h +2 -0
@@ -1207,5 +1207,7 @@ int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow);int rtw89_mac_ptk_drop_by_band_and_wait (struct rtw89_dev *rtwdev,enum rtw89_mac_idx band);void rtw89_mac_hw_mgnt_sec (struct rtw89_dev *rtwdev,bool wow); +int rtw89_fwdl_check_path_ready_ax (struct rtw89_dev *rtwdev, +bool h2c_or_fwdl);#endif
Signature · 1 line
2.25.1
Re: [PATCH v2 1/8] wifi: rtw89: fw: move polling function of firmware path ready to an individual function
Quoted 8 lines · Ping-Ke Shih
To download firmware, we need to check path is ready. There are two kinds of path -- one is to download firmware header, and the other is to download firmware body.
Since the polling method is different from WiFi 7 chips, make it to be an individual function, and then we can reuse the download flow.
Signed-off-by Ping-Ke Shih <[email protected]>
8 patches applied to wireless-next.git, thanks.
80e706a85cb5 wifi: rtw89: fw: move polling function of firmware path ready to an individual function ae4dc23d139c wifi: rtw89: fw: generalize download firmware flow by mac_gen pointers 68261ddbb2bc wifi: rtw89: fw: implement supported functions of download firmware for WiFi 7 chips fa31a8c58d6e wifi: rtw89: fw: add checking type for variant type of firmware a712eef681ed wifi: rtw89: fw: propagate an argument include_bb for BB MCU firmware c6ea2a8391a5 wifi: rtw89: 8922a: add chip_ops::bb_preinit to enable BB before downloading firmware 38bae445a30b wifi: rtw89: fw: refine download flow to support variant firmware suits b227c990de9a wifi: rtw89: 8922a: set memory heap address for secure firmware
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Ping-Ke Shih
maintainerPATCH v2 2/8 wifi: rtw89: fw: generalize download firmware flow by mac_gen pointers
In reply to Ping-Ke ShihIn order to reuse the flow to download firmware, define some mac_gen::ops to implement them for WiFi 6 and 7 chips individually. This doesn't change logic at all.
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/fw.c | 21 +++++++++------------ drivers/net/wireless/realtek/rtw89/mac.c | 17 +++++++++++++++-- drivers/net/wireless/realtek/rtw89/mac.h | 9 +++++---- 3 files changed, 29 insertions(+), 18 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +9 -12
@@ -47,19 +47,13 @@ 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); } -static u8 _fw_get_rdy (struct rtw89_dev *rtwdev) -{ -u8 val =rtw89_read8 (rtwdev,R_AX_WCPU_FW_CTRL ); - -return FIELD_GET (B_AX_WCPU_FWDL_STS_MASK , val); -} -int rtw89_fw_check_rdy (struct rtw89_dev *rtwdev) { +const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;u8 val;int ret; - ret =read_poll_timeout_atomic (_fw_get_rdy, val, + ret =read_poll_timeout_atomic (mac->fwdl_get_status, val, val ==RTW89_FWDL_WCPU_FW_INIT_RDY ,1 ,FWDL_WAIT_CNT , false, rtwdev);if (ret) {
@@ -77,6 +71,7 @@ int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)return -EINVAL ;default : +rtw89_err (rtwdev,"fw unexpected status %d\n" , val);return -EBUSY ; } }
@@ -767,6 +762,7 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 lstatic int rtw89_fw_download_hdr (struct rtw89_dev *rtwdev,const u8 *fw,u32 len) { +const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;int ret; ret =__rtw89_fw_download_hdr (rtwdev, fw, len);
@@ -775,7 +771,7 @@ static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 lenreturn ret; } - ret =rtw89_fwdl_check_path_ready_ax (rtwdev, false); + ret = mac->fwdl_check_path_ready (rtwdev, false);if (ret) {rtw89_err (rtwdev,"[ERR]FWDL path ready\n" );return ret;
@@ -885,13 +881,14 @@ static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)int rtw89_fw_download (struct rtw89_dev *rtwdev,enum rtw89_fw_type type) { +const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;struct rtw89_fw_info *fw_info = &rtwdev->fw;struct rtw89_fw_suit *fw_suit =rtw89_fw_suit_get (rtwdev, type);struct rtw89_fw_bin_info info;int ret; -rtw89_mac_disable_cpu (rtwdev); - ret =rtw89_mac_enable_cpu (rtwdev,0 , true); + mac->disable_cpu (rtwdev); + ret = mac->fwdl_enable_wcpu (rtwdev,0 , true);if (ret)return ret;
@@ -901,7 +898,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) goto fwdl_err; } - ret =rtw89_fwdl_check_path_ready_ax (rtwdev, true); + ret = mac->fwdl_check_path_ready (rtwdev, true);if (ret) {rtw89_err (rtwdev,"[ERR]H2C path ready\n" ); goto fwdl_err;
drivers/net/wireless/realtek/rtw89/mac.c +15 -2
@@ -3452,7 +3452,7 @@ static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev)rtw89_mac_mem_write (rtwdev,R_AX_WDT_STATUS , val32,RTW89_MAC_MEM_CPU_LOCAL ); } -void rtw89_mac_disable_cpu (struct rtw89_dev *rtwdev) +static void rtw89_mac_disable_cpu_ax (struct rtw89_dev *rtwdev) {clear_bit (RTW89_FLAG_FW_RDY , rtwdev->flags);
@@ -3467,7 +3467,7 @@ void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev)rtw89_write32_set (rtwdev,R_AX_PLATFORM_ENABLE ,B_AX_PLATFORM_EN ); } -int rtw89_mac_enable_cpu (struct rtw89_dev *rtwdev,u8 boot_reason,bool dlfw) +static int rtw89_mac_enable_cpu_ax (struct rtw89_dev *rtwdev,u8 boot_reason,bool dlfw) {u32 val;int ret;
@@ -5684,6 +5684,14 @@ 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) +{ +u8 val =rtw89_read8 (rtwdev,R_AX_WCPU_FW_CTRL ); + +return FIELD_GET (B_AX_WCPU_FWDL_STS_MASK , val); +} + +static int rtw89_fwdl_check_path_ready_ax (struct rtw89_dev *rtwdev,bool h2c_or_fwdl) {
@@ -5701,5 +5709,10 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = { .indir_access_addr = R_AX_INDIR_ACCESS_ENTRY, .mem_base_addrs = rtw89_mac_mem_base_addrs_ax, .rx_fltr = R_AX_RX_FLTR_OPT, + + .disable_cpu = rtw89_mac_disable_cpu_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, };EXPORT_SYMBOL (rtw89_mac_gen_ax);
drivers/net/wireless/realtek/rtw89/mac.h +5 -4
@@ -858,6 +858,11 @@ struct rtw89_mac_gen_def {u32 indir_access_addr;const u32 *mem_base_addrs;u32 rx_fltr; + +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); +int (*fwdl_check_path_ready)(struct rtw89_dev *rtwdev,bool h2c_or_fwdl); };extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax;
@@ -975,8 +980,6 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);void rtw89_mac_stop_ap (struct rtw89_dev *rtwdev,struct rtw89_vif *rtwvif);int rtw89_mac_remove_vif (struct rtw89_dev *rtwdev,struct rtw89_vif *vif); -void rtw89_mac_disable_cpu (struct rtw89_dev *rtwdev); -int rtw89_mac_enable_cpu (struct rtw89_dev *rtwdev,u8 boot_reason,bool dlfw);int rtw89_mac_enable_bb_rf (struct rtw89_dev *rtwdev);int rtw89_mac_disable_bb_rf (struct rtw89_dev *rtwdev);
@@ -1207,7 +1210,5 @@ int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow);int rtw89_mac_ptk_drop_by_band_and_wait (struct rtw89_dev *rtwdev,enum rtw89_mac_idx band);void rtw89_mac_hw_mgnt_sec (struct rtw89_dev *rtwdev,bool wow); -int rtw89_fwdl_check_path_ready_ax (struct rtw89_dev *rtwdev, -bool h2c_or_fwdl);#endif
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 3/8 wifi: rtw89: fw: implement supported functions of download firmware for WiFi 7 chips
In reply to Ping-Ke ShihTo work with generalized flow of download firmware, implement WiFi 7 specific functions to support it. These functions include disable/enable WiFi CPU, status of path ready, and status of firmware.
---
v2:
- correct settings I miss from internal commit
--- drivers/net/wireless/realtek/rtw89/mac_be.c | 131 ++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/reg.h | 107 ++++++++++++++++ 2 files changed, 238 insertions(+)
drivers/net/wireless/realtek/rtw89/mac_be.c +131 -0
@@ -2,6 +2,8 @@/* Copyright(c) 2019-2020 Realtek Corporation */ +#include "debug.h" +#include "fw.h" #include "mac.h" #include "reg.h"
@@ -28,11 +30,140 @@ static const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = { [RTW89_MAC_MEM_WD_PAGE] = WD_PAGE_BASE_ADDR_BE, }; +static void rtw89_mac_disable_cpu_be (struct rtw89_dev *rtwdev) +{ +u32 val32; + +clear_bit (RTW89_FLAG_FW_RDY , rtwdev->flags); + +rtw89_write32_clr (rtwdev,R_BE_PLATFORM_ENABLE ,B_BE_WCPU_EN ); +rtw89_write32_set (rtwdev,R_BE_PLATFORM_ENABLE ,B_BE_HOLD_AFTER_RESET ); +rtw89_write32_set (rtwdev,R_BE_PLATFORM_ENABLE ,B_BE_WCPU_EN ); + + val32 =rtw89_read32 (rtwdev,R_BE_WCPU_FW_CTRL ); + val32 &=B_BE_RUN_ENV_MASK ; +rtw89_write32 (rtwdev,R_BE_WCPU_FW_CTRL , val32); + +rtw89_write32_set (rtwdev,R_BE_DCPU_PLATFORM_ENABLE ,B_BE_DCPU_PLATFORM_EN ); + +rtw89_write32 (rtwdev,R_BE_UDM0 ,0 ); +rtw89_write32 (rtwdev,R_BE_HALT_C2H ,0 ); +rtw89_write32 (rtwdev,R_BE_UDM2 ,0 ); +} + +static void set_cpu_en (struct rtw89_dev *rtwdev) +{ +u32 set =B_BE_WLANCPU_FWDL_EN ; + +rtw89_write32_set (rtwdev,R_BE_WCPU_FW_CTRL , set); +} + +static int wcpu_on (struct rtw89_dev *rtwdev,u8 boot_reason,bool dlfw) +{ +u32 val32; +int ret; + +rtw89_write32_set (rtwdev,R_BE_UDM0 ,B_BE_UDM0_DBG_MODE_CTRL ); + + val32 =rtw89_read32 (rtwdev,R_BE_HALT_C2H ); +if (val32) { +rtw89_warn (rtwdev,"[SER] AON L2 Debug register not empty before Boot.\n" ); +rtw89_warn (rtwdev,"[SER] %s: R_BE_HALT_C2H = 0x%x\n" , __func__, val32); + } + val32 =rtw89_read32 (rtwdev,R_BE_UDM1 ); +if (val32) { +rtw89_warn (rtwdev,"[SER] AON L2 Debug register not empty before Boot.\n" ); +rtw89_warn (rtwdev,"[SER] %s: R_BE_UDM1 = 0x%x\n" , __func__, val32); + } + val32 =rtw89_read32 (rtwdev,R_BE_UDM2 ); +if (val32) { +rtw89_warn (rtwdev,"[SER] AON L2 Debug register not empty before Boot.\n" ); +rtw89_warn (rtwdev,"[SER] %s: R_BE_UDM2 = 0x%x\n" , __func__, val32); + } + +rtw89_write32 (rtwdev,R_BE_UDM1 ,0 ); +rtw89_write32 (rtwdev,R_BE_UDM2 ,0 ); +rtw89_write32 (rtwdev,R_BE_HALT_H2C ,0 ); +rtw89_write32 (rtwdev,R_BE_HALT_C2H ,0 ); +rtw89_write32 (rtwdev,R_BE_HALT_H2C_CTRL ,0 ); +rtw89_write32 (rtwdev,R_BE_HALT_C2H_CTRL ,0 ); + +rtw89_write32_set (rtwdev,R_BE_SYS_CLK_CTRL ,B_BE_CPU_CLK_EN ); +rtw89_write32_clr (rtwdev,R_BE_SYS_CFG5 , +B_BE_WDT_WAKE_PCIE_EN |B_BE_WDT_WAKE_USB_EN ); +rtw89_write32_clr (rtwdev,R_BE_WCPU_FW_CTRL , +B_BE_WDT_PLT_RST_EN |B_BE_WCPU_ROM_CUT_GET ); + +rtw89_write16_mask (rtwdev,R_BE_BOOT_REASON ,B_BE_BOOT_REASON_MASK , boot_reason); +rtw89_write32_clr (rtwdev,R_BE_PLATFORM_ENABLE ,B_BE_WCPU_EN ); +rtw89_write32_clr (rtwdev,R_BE_PLATFORM_ENABLE ,B_BE_HOLD_AFTER_RESET ); +rtw89_write32_set (rtwdev,R_BE_PLATFORM_ENABLE ,B_BE_WCPU_EN ); + +if (!dlfw) { + ret =rtw89_fw_check_rdy (rtwdev); +if (ret) +return ret; + } + +return 0 ; +} + +static int rtw89_mac_fwdl_enable_wcpu_be (struct rtw89_dev *rtwdev, +u8 boot_reason,bool dlfw) +{ +set_cpu_en (rtwdev); + +return wcpu_on (rtwdev, boot_reason, dlfw); +} + +static const u8 fwdl_status_map[] = { + [0 ] =RTW89_FWDL_INITIAL_STATE , + [1 ] =RTW89_FWDL_FWDL_ONGOING , + [4 ] =RTW89_FWDL_CHECKSUM_FAIL , + [5 ] =RTW89_FWDL_SECURITY_FAIL , + [6 ] =RTW89_FWDL_SECURITY_FAIL , + [7 ] =RTW89_FWDL_CV_NOT_MATCH , + [8 ] =RTW89_FWDL_RSVD0 , + [2 ] =RTW89_FWDL_WCPU_FWDL_RDY , + [3 ] =RTW89_FWDL_WCPU_FW_INIT_RDY , + [9 ] =RTW89_FWDL_RSVD0 , +}; + +static u8 fwdl_get_status_be (struct rtw89_dev *rtwdev) +{ +u32 val32; +u8 st; + + val32 =rtw89_read32 (rtwdev,R_BE_WCPU_FW_CTRL ); + + st =u32_get_bits (val32,B_BE_WCPU_FWDL_STATUS_MASK ); +if (st <ARRAY_SIZE (fwdl_status_map)) +return fwdl_status_map[st]; + +return st; +} + +static int rtw89_fwdl_check_path_ready_be (struct rtw89_dev *rtwdev, +bool h2c_or_fwdl) +{ +u32 check = h2c_or_fwdl ?B_BE_H2C_PATH_RDY :B_BE_DLFW_PATH_RDY ; +u32 val; + +return read_poll_timeout_atomic (rtw89_read32, val, val & check, +1 ,1000000 , false, + rtwdev,R_BE_WCPU_FW_CTRL ); +} +const struct rtw89_mac_gen_def rtw89_mac_gen_be = { .band1_offset =RTW89_MAC_BE_BAND_REG_OFFSET , .filter_model_addr =R_BE_FILTER_MODEL_ADDR , .indir_access_addr =R_BE_INDIR_ACCESS_ENTRY , .mem_base_addrs = rtw89_mac_mem_base_addrs_be, .rx_fltr =R_BE_RX_FLTR_OPT , + + .disable_cpu = rtw89_mac_disable_cpu_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, };EXPORT_SYMBOL (rtw89_mac_gen_be);
drivers/net/wireless/realtek/rtw89/reg.h +107 -0
115 lines not on this page · raw message
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 4/8 wifi: rtw89: fw: add checking type for variant type of firmware
In reply to Ping-Ke ShihFor 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.
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/core.h | 8 +++++++ drivers/net/wireless/realtek/rtw89/fw.c | 19 ++++++++-------- drivers/net/wireless/realtek/rtw89/fw.h | 2 +- drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- drivers/net/wireless/realtek/rtw89/mac.h | 2 +- drivers/net/wireless/realtek/rtw89/mac_be.c | 25 +++++++++++++++++++-- 6 files changed, 45 insertions(+), 15 deletions(-)
drivers/net/wireless/realtek/rtw89/core.h +8 -0
@@ -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 ,
drivers/net/wireless/realtek/rtw89/fw.c +10 -9
@@ -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:
drivers/net/wireless/realtek/rtw89/fw.h +1 -1
@@ -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 *
drivers/net/wireless/realtek/rtw89/mac.c +2 -2
@@ -3505,7 +3505,7 @@ static int rtw89_mac_enable_cpu_ax(struct rtw89_dev *rtwdev, u8 boot_reason, booif (!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 );
drivers/net/wireless/realtek/rtw89/mac.h +1 -1
@@ -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); };
drivers/net/wireless/realtek/rtw89/mac_be.c +23 -2
@@ -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];
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 5/8 wifi: rtw89: fw: propagate an argument include_bb for BB MCU firmware
In reply to Ping-Ke ShihThough WiFi 7 chips need BB MCU firmware, we don't download it in probe stage. Instead, only bring interface up under normal operation or WoWLAN mode. So, add an argument to assist download flow to setup download settings properly.
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/core.c | 2 +- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 5 +++-- drivers/net/wireless/realtek/rtw89/fw.h | 3 ++- drivers/net/wireless/realtek/rtw89/mac.c | 11 +++++++---- drivers/net/wireless/realtek/rtw89/mac.h | 5 +++-- drivers/net/wireless/realtek/rtw89/mac_be.c | 10 +++++++--- drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + drivers/net/wireless/realtek/rtw89/wow.c | 4 +++- 12 files changed, 31 insertions(+), 14 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +1 -1
@@ -3788,7 +3788,7 @@ static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) {int ret; - ret =rtw89_mac_partial_init (rtwdev); + ret =rtw89_mac_partial_init (rtwdev, false);if (ret)return ret;
drivers/net/wireless/realtek/rtw89/core.h +1 -0
@@ -3446,6 +3446,7 @@ struct rtw89_chip_info {const char *fw_basename;u8 fw_format_max;bool try_ce_fw; +u8 bbmcu_nr;u32 needed_fw_elms;u32 fifo_size;bool small_fifo_size;
drivers/net/wireless/realtek/rtw89/fw.c +3 -2
@@ -872,7 +872,8 @@ static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)rtw89_fw_prog_cnt_dump (rtwdev); } -int rtw89_fw_download (struct rtw89_dev *rtwdev,enum rtw89_fw_type type) +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;
@@ -881,7 +882,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)int ret; mac->disable_cpu (rtwdev); - ret = mac->fwdl_enable_wcpu (rtwdev,0 , true); + ret = mac->fwdl_enable_wcpu (rtwdev,0 , true, include_bb);if (ret)return ret;
drivers/net/wireless/realtek/rtw89/fw.h +2 -1
@@ -3628,7 +3628,8 @@ rtw89_early_fw_feature_recognize(struct device *device,const struct rtw89_chip_info *chip, struct rtw89_fw_info *early_fw, int *used_fw_format); -int rtw89_fw_download (struct rtw89_dev *rtwdev,enum rtw89_fw_type type); +int rtw89_fw_download (struct rtw89_dev *rtwdev,enum rtw89_fw_type type, +bool include_bb);void rtw89_load_firmware_work (struct work_struct *work);void rtw89_unload_firmware (struct rtw89_dev *rtwdev);int rtw89_wait_firmware_completion (struct rtw89_dev *rtwdev);
drivers/net/wireless/realtek/rtw89/mac.c +7 -4
@@ -3467,7 +3467,8 @@ static void rtw89_mac_disable_cpu_ax(struct rtw89_dev *rtwdev)rtw89_write32_set (rtwdev,R_AX_PLATFORM_ENABLE ,B_AX_PLATFORM_EN ); } -static int rtw89_mac_enable_cpu_ax (struct rtw89_dev *rtwdev,u8 boot_reason,bool dlfw) +static int rtw89_mac_enable_cpu_ax (struct rtw89_dev *rtwdev,u8 boot_reason, +bool dlfw,bool include_bb) {u32 val;int ret;
@@ -3592,7 +3593,7 @@ int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev) }EXPORT_SYMBOL (rtw89_mac_disable_bb_rf); -int rtw89_mac_partial_init (struct rtw89_dev *rtwdev) +int rtw89_mac_partial_init (struct rtw89_dev *rtwdev,bool include_bb) {int ret;
@@ -3616,7 +3617,7 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev)return ret; } - ret =rtw89_fw_download (rtwdev,RTW89_FW_NORMAL ); + ret =rtw89_fw_download (rtwdev,RTW89_FW_NORMAL , include_bb);if (ret)return ret;
@@ -3625,9 +3626,11 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev)int rtw89_mac_init (struct rtw89_dev *rtwdev) { +const struct rtw89_chip_info *chip = rtwdev->chip; +bool include_bb = !!chip->bbmcu_nr;int ret; - ret =rtw89_mac_partial_init (rtwdev); + ret =rtw89_mac_partial_init (rtwdev, include_bb);if (ret) goto fail;
drivers/net/wireless/realtek/rtw89/mac.h +3 -2
@@ -860,7 +860,8 @@ struct rtw89_mac_gen_def {u32 rx_fltr;void (*disable_cpu)(struct rtw89_dev *rtwdev); -int (*fwdl_enable_wcpu)(struct rtw89_dev *rtwdev,u8 boot_reason,bool dlfw); +int (*fwdl_enable_wcpu)(struct rtw89_dev *rtwdev,u8 boot_reason, +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); };
@@ -962,7 +963,7 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, }void rtw89_mac_pwr_off (struct rtw89_dev *rtwdev); -int rtw89_mac_partial_init (struct rtw89_dev *rtwdev); +int rtw89_mac_partial_init (struct rtw89_dev *rtwdev,bool include_bb);int rtw89_mac_init (struct rtw89_dev *rtwdev);int rtw89_mac_check_mac_en (struct rtw89_dev *rtwdev,u8 band,enum rtw89_mac_hwmod_sel sel);
drivers/net/wireless/realtek/rtw89/mac_be.c +7 -3
@@ -51,10 +51,13 @@ static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev)rtw89_write32 (rtwdev,R_BE_UDM2 ,0 ); } -static void set_cpu_en (struct rtw89_dev *rtwdev) +static void set_cpu_en (struct rtw89_dev *rtwdev,bool include_bb) {u32 set =B_BE_WLANCPU_FWDL_EN ; +if (include_bb) + set |=B_BE_BBMCU0_FWDL_EN ; +rtw89_write32_set (rtwdev,R_BE_WCPU_FW_CTRL , set); }
@@ -109,9 +112,10 @@ static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) }static int rtw89_mac_fwdl_enable_wcpu_be (struct rtw89_dev *rtwdev, -u8 boot_reason,bool dlfw) +u8 boot_reason,bool dlfw, +bool include_bb) { -set_cpu_en (rtwdev); +set_cpu_en (rtwdev, include_bb);return wcpu_on (rtwdev, boot_reason, dlfw); }
drivers/net/wireless/realtek/rtw89/rtw8851b.c +1 -0
@@ -2345,6 +2345,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .fw_basename = RTW8851B_FW_BASENAME, .fw_format_max = RTW8851B_FW_FORMAT_MAX, .try_ce_fw = true, + .bbmcu_nr = 0, .needed_fw_elms = 0, .fifo_size = 196608, .small_fifo_size = true,
drivers/net/wireless/realtek/rtw89/rtw8852a.c +1 -0
@@ -2081,6 +2081,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .fw_basename = RTW8852A_FW_BASENAME, .fw_format_max = RTW8852A_FW_FORMAT_MAX, .try_ce_fw = false, + .bbmcu_nr = 0, .needed_fw_elms = 0, .fifo_size = 458752, .small_fifo_size = false,
drivers/net/wireless/realtek/rtw89/rtw8852b.c +1 -0
@@ -2514,6 +2514,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .fw_basename = RTW8852B_FW_BASENAME, .fw_format_max = RTW8852B_FW_FORMAT_MAX, .try_ce_fw = true, + .bbmcu_nr = 0, .needed_fw_elms = 0, .fifo_size = 196608, .small_fifo_size = true,
drivers/net/wireless/realtek/rtw89/rtw8852c.c +1 -0
@@ -2811,6 +2811,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .fw_basename = RTW8852C_FW_BASENAME, .fw_format_max = RTW8852C_FW_FORMAT_MAX, .try_ce_fw = false, + .bbmcu_nr = 0, .needed_fw_elms = 0, .fifo_size = 458752, .small_fifo_size = false,
drivers/net/wireless/realtek/rtw89/wow.c +3 -1
@@ -488,6 +488,8 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)struct rtw89_wow_param *rtw_wow = &rtwdev->wow;struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; +const struct rtw89_chip_info *chip = rtwdev->chip; +bool include_bb = !!chip->bbmcu_nr;struct ieee80211_sta *wow_sta;struct rtw89_sta *rtwsta =NULL ;bool is_conn = true;
@@ -501,7 +503,7 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)else is_conn = false; - ret =rtw89_fw_download (rtwdev, fw_type); + ret =rtw89_fw_download (rtwdev, fw_type, include_bb);if (ret) {rtw89_warn (rtwdev,"download fw failed\n" );return ret;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 6/8 wifi: rtw89: 8922a: add chip_ops::bb_preinit to enable BB before downloading firmware
In reply to Ping-Ke ShihBefore downloading firmware for BB MCU, call this ops to enable baseband hardware.
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/core.h | 10 ++++++++++ drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++ drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + 6 files changed, 20 insertions(+)
drivers/net/wireless/realtek/rtw89/core.h +10 -0
@@ -3032,6 +3032,7 @@ struct rtw89_hci_info {struct rtw89_chip_ops {int (*enable_bb_rf)(struct rtw89_dev *rtwdev);int (*disable_bb_rf)(struct rtw89_dev *rtwdev); +void (*bb_preinit)(struct rtw89_dev *rtwdev,enum rtw89_phy_idx phy_idx);void (*bb_reset)(struct rtw89_dev *rtwdev,enum rtw89_phy_idx phy_idx);void (*bb_sethw)(struct rtw89_dev *rtwdev);
@@ -5026,6 +5027,15 @@ static inline void rtw89_chip_rfe_gpio(struct rtw89_dev *rtwdev) chip->ops->rfe_gpio (rtwdev); } +static inline +void rtw89_chip_bb_preinit (struct rtw89_dev *rtwdev,enum rtw89_phy_idx phy_idx) +{ +const struct rtw89_chip_info *chip = rtwdev->chip; + +if (chip->ops->bb_preinit) + chip->ops->bb_preinit (rtwdev, phy_idx); +} +static inline void rtw89_chip_bb_sethw (struct rtw89_dev *rtwdev) {const struct rtw89_chip_info *chip = rtwdev->chip;
drivers/net/wireless/realtek/rtw89/mac.c +6 -0
@@ -3607,6 +3607,12 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)rtw89_mac_ctrl_hci_dma_trx (rtwdev, true); +if (include_bb) { +rtw89_chip_bb_preinit (rtwdev,RTW89_PHY_0 ); +if (rtwdev->dbcc_en) +rtw89_chip_bb_preinit (rtwdev,RTW89_PHY_1 ); + } + ret =rtw89_mac_dmac_pre_init (rtwdev);if (ret)return ret;
drivers/net/wireless/realtek/rtw89/rtw8851b.c +1 -0
@@ -2280,6 +2280,7 @@ static int rtw8851b_mac_disable_bb_rf(struct rtw89_dev *rtwdev)static const struct rtw89_chip_ops rtw8851b_chip_ops = { .enable_bb_rf = rtw8851b_mac_enable_bb_rf, .disable_bb_rf = rtw8851b_mac_disable_bb_rf, + .bb_preinit =NULL , .bb_reset = rtw8851b_bb_reset, .bb_sethw = rtw8851b_bb_sethw, .read_rf = rtw89_phy_read_rf_v1,
drivers/net/wireless/realtek/rtw89/rtw8852a.c +1 -0
@@ -2025,6 +2025,7 @@ static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = {static const struct rtw89_chip_ops rtw8852a_chip_ops = { .enable_bb_rf = rtw89_mac_enable_bb_rf, .disable_bb_rf = rtw89_mac_disable_bb_rf, + .bb_preinit =NULL , .bb_reset = rtw8852a_bb_reset, .bb_sethw = rtw8852a_bb_sethw, .read_rf = rtw89_phy_read_rf,
drivers/net/wireless/realtek/rtw89/rtw8852b.c +1 -0
@@ -2449,6 +2449,7 @@ static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev)static const struct rtw89_chip_ops rtw8852b_chip_ops = { .enable_bb_rf = rtw8852b_mac_enable_bb_rf, .disable_bb_rf = rtw8852b_mac_disable_bb_rf, + .bb_preinit =NULL , .bb_reset = rtw8852b_bb_reset, .bb_sethw = rtw8852b_bb_sethw, .read_rf = rtw89_phy_read_rf_v1,
drivers/net/wireless/realtek/rtw89/rtw8852c.c +1 -0
@@ -2755,6 +2755,7 @@ static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = {static const struct rtw89_chip_ops rtw8852c_chip_ops = { .enable_bb_rf = rtw8852c_mac_enable_bb_rf, .disable_bb_rf = rtw8852c_mac_disable_bb_rf, + .bb_preinit =NULL , .bb_reset = rtw8852c_bb_reset, .bb_sethw = rtw8852c_bb_sethw, .read_rf = rtw89_phy_read_rf_v1,
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 7/8 wifi: rtw89: fw: refine download flow to support variant firmware suits
In reply to Ping-Ke ShihTo support download more than one firmware, adjust flow to download firmware by unit of firmware suit. Then, flow becomes
1. initial setup - disable/enable_wcpu
2. for all firmware suits
2.1. download WiFi CPU, and check ready
2.2. download BB MCU, and check ready
3. check status code to make sure all ready
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/fw.c | 84 +++++++++++++++++++------ 1 file changed, 65 insertions(+), 19 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +65 -19
@@ -823,10 +823,27 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,return ret; } -static int rtw89_fw_download_main (struct rtw89_dev *rtwdev,const u8 *fw, +static enum rtw89_fwdl_check_type +rtw89_fw_get_fwdl_chk_type_from_suit (struct rtw89_dev *rtwdev, +const struct rtw89_fw_suit *fw_suit) +{ +switch (fw_suit->type) { +case RTW89_FW_BBMCU0 : +return RTW89_FWDL_CHECK_BB0_FWDL_DONE ; +case RTW89_FW_BBMCU1 : +return RTW89_FWDL_CHECK_BB1_FWDL_DONE ; +default : +return RTW89_FWDL_CHECK_WCPU_FWDL_DONE ; + } +} + +static int rtw89_fw_download_main (struct rtw89_dev *rtwdev, +const struct rtw89_fw_suit *fw_suit,struct rtw89_fw_bin_info *info) {struct rtw89_fw_hdr_section_info *section_info = info->section_info; +const struct rtw89_chip_info *chip = rtwdev->chip; +enum rtw89_fwdl_check_type chk_type;u8 section_num = info->section_num;int ret;
@@ -837,6 +854,16 @@ static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw, section_info++; } +if (chip->chip_gen ==RTW89_CHIP_AX ) +return 0 ; + + chk_type =rtw89_fw_get_fwdl_chk_type_from_suit (rtwdev, fw_suit); + ret =rtw89_fw_check_rdy (rtwdev, chk_type); +if (ret) { +rtw89_warn (rtwdev,"failed to download firmware type %u\n" , + fw_suit->type); +return ret; + }return 0 ; }
@@ -872,43 +899,62 @@ static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)rtw89_fw_prog_cnt_dump (rtwdev); } -int rtw89_fw_download (struct rtw89_dev *rtwdev,enum rtw89_fw_type type, -bool include_bb) +static int rtw89_fw_download_suit (struct rtw89_dev *rtwdev, +struct rtw89_fw_suit *fw_suit) {const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; -struct rtw89_fw_info *fw_info = &rtwdev->fw; -struct rtw89_fw_suit *fw_suit =rtw89_fw_suit_get (rtwdev, type);struct rtw89_fw_bin_info info;int ret; - mac->disable_cpu (rtwdev); - ret = mac->fwdl_enable_wcpu (rtwdev,0 , true, include_bb); -if (ret) -return ret; - ret =rtw89_fw_hdr_parser (rtwdev, fw_suit, &info);if (ret) {rtw89_err (rtwdev,"parse fw header fail\n" ); - goto fwdl_err; +return ret; } ret = mac->fwdl_check_path_ready (rtwdev, true);if (ret) {rtw89_err (rtwdev,"[ERR]H2C path ready\n" ); - goto fwdl_err; +return ret; } ret =rtw89_fw_download_hdr (rtwdev, fw_suit->data, info.hdr_len - info.dynamic_hdr_len); -if (ret) { - ret = -EBUSY ; - goto fwdl_err; - } +if (ret) +return ret; - ret =rtw89_fw_download_main (rtwdev, fw_suit->data, &info); -if (ret) { - ret = -EBUSY ; + ret =rtw89_fw_download_main (rtwdev, fw_suit, &info); +if (ret) +return ret; + +return 0 ; +} + +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; +struct rtw89_fw_suit *fw_suit =rtw89_fw_suit_get (rtwdev, type); +u8 bbmcu_nr = rtwdev->chip->bbmcu_nr; +int ret; +int i; + + mac->disable_cpu (rtwdev); + ret = mac->fwdl_enable_wcpu (rtwdev,0 , true, include_bb); +if (ret) +return ret; + + ret =rtw89_fw_download_suit (rtwdev, fw_suit); +if (ret) goto fwdl_err; + +for (i =0 ; i < bbmcu_nr && include_bb; i++) { + fw_suit =rtw89_fw_suit_get (rtwdev,RTW89_FW_BBMCU0 + i); + + ret =rtw89_fw_download_suit (rtwdev, fw_suit); +if (ret) + goto fwdl_err; } fw_info->h2c_seq =0 ;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v2 8/8 wifi: rtw89: 8922a: set memory heap address for secure firmware
In reply to Ping-Ke ShihSecure firmware is protected by public/private key cryptography. To help firmware self verify integrity, configure a heap address for these data before downloading firmware.
---
v2: no change
--- drivers/net/wireless/realtek/rtw89/fw.c | 4 ++++ drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ 2 files changed, 6 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +4 -0
@@ -912,6 +912,10 @@ static int rtw89_fw_download_suit(struct rtw89_dev *rtwdev,return ret; } +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 ); + ret = mac->fwdl_check_path_ready (rtwdev, true);if (ret) {rtw89_err (rtwdev,"[ERR]H2C path ready\n" );
drivers/net/wireless/realtek/rtw89/reg.h +2 -0
@@ -3670,6 +3670,8 @@#define B_BE_LPS_STATUS BIT(3)#define B_BE_HCI_TXDMA_BUSY BIT(2) +#define R_BE_SECURE_BOOT_MALLOC_INFO 0x0184 +#define R_BE_WCPU_FW_CTRL 0x01E0#define B_BE_RUN_ENV_MASK GENMASK(31, 30)#define B_BE_WCPU_FWDL_STATUS_MASK GENMASK(29, 26)
Signature · 1 line
2.25.1