diff options
author | Ping-Ke Shih <pkshih@realtek.com> | 2024-10-30 03:21:34 +0100 |
---|---|---|
committer | Ping-Ke Shih <pkshih@realtek.com> | 2024-11-06 07:00:44 +0100 |
commit | 6d995ef770af225c9066537a07d941e0c92e0366 (patch) | |
tree | dc71c98ad90ede5ca221086d4065cf2d5143e042 /drivers/net/wireless/realtek | |
parent | wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to share with v0 (diff) | |
download | linux-6d995ef770af225c9066537a07d941e0c92e0366.tar.xz linux-6d995ef770af225c9066537a07d941e0c92e0366.zip |
wifi: rtw89: fw: use common function to parse security section for WiFi 6 chips
The MSSC (multiple security section count) can be regular number (shown in
below figure) or 0xFF (supported already). For WiFi 7 or newer WiFi 6
chips, the MSSC will be 0xFF. But early WiFi 6 chip such as RTL8852B
could be either one of the cases.
Extend __parse_security_section() to support both with/without secure
boot mode accordingly.
+---------------------------+ -\
| firmware header | |
| | |
| +-----------------------+ | |
| | section type/size * N | | |
| +-----------------------+ | |
+---------------------------+ -/
: :
+---------------------------+ -\
| secure section type (ID:9)| |
| | |
+----|-> [ security key data ] | |
| +---------------------------+ -/
| |MSS Pool for above section |
| | [ security key data 1 ] |
+----|- [ security key data 2 ] |
by mss_idx | [ security key data 3 ] |
| ... M | * M = MSSC (MSSC != 0xFF)
+---------------------------+
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20241030022135.11688-8-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless/realtek')
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/fw.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/fw.h | 1 |
2 files changed, 46 insertions, 12 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 5849579a628e..2191c037d72e 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -56,6 +56,11 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb); static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, struct rtw89_wait_info *wait, unsigned int cond); +static int __parse_security_section(struct rtw89_dev *rtwdev, + struct rtw89_fw_bin_info *info, + struct rtw89_fw_hdr_section_info *section_info, + const void *content, + u32 *mssc_len); static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, bool header) @@ -132,7 +137,8 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le const u8 *fw_end = fw + len; const u8 *bin; u32 base_hdr_len; - u32 mssc_len = 0; + u32 mssc_len; + int ret; u32 i; if (!info) @@ -164,29 +170,47 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le section = &fw_hdr->sections[i]; section_info->type = le32_get_bits(section->w1, FWSECTION_HDR_W1_SECTIONTYPE); + section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); + + if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) + section_info->len += FWDL_SECTION_CHKSUM_LEN; + section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); + section_info->dladdr = + le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; + section_info->addr = bin; + if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { section_info->mssc = le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC); - mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; + + ret = __parse_security_section(rtwdev, info, section_info, + bin, &mssc_len); + if (ret) + return ret; if (sec->secure_boot && chip->chip_id == RTL8852B) section_info->len_override = 960; } else { section_info->mssc = 0; + mssc_len = 0; } - section_info->len = le32_get_bits(section->w1, FWSECTION_HDR_W1_SEC_SIZE); - if (le32_get_bits(section->w1, FWSECTION_HDR_W1_CHECKSUM)) - section_info->len += FWDL_SECTION_CHKSUM_LEN; - section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_W1_REDL); - section_info->dladdr = - le32_get_bits(section->w0, FWSECTION_HDR_W0_DL_ADDR) & 0x1fffffff; - section_info->addr = bin; - bin += section_info->len; + rtw89_debug(rtwdev, RTW89_DBG_FW, + "section[%d] type=%d len=0x%-6x mssc=%d mssc_len=%d addr=%tx\n", + i, section_info->type, section_info->len, + section_info->mssc, mssc_len, bin - fw); + rtw89_debug(rtwdev, RTW89_DBG_FW, + " ignore=%d key_addr=%p (0x%tx) key_len=%d key_idx=%d\n", + section_info->ignore, section_info->key_addr, + section_info->key_addr ? + section_info->key_addr - section_info->addr : 0, + section_info->key_len, section_info->key_idx); + + bin += section_info->len + mssc_len; section_info++; } - if (fw_end != bin + mssc_len) { + if (fw_end != bin) { rtw89_err(rtwdev, "[ERR]fw bin size\n"); return -EINVAL; } @@ -326,9 +350,10 @@ static int __parse_security_section(struct rtw89_dev *rtwdev, const void *content, u32 *mssc_len) { + struct rtw89_fw_secure *sec = &rtwdev->fw.sec; int ret; - if (section_info->mssc == FORMATTED_MSSC) { + if ((section_info->mssc & FORMATTED_MSSC_MASK) == FORMATTED_MSSC) { ret = __parse_formatted_mssc(rtwdev, info, section_info, content, mssc_len); if (ret) @@ -338,6 +363,14 @@ static int __parse_security_section(struct rtw89_dev *rtwdev, if (info->dsp_checksum) *mssc_len += section_info->mssc * FWDL_SECURITY_CHKSUM_LEN; + if (sec->secure_boot) { + if (sec->mss_idx >= section_info->mssc) + return -EFAULT; + section_info->key_addr = content + section_info->len + + sec->mss_idx * FWDL_SECURITY_SIGLEN; + section_info->key_len = FWDL_SECURITY_SIGLEN; + } + info->secure_section_exist = true; } diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index bd7680264849..efa63d444821 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -583,6 +583,7 @@ struct rtw89_fw_hdr_section_v1 { #define FWSECTION_HDR_V1_W1_REDL BIT(29) #define FWSECTION_HDR_V1_W2_MSSC GENMASK(7, 0) #define FORMATTED_MSSC 0xFF +#define FORMATTED_MSSC_MASK GENMASK(7, 0) #define FWSECTION_HDR_V1_W2_BBMCU_IDX GENMASK(27, 24) struct rtw89_fw_hdr_v1 { |