wifi: rtw89: return failure if needed firmware elements are not recognized
authorPing-Ke Shih <pkshih@realtek.com>
Tue, 1 Aug 2023 02:11:27 +0000 (10:11 +0800)
committerKalle Valo <kvalo@kernel.org>
Thu, 3 Aug 2023 12:04:12 +0000 (15:04 +0300)
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 <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230801021127.15919-9-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c

index bf6d8ef89097c1dfee86f1c6c31dc659e1555222..fa4bbc4095ab933709033eb2f04eb8dd71858263 100644 (file)
@@ -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;
index 1ca99dad2ac0a19bb74ef855b1166464f9c2d94b..2811a94b5f69ad90ffec0dcbb3502f3741187580 100644 (file)
@@ -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;
 }
 
index cbb130537e07d6175bc7ef85631c91c77206ff77..775f4e8fbda4dd4a8d9e8e0092c7c56510f1bc5f 100644 (file)
@@ -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 {
index 456b8369fb06890ff3abf36e429f12e6e8a3d721..b5740639e267917e07afa77a8fee2f2aa134e843 100644 (file)
@@ -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,
index 0fc5eb777a4aadc773b63a529c4dcb603984f31b..41f05276406d15c25908b8a8fad4e7b7f63afcf7 100644 (file)
@@ -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,
index d76d74cc867ad5917996d54791d5419eecda08fb..eb2210cb7e09995f6df18193ae4cee6de0c76700 100644 (file)
@@ -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,
index f269832b2bc6ff6660efc8e78706e995d14e53fd..b1af72fbf08573fe26b9325e6804cb3512f04138 100644 (file)
@@ -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,