Commit 1b073b35 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

wifi: rtw89: introduce v1 format of firmware header

New firmware header is used by upcoming WiFi 7 chips to have more
information, so use common field w3[31:24] to determine header version,
and then use corresponding function to read firmware version and commit ID:

rtw89_8852be 0000:03:00.0: Firmware version 0.29.29.1 (799134c3), cmd version 1, type 5
rtw89_8852be 0000:03:00.0: Firmware version 0.29.29.1 (799134c3), cmd version 1, type 3
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/20230801021127.15919-4-pkshih@realtek.com
parent cad2bd8a
...@@ -3563,6 +3563,7 @@ enum rtw89_fw_feature { ...@@ -3563,6 +3563,7 @@ enum rtw89_fw_feature {
}; };
struct rtw89_fw_suit { struct rtw89_fw_suit {
enum rtw89_fw_type type;
const u8 *data; const u8 *data;
u32 size; u32 size;
u8 major_ver; u8 major_ver;
...@@ -3575,6 +3576,8 @@ struct rtw89_fw_suit { ...@@ -3575,6 +3576,8 @@ struct rtw89_fw_suit {
u16 build_hour; u16 build_hour;
u16 build_min; u16 build_min;
u8 cmd_ver; u8 cmd_ver;
u8 hdr_ver;
u32 commitid;
}; };
#define RTW89_FW_VER_CODE(major, minor, sub, idx) \ #define RTW89_FW_VER_CODE(major, minor, sub, idx) \
......
...@@ -196,30 +196,72 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, ...@@ -196,30 +196,72 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
return 0; return 0;
} }
static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev, static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev,
enum rtw89_fw_type type, struct rtw89_fw_suit *fw_suit,
struct rtw89_fw_suit *fw_suit) const struct rtw89_fw_hdr *hdr)
{ {
const struct rtw89_fw_hdr *hdr = (const struct rtw89_fw_hdr *)fw_suit->data;
if (type == RTW89_FW_LOGFMT)
return;
fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION); fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION);
fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION); fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION);
fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION); fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION);
fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX); fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX);
fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID);
fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR); fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR);
fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH); fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH);
fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE); fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE);
fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR); fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR);
fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN); fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN);
fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION); fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION);
}
static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev,
struct rtw89_fw_suit *fw_suit,
const struct rtw89_fw_hdr_v1 *hdr)
{
fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION);
fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION);
fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION);
fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX);
fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID);
fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR);
fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH);
fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE);
fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR);
fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN);
fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION);
}
static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
enum rtw89_fw_type type,
struct rtw89_fw_suit *fw_suit)
{
const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data;
const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data;
if (type == RTW89_FW_LOGFMT)
return 0;
fw_suit->type = type;
fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER);
switch (fw_suit->hdr_ver) {
case 0:
rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0);
break;
case 1:
rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1);
break;
default:
rtw89_err(rtwdev, "Unknown firmware header version %u\n",
fw_suit->hdr_ver);
return -ENOENT;
}
rtw89_info(rtwdev, rtw89_info(rtwdev,
"Firmware version %u.%u.%u.%u, cmd version %u, type %u\n", "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n",
fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
fw_suit->sub_idex, fw_suit->cmd_ver, type); fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type);
return 0;
} }
static static
...@@ -233,9 +275,7 @@ int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, ...@@ -233,9 +275,7 @@ int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
if (ret) if (ret)
return ret; return ret;
rtw89_fw_update_ver(rtwdev, type, fw_suit); return rtw89_fw_update_ver(rtwdev, type, fw_suit);
return 0;
} }
#define __DEF_FW_FEAT_COND(__cond, __op) \ #define __DEF_FW_FEAT_COND(__cond, __op) \
......
...@@ -463,7 +463,9 @@ struct rtw89_fw_hdr { ...@@ -463,7 +463,9 @@ struct rtw89_fw_hdr {
#define FW_HDR_W1_MINOR_VERSION GENMASK(15, 8) #define FW_HDR_W1_MINOR_VERSION GENMASK(15, 8)
#define FW_HDR_W1_SUBVERSION GENMASK(23, 16) #define FW_HDR_W1_SUBVERSION GENMASK(23, 16)
#define FW_HDR_W1_SUBINDEX GENMASK(31, 24) #define FW_HDR_W1_SUBINDEX GENMASK(31, 24)
#define FW_HDR_W2_COMMITID GENMASK(31, 0)
#define FW_HDR_W3_LEN GENMASK(23, 16) #define FW_HDR_W3_LEN GENMASK(23, 16)
#define FW_HDR_W3_HDR_VER GENMASK(31, 24)
#define FW_HDR_W4_MONTH GENMASK(7, 0) #define FW_HDR_W4_MONTH GENMASK(7, 0)
#define FW_HDR_W4_DATE GENMASK(15, 8) #define FW_HDR_W4_DATE GENMASK(15, 8)
#define FW_HDR_W4_HOUR GENMASK(23, 16) #define FW_HDR_W4_HOUR GENMASK(23, 16)
...@@ -473,6 +475,37 @@ struct rtw89_fw_hdr { ...@@ -473,6 +475,37 @@ struct rtw89_fw_hdr {
#define FW_HDR_W7_DYN_HDR BIT(16) #define FW_HDR_W7_DYN_HDR BIT(16)
#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24) #define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24)
struct rtw89_fw_hdr_v1 {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
__le32 w7;
__le32 w8;
__le32 w9;
__le32 w10;
__le32 w11;
} __packed;
#define FW_HDR_V1_W1_MAJOR_VERSION GENMASK(7, 0)
#define FW_HDR_V1_W1_MINOR_VERSION GENMASK(15, 8)
#define FW_HDR_V1_W1_SUBVERSION GENMASK(23, 16)
#define FW_HDR_V1_W1_SUBINDEX GENMASK(31, 24)
#define FW_HDR_V1_W2_COMMITID GENMASK(31, 0)
#define FW_HDR_V1_W3_CMD_VERSERION GENMASK(23, 16)
#define FW_HDR_V1_W3_HDR_VER GENMASK(31, 24)
#define FW_HDR_V1_W4_MONTH GENMASK(7, 0)
#define FW_HDR_V1_W4_DATE GENMASK(15, 8)
#define FW_HDR_V1_W4_HOUR GENMASK(23, 16)
#define FW_HDR_V1_W4_MIN GENMASK(31, 24)
#define FW_HDR_V1_W5_YEAR GENMASK(15, 0)
#define FW_HDR_V1_W5_HDR_SIZE GENMASK(31, 16)
#define FW_HDR_V1_W6_SEC_NUM GENMASK(15, 8)
#define FW_HDR_V1_W7_DYN_HDR BIT(16)
static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val) static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val)
{ {
le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 0)); le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 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