From dd59c6a32b7189f51947edc5b15939367729dd85 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 1 Aug 2023 10:11:27 +0800 Subject: [PATCH] wifi: rtw89: return failure if needed firmware elements are not recognized WiFi 7 chips doesn't have static const tables defined in driver. If tables aren't loaded properly from firmware file, driver can get NULL pointer access exception. One way is to add the checking statements when trying to access these tables, but I choose to check them right after loading firmware elements from firmware file, so I don't need to add error handlers everywhere. Currently, the needed firmware elements of WiFi 6 chips are all zero, and coming WiFi 7 chip will need at least BB MCU, parameters of BB and RF. We will add them after 8922AE is verified. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230801021127.15919-9-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 11 +++++++++++ drivers/net/wireless/realtek/rtw89/fw.h | 2 ++ 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 + 7 files changed, 18 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index bf6d8ef89097c..fa4bbc4095ab9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3382,6 +3382,7 @@ struct rtw89_chip_info { const char *fw_basename; u8 fw_format_max; bool try_ce_fw; + u32 needed_fw_elms; u32 fifo_size; bool small_fifo_size; u32 dle_scc_rsvd_size; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 1ca99dad2ac0a..2811a94b5f69a 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -635,6 +635,8 @@ int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) { struct rtw89_fw_info *fw_info = &rtwdev->fw; const struct firmware *firmware = fw_info->req.firmware; + const struct rtw89_chip_info *chip = rtwdev->chip; + u32 unrecognized_elements = chip->needed_fw_elms; const struct rtw89_fw_element_handler *handler; const struct rtw89_fw_element_hdr *hdr; u32 elm_size; @@ -642,6 +644,8 @@ int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) u32 offset; int ret; + BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM); + offset = rtw89_mfw_get_size(rtwdev); offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); if (offset == 0) @@ -672,11 +676,18 @@ int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev) rtw89_info(rtwdev, "Firmware element %s version: %4ph\n", handler->name, hdr->ver); + unrecognized_elements &= ~BIT(elem_id); next: offset += sizeof(*hdr) + elm_size; offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN); } + if (unrecognized_elements) { + rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n", + unrecognized_elements); + return -ENOENT; + } + return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index cbb130537e07d..775f4e8fbda4d 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -3412,6 +3412,8 @@ enum rtw89_fw_element_id { RTW89_FW_ELEMENT_ID_RADIO_C = 6, RTW89_FW_ELEMENT_ID_RADIO_D = 7, RTW89_FW_ELEMENT_ID_RF_NCTL = 8, + + RTW89_FW_ELEMENT_ID_NUM, }; struct rtw89_fw_element_hdr { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 456b8369fb068..b5740639e2679 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -2339,6 +2339,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, + .needed_fw_elms = 0, .fifo_size = 196608, .small_fifo_size = true, .dle_scc_rsvd_size = 98304, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 0fc5eb777a4aa..41f05276406d1 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2076,6 +2076,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, + .needed_fw_elms = 0, .fifo_size = 458752, .small_fifo_size = false, .dle_scc_rsvd_size = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index d76d74cc867ad..eb2210cb7e099 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -2508,6 +2508,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, + .needed_fw_elms = 0, .fifo_size = 196608, .small_fifo_size = true, .dle_scc_rsvd_size = 98304, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index f269832b2bc6f..b1af72fbf0857 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2807,6 +2807,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, + .needed_fw_elms = 0, .fifo_size = 458752, .small_fifo_size = false, .dle_scc_rsvd_size = 0, -- 2.30.2