Commit 18ddf102 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

wifi: rtw89: fw: adapt to new firmware format of security section

Normally, system image should ensure firmware integrity, but we provide
an advance feature to ensure this by security section along with firmware.
To enable this feature, custom ID is programmed into efuse, and driver
will download proper security section to firmware.

Since I don't have this kind hardware modules on hand yet, but new format
is used by newer firmware. Therefore, I prepare this patch in advance to
consider size of security section as a factor of checking rule of firmware
size, but don't actually download security section to firmware.

This patch is backward compatible, so it will be safe to have this change
before adding an new format firmware to linux-firmware repository.
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221209012215.7342-1-pkshih@realtek.com
parent 25ed1a17
...@@ -91,6 +91,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, ...@@ -91,6 +91,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
const u8 *fwdynhdr; const u8 *fwdynhdr;
const u8 *bin; const u8 *bin;
u32 base_hdr_len; u32 base_hdr_len;
u32 mssc_len = 0;
u32 i; u32 i;
if (!info) if (!info)
...@@ -120,6 +121,14 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, ...@@ -120,6 +121,14 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
fw += RTW89_FW_HDR_SIZE; fw += RTW89_FW_HDR_SIZE;
section_info = info->section_info; section_info = info->section_info;
for (i = 0; i < info->section_num; i++) { for (i = 0; i < info->section_num; i++) {
section_info->type = GET_FWSECTION_HDR_SECTIONTYPE(fw);
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
section_info->mssc = GET_FWSECTION_HDR_MSSC(fw);
mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
} else {
section_info->mssc = 0;
}
section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw);
if (GET_FWSECTION_HDR_CHECKSUM(fw)) if (GET_FWSECTION_HDR_CHECKSUM(fw))
section_info->len += FWDL_SECTION_CHKSUM_LEN; section_info->len += FWDL_SECTION_CHKSUM_LEN;
...@@ -132,7 +141,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, ...@@ -132,7 +141,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
section_info++; section_info++;
} }
if (fw_end != bin) { if (fw_end != bin + mssc_len) {
rtw89_err(rtwdev, "[ERR]fw bin size\n"); rtw89_err(rtwdev, "[ERR]fw bin size\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -171,6 +171,8 @@ struct rtw89_fw_hdr_section_info { ...@@ -171,6 +171,8 @@ struct rtw89_fw_hdr_section_info {
const u8 *addr; const u8 *addr;
u32 len; u32 len;
u32 dladdr; u32 dladdr;
u32 mssc;
u8 type;
}; };
struct rtw89_fw_bin_info { struct rtw89_fw_bin_info {
...@@ -480,14 +482,21 @@ static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val) ...@@ -480,14 +482,21 @@ static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val)
#define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8) #define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8)
#define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0) #define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0)
#define FWDL_SECURITY_SECTION_TYPE 9
#define FWDL_SECURITY_SIGLEN 512
#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0))
#define GET_FWSECTION_HDR_SECTIONTYPE(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(27, 24))
#define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \ #define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 0)) le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 0))
#define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \ #define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(28)) le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(28))
#define GET_FWSECTION_HDR_REDL(fwhdr) \ #define GET_FWSECTION_HDR_REDL(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(29)) le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(29))
#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ #define GET_FWSECTION_HDR_MSSC(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0)) le32_get_bits(*((const __le32 *)(fwhdr) + 2), GENMASK(31, 0))
#define GET_FW_HDR_MAJOR_VERSION(fwhdr) \ #define GET_FW_HDR_MAJOR_VERSION(fwhdr) \
le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(7, 0)) le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(7, 0))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment