* [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips
@ 2024-10-30 2:21 Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common Ping-Ke Shih
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
rtw89 has supported firmware secure boot for WiFi 7 chip, and this
patchset is to support WiFi 6 chips.
Basically flow of firmware secure boot is:
1. read efuse to determine if hardware module need firmware secure boot
(Patches 1~3 adjust existing code and add new foramt)
2. select key data and relocate firmware content
(Patches 4, 6 and 7 adjust existing code to support new format)
3. download firmware
Remaining patches 5 and 8 are to set and unset registers for the case of
firmware secure boot. Both don't affect original behavior.
Ping-Ke Shih (8):
wifi: rtw89: efuse: move reading efuse of fw secure info to common
wifi: rtw89: efuse: move recognize firmware MSS info v1 to common
wifi: rtw89: efuse: read firmware secure info v0 from efuse for WiFi 6
chips
wifi: rtw89: fw: shrink download size of security section for RTL8852B
wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to
register
wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to
share with v0
wifi: rtw89: fw: use common function to parse security section for
WiFi 6 chips
wifi: rtw89: mac: no configure CMAC/DMAC tables for firmware secure
boot
drivers/net/wireless/realtek/rtw89/core.h | 5 +-
drivers/net/wireless/realtek/rtw89/efuse.c | 150 ++++++++++++++++++
drivers/net/wireless/realtek/rtw89/efuse.h | 2 +
drivers/net/wireless/realtek/rtw89/efuse_be.c | 52 +-----
drivers/net/wireless/realtek/rtw89/fw.c | 109 ++++++++++---
drivers/net/wireless/realtek/rtw89/fw.h | 5 +
drivers/net/wireless/realtek/rtw89/mac.c | 27 +++-
drivers/net/wireless/realtek/rtw89/mac.h | 12 ++
drivers/net/wireless/realtek/rtw89/mac_be.c | 2 +
drivers/net/wireless/realtek/rtw89/reg.h | 2 +
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 3 -
11 files changed, 291 insertions(+), 78 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-11-06 6:08 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 2/8] wifi: rtw89: efuse: move recognize firmware MSS info v1 " Ping-Ke Shih
` (6 subsequent siblings)
7 siblings, 1 reply; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
The secure key used by certain hardware module is programmed in efuse, so
driver should read the information from efuse before downloading firmware.
Originally only RTL8922AE can support firmware secure boot, and read efuse
during chip power on. To extend to support all chips, move the caller to
common power on flow and add separate functions to read efuse for
WiFi 6 chips.
No logic change at all.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/efuse.c | 5 +++++
drivers/net/wireless/realtek/rtw89/efuse.h | 1 +
drivers/net/wireless/realtek/rtw89/efuse_be.c | 1 -
drivers/net/wireless/realtek/rtw89/mac.c | 5 +++++
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac_be.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 3 ---
7 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c
index e1236079a84a..532623130c41 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse.c
@@ -354,3 +354,8 @@ int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
return 0;
}
EXPORT_SYMBOL(rtw89_read_efuse_ver);
+
+int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
+{
+ return 0;
+}
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h
index 72416f56a071..a2f6f36e697f 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.h
+++ b/drivers/net/wireless/realtek/rtw89/efuse.h
@@ -23,6 +23,7 @@ int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev);
int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle);
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv);
+int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev);
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/efuse_be.c b/drivers/net/wireless/realtek/rtw89/efuse_be.c
index 0be26d5fdf7c..756aaf886af9 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse_be.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse_be.c
@@ -559,4 +559,3 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
return 0;
}
-EXPORT_SYMBOL(rtw89_efuse_read_fw_secure_be);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 588e2b96bf43..7ed29bc69009 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -1444,6 +1444,7 @@ void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
{
#define PWR_ACT 1
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_pwr_cfg * const *cfg_seq;
int (*cfg_func)(struct rtw89_dev *rtwdev);
@@ -1472,6 +1473,9 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
return ret;
if (on) {
+ if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
+ mac->efuse_read_fw_secure(rtwdev);
+
set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
@@ -6673,6 +6677,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_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,
+ .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_ax,
.cfg_plt = rtw89_mac_cfg_plt_ax,
.get_plt_cnt = rtw89_mac_get_plt_cnt_ax,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 721fa3b4f82b..4d4b505e3bc9 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -988,6 +988,7 @@ struct rtw89_mac_gen_def {
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);
+ int (*efuse_read_fw_secure)(struct rtw89_dev *rtwdev);
int (*cfg_plt)(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt);
u16 (*get_plt_cnt)(struct rtw89_dev *rtwdev, u8 band);
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 30943462640f..e0d7cf9fd7ee 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -2603,6 +2603,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.parse_efuse_map = rtw89_parse_efuse_map_be,
.parse_phycap_map = rtw89_parse_phycap_map_be,
.cnv_efuse_state = rtw89_cnv_efuse_state_be,
+ .efuse_read_fw_secure = rtw89_efuse_read_fw_secure_be,
.cfg_plt = rtw89_mac_cfg_plt_be,
.get_plt_cnt = rtw89_mac_get_plt_cnt_be,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index 27069a55e368..f17cb1204f80 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -399,9 +399,6 @@ static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
B_BE_FEN_BBPLAT_RSTB);
- if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
- rtw89_efuse_read_fw_secure_be(rtwdev);
-
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/8] wifi: rtw89: efuse: move recognize firmware MSS info v1 to common
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 3/8] wifi: rtw89: efuse: read firmware secure info v0 from efuse for WiFi 6 chips Ping-Ke Shih
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
The WiFi 6 chip use the same firmware MSS information v1 read from efuse,
so move this logic to common.
No change logic at all.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/efuse.c | 59 +++++++++++++++++++
drivers/net/wireless/realtek/rtw89/efuse.h | 1 +
drivers/net/wireless/realtek/rtw89/efuse_be.c | 51 +---------------
3 files changed, 62 insertions(+), 49 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c
index 532623130c41..a02b04eecd05 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse.c
@@ -11,11 +11,24 @@
#define EF_CV_MASK GENMASK(7, 4)
#define EF_CV_INV 15
+#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
+#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
+#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
+#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
+
enum rtw89_efuse_bank {
RTW89_EFUSE_BANK_WIFI,
RTW89_EFUSE_BANK_BT,
};
+enum rtw89_efuse_mss_dev_type {
+ MSS_DEV_TYPE_FWSEC_DEF = 0xF,
+ MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
+ MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
+ MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
+ MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
+};
+
static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev,
enum rtw89_efuse_bank bank)
{
@@ -355,6 +368,52 @@ int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
}
EXPORT_SYMBOL(rtw89_read_efuse_ver);
+static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
+{
+ switch (mss_dev_type) {
+ case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
+ mss_dev_type = 0x0;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
+ mss_dev_type = 0x1;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
+ mss_dev_type = 0x2;
+ break;
+ case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
+ mss_dev_type = 0x3;
+ break;
+ case MSS_DEV_TYPE_FWSEC_DEF:
+ mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
+ break;
+ default:
+ rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
+ mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
+ break;
+ }
+
+ return mss_dev_type;
+}
+
+int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 mss_dev_type;
+
+ mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
+ sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
+ u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
+ sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
+
+ sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
+ if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
+ rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
{
return 0;
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h
index a2f6f36e697f..a96fc1044791 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.h
+++ b/drivers/net/wireless/realtek/rtw89/efuse.h
@@ -23,6 +23,7 @@ int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev);
int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev);
int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle);
int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *efv);
+int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2);
int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev);
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/efuse_be.c b/drivers/net/wireless/realtek/rtw89/efuse_be.c
index 756aaf886af9..64768923b0f0 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse_be.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse_be.c
@@ -8,11 +8,7 @@
#include "reg.h"
#define EFUSE_EXTERNALPN_ADDR_BE 0x1580
-#define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0)
-#define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4)
#define EFUSE_SERIALNUM_ADDR_BE 0x1581
-#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
-#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
#define EFUSE_SB_CRYP_SEL_ADDR 0x1582
#define EFUSE_SB_CRYP_SEL_SIZE 2
#define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF
@@ -20,14 +16,6 @@
#define EFUSE_SEC_BE_START 0x1580
#define EFUSE_SEC_BE_SIZE 4
-enum rtw89_efuse_mss_dev_type {
- MSS_DEV_TYPE_FWSEC_DEF = 0xF,
- MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC,
- MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA,
- MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9,
- MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6,
-};
-
static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = {
0x8000100, 0xC000180
};
@@ -477,33 +465,6 @@ static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel)
return sb_cryp_sel_v + low_bit;
}
-static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
-{
- switch (mss_dev_type) {
- case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
- mss_dev_type = 0x0;
- break;
- case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
- mss_dev_type = 0x1;
- break;
- case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
- mss_dev_type = 0x2;
- break;
- case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
- mss_dev_type = 0x3;
- break;
- case MSS_DEV_TYPE_FWSEC_DEF:
- mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
- break;
- default:
- rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
- mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
- break;
- }
-
- return mss_dev_type;
-}
-
int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
@@ -511,7 +472,6 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
u32 sec_size = EFUSE_SEC_BE_SIZE;
u16 sb_cryp_sel, sb_cryp_sel_idx;
u8 sec_map[EFUSE_SEC_BE_SIZE];
- u8 mss_dev_type;
u8 b1, b2;
int ret;
@@ -538,16 +498,9 @@ int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev)
b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr];
b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr];
- mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
- sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
- u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
- sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
-
- sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
- if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
- rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
+ ret = rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
+ if (ret)
goto out;
- }
sec->secure_boot = true;
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/8] wifi: rtw89: efuse: read firmware secure info v0 from efuse for WiFi 6 chips
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 2/8] wifi: rtw89: efuse: move recognize firmware MSS info v1 " Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 4/8] wifi: rtw89: fw: shrink download size of security section for RTL8852B Ping-Ke Shih
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
WiFi 6 chips could program secure information in v0 or v1 format. Use
existing v1 parser or newly added v0 parser to recognize firmware key
that is going to be used.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 5 +-
drivers/net/wireless/realtek/rtw89/efuse.c | 86 ++++++++++++++++++++++
2 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 5fa59cd138c1..ccee011c9975 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4516,11 +4516,14 @@ enum rtw89_fw_mss_dev_type {
};
struct rtw89_fw_secure {
- bool secure_boot;
+ bool secure_boot: 1;
+ bool can_mss_v1: 1;
+ bool can_mss_v0: 1;
u32 sb_sel_mgn;
u8 mss_dev_type;
u8 mss_cust_idx;
u8 mss_key_num;
+ u8 mss_idx; /* v0 */
};
struct rtw89_fw_info {
diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c
index a02b04eecd05..6c6c763510af 100644
--- a/drivers/net/wireless/realtek/rtw89/efuse.c
+++ b/drivers/net/wireless/realtek/rtw89/efuse.c
@@ -16,6 +16,20 @@
#define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0)
#define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6)
+#define EFUSE_EXTERNALPN_ADDR_AX 0x5EC
+#define EFUSE_CUSTOMER_ADDR_AX 0x5ED
+#define EFUSE_SERIALNUM_ADDR_AX 0x5ED
+
+#define EFUSE_B1_EXTERNALPN_MASK GENMASK(7, 0)
+#define EFUSE_B2_CUSTOMER_MASK GENMASK(3, 0)
+#define EFUSE_B2_SERIALNUM_MASK GENMASK(6, 4)
+
+#define OTP_KEY_INFO_NUM 2
+
+static const u8 otp_key_info_externalPN[OTP_KEY_INFO_NUM] = {0x0, 0x0};
+static const u8 otp_key_info_customer[OTP_KEY_INFO_NUM] = {0x0, 0x1};
+static const u8 otp_key_info_serialNum[OTP_KEY_INFO_NUM] = {0x0, 0x1};
+
enum rtw89_efuse_bank {
RTW89_EFUSE_BANK_WIFI,
RTW89_EFUSE_BANK_BT,
@@ -397,24 +411,96 @@ static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 mss_dev_type;
+ if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) {
+ mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB;
+ sec->mss_cust_idx = 0;
+ sec->mss_key_num = 0;
+
+ goto mss_dev_type;
+ }
+
mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
+mss_dev_type:
sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
return -ENOENT;
}
+ sec->can_mss_v1 = true;
+
return 0;
}
+static
+int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
+{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u8 externalPN;
+ u8 serialNum;
+ u8 customer;
+ u8 i;
+
+ externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK);
+ customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK);
+ serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK);
+
+ for (i = 0; i < OTP_KEY_INFO_NUM; i++) {
+ if (externalPN == otp_key_info_externalPN[i] &&
+ customer == otp_key_info_customer[i] &&
+ serialNum == otp_key_info_serialNum[i]) {
+ sec->mss_idx = i;
+ sec->can_mss_v0 = true;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+ u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX;
+ u32 sec_size = 2;
+ u8 sec_map[2];
+ u8 b1, b2;
+ int ret;
+
+ ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map,
+ sec_addr, sec_size, false);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to dump secsel map\n");
+ return ret;
+ }
+
+ b1 = sec_map[0];
+ b2 = sec_map[1];
+
+ if (b1 == 0xFF && b2 == 0xFF)
+ return 0;
+
+ rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2);
+ rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
+ if (!sec->can_mss_v1 && !sec->can_mss_v0)
+ goto out;
+
+ sec->secure_boot = true;
+
+out:
+ rtw89_debug(rtwdev, RTW89_DBG_FW,
+ "MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n",
+ sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1,
+ sec->mss_dev_type, sec->mss_cust_idx,
+ sec->mss_key_num, sec->mss_idx);
+
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/8] wifi: rtw89: fw: shrink download size of security section for RTL8852B
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
` (2 preceding siblings ...)
2024-10-30 2:21 ` [PATCH 3/8] wifi: rtw89: efuse: read firmware secure info v0 from efuse for WiFi 6 chips Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 5/8] wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to register Ping-Ke Shih
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
For RTL8852B, when current firmware is secure boot, the security section
needs a special treatment that shrink its size to 960.
As figure below, not only shrink the amount of download size of security
section (2), but also need to modify the section size in firmware header
(1) that is also downloaded to chip.
+---------------------------+
| firmware header |
| |
| +-----------------------+ |
| | section type, size N -|-|-------+
| | ... (1) | | |
| +-----------------------+ | |
+---------------------------+ | 2048 shrink to 960
: : |
+---------------------------+ -\ |
| security section type 9 | | |
| (2) | | <--+
| | |
+---------------------------+ -/
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 36 ++++++++++++++++++++++---
drivers/net/wireless/realtek/rtw89/fw.h | 1 +
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 1fc1ee46b3a3..0af0e539e976 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -124,7 +124,9 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
struct rtw89_fw_bin_info *info)
{
const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_fw_hdr_section_info *section_info;
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
const struct rtw89_fw_hdr_section *section;
const u8 *fw_end = fw + len;
@@ -165,6 +167,9 @@ static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section_info->mssc =
le32_get_bits(section->w2, FWSECTION_HDR_W2_MSSC);
mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
+
+ if (sec->secure_boot && chip->chip_id == RTL8852B)
+ section_info->len_override = 960;
} else {
section_info->mssc = 0;
}
@@ -1155,9 +1160,24 @@ static u32 __rtw89_fw_download_tweak_hdr_v0(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr *fw_hdr)
{
+ struct rtw89_fw_hdr_section_info *section_info;
+ struct rtw89_fw_hdr_section *section;
+ int i;
+
le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN,
FW_HDR_W7_PART_SIZE);
+ for (i = 0; i < info->section_num; i++) {
+ section_info = &info->section_info[i];
+
+ if (!section_info->len_override)
+ continue;
+
+ section = &fw_hdr->sections[i];
+ le32p_replace_bits(§ion->w1, section_info->len_override,
+ FWSECTION_HDR_W1_SEC_SIZE);
+ }
+
return 0;
}
@@ -1286,10 +1306,20 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev,
if (info->ignore)
return 0;
+ if (info->len_override) {
+ if (info->len_override > info->len)
+ rtw89_warn(rtwdev, "override length %u larger than original %u\n",
+ info->len_override, info->len);
+ else
+ residue_len = info->len_override;
+ }
+
if (info->key_addr && info->key_len) {
- if (info->len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
- rtw89_warn(rtwdev, "ignore to copy key data because of len %d, %d, %d\n",
- info->len, FWDL_SECTION_PER_PKT_LEN, info->key_len);
+ if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len)
+ rtw89_warn(rtwdev,
+ "ignore to copy key data because of len %d, %d, %d, %d\n",
+ info->len, FWDL_SECTION_PER_PKT_LEN,
+ info->key_len, residue_len);
else
copy_key = true;
}
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 2e2035705881..83fcd5edc057 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -261,6 +261,7 @@ struct rtw89_fw_hdr_section_info {
u8 redl;
const u8 *addr;
u32 len;
+ u32 len_override;
u32 dladdr;
u32 mssc;
u8 type;
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/8] wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to register
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
` (3 preceding siblings ...)
2024-10-30 2:21 ` [PATCH 4/8] wifi: rtw89: fw: shrink download size of security section for RTL8852B Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 6/8] wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to share with v0 Ping-Ke Shih
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
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>
---
drivers/net/wireless/realtek/rtw89/fw.c | 4 ++++
drivers/net/wireless/realtek/rtw89/fw.h | 3 +++
drivers/net/wireless/realtek/rtw89/mac.c | 15 +++++++++++++++
drivers/net/wireless/realtek/rtw89/mac.h | 11 +++++++++++
drivers/net/wireless/realtek/rtw89/mac_be.c | 1 +
drivers/net/wireless/realtek/rtw89/reg.h | 2 ++
6 files changed, 36 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 0af0e539e976..0b2987bd662e 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -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);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 83fcd5edc057..bd7680264849 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -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,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 7ed29bc69009..8985bd8fa38f 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -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,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 4d4b505e3bc9..18579c020548 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -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
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index e0d7cf9fd7ee..f7a396c8a3cd 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -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,
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 69678eab2309..18ec7c0252fb 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -196,6 +196,8 @@
#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)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/8] wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to share with v0
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
` (4 preceding siblings ...)
2024-10-30 2:21 ` [PATCH 5/8] wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to register Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 7/8] wifi: rtw89: fw: use common function to parse security section for WiFi 6 chips Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 8/8] wifi: rtw89: mac: no configure CMAC/DMAC tables for firmware secure boot Ping-Ke Shih
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
The security section can be a common parser for v0 and v1 format of
firmware header, so move retrieval code of v1 MSSC from the function, and
then sharing becomes possible.
Not logic change at all.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 0b2987bd662e..4229065e07e8 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -241,7 +241,6 @@ static int __get_mssc_key_idx(struct rtw89_dev *rtwdev,
static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
- const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
@@ -324,18 +323,14 @@ static int __parse_formatted_mssc(struct rtw89_dev *rtwdev,
static int __parse_security_section(struct rtw89_dev *rtwdev,
struct rtw89_fw_bin_info *info,
struct rtw89_fw_hdr_section_info *section_info,
- const struct rtw89_fw_hdr_section_v1 *section,
const void *content,
u32 *mssc_len)
{
int ret;
- section_info->mssc =
- le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
-
if (section_info->mssc == FORMATTED_MSSC) {
ret = __parse_formatted_mssc(rtwdev, info, section_info,
- section, content, mssc_len);
+ content, mssc_len);
if (ret)
return -EINVAL;
} else {
@@ -401,8 +396,11 @@ static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 le
section_info->addr = bin;
if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
+ section_info->mssc =
+ le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
+
ret = __parse_security_section(rtwdev, info, section_info,
- section, bin, &mssc_len);
+ bin, &mssc_len);
if (ret)
return ret;
} else {
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/8] wifi: rtw89: fw: use common function to parse security section for WiFi 6 chips
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
` (5 preceding siblings ...)
2024-10-30 2:21 ` [PATCH 6/8] wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to share with v0 Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 8/8] wifi: rtw89: mac: no configure CMAC/DMAC tables for firmware secure boot Ping-Ke Shih
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
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>
---
drivers/net/wireless/realtek/rtw89/fw.c | 57 +++++++++++++++++++------
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 4229065e07e8..538622c29e42 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 {
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/8] wifi: rtw89: mac: no configure CMAC/DMAC tables for firmware secure boot
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
` (6 preceding siblings ...)
2024-10-30 2:21 ` [PATCH 7/8] wifi: rtw89: fw: use common function to parse security section for WiFi 6 chips Ping-Ke Shih
@ 2024-10-30 2:21 ` Ping-Ke Shih
7 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-10-30 2:21 UTC (permalink / raw)
To: linux-wireless
The initial CMAC/DMAC tables used by WiFi 6 chips are not needed to be
called for firmware secure boot. Otherwise, it causes firmware abnormal
and throw warnings.
rtw89_8852be 0000:03:00.0: FW status = 0x1400
rtw89_8852be 0000:03:00.0: FW BADADDR = 0xb872f800
rtw89_8852be 0000:03:00.0: FW EPC/RA = 0xb89333b7
rtw89_8852be 0000:03:00.0: FW MISC = 0x0
rtw89_8852be 0000:03:00.0: R_AX_HALT_C2H = 0x10002010
rtw89_8852be 0000:03:00.0: R_AX_SER_DBG_INFO = 0x0
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c97
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c95
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c99
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c9b
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c9f
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c9b
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c99
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c9d
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c97
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c97
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c97
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c99
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c97
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c9f
rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb89a2c99
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/mac.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 8985bd8fa38f..7907b84d204b 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -4000,9 +4000,10 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
u8 i;
- if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
for (i = 0; i < 4; i++) {
@@ -4014,7 +4015,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
- if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
+
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
return;
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common
2024-10-30 2:21 ` [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common Ping-Ke Shih
@ 2024-11-06 6:08 ` Ping-Ke Shih
0 siblings, 0 replies; 10+ messages in thread
From: Ping-Ke Shih @ 2024-11-06 6:08 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless
Ping-Ke Shih <pkshih@realtek.com> wrote:
> The secure key used by certain hardware module is programmed in efuse, so
> driver should read the information from efuse before downloading firmware.
>
> Originally only RTL8922AE can support firmware secure boot, and read efuse
> during chip power on. To extend to support all chips, move the caller to
> common power on flow and add separate functions to read efuse for
> WiFi 6 chips.
>
> No logic change at all.
>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
8 patch(es) applied to rtw-next branch of rtw.git, thanks.
d230e215e3b9 wifi: rtw89: efuse: move reading efuse of fw secure info to common
0ce1df1cc352 wifi: rtw89: efuse: move recognize firmware MSS info v1 to common
e1551a79c499 wifi: rtw89: efuse: read firmware secure info v0 from efuse for WiFi 6 chips
40c06adf63d0 wifi: rtw89: fw: shrink download size of security section for RTL8852B
86ee0024e582 wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to register
f9fe3baeb204 wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to share with v0
6d995ef770af wifi: rtw89: fw: use common function to parse security section for WiFi 6 chips
da824a86b07c wifi: rtw89: mac: no configure CMAC/DMAC tables for firmware secure boot
---
https://github.com/pkshih/rtw.git
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-11-06 6:08 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-30 2:21 [PATCH 0/8] wifi: rtw89: support firmware secure boot for WiFi 6 chips Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 1/8] wifi: rtw89: efuse: move reading efuse of fw secure info to common Ping-Ke Shih
2024-11-06 6:08 ` Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 2/8] wifi: rtw89: efuse: move recognize firmware MSS info v1 " Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 3/8] wifi: rtw89: efuse: read firmware secure info v0 from efuse for WiFi 6 chips Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 4/8] wifi: rtw89: fw: shrink download size of security section for RTL8852B Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 5/8] wifi: rtw89: fw: set recorded IDMEM share mode in firmware header to register Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 6/8] wifi: rtw89: fw: move v1 MSSC out of __parse_security_section() to share with v0 Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 7/8] wifi: rtw89: fw: use common function to parse security section for WiFi 6 chips Ping-Ke Shih
2024-10-30 2:21 ` [PATCH 8/8] wifi: rtw89: mac: no configure CMAC/DMAC tables for firmware secure boot Ping-Ke Shih
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).