wifi: iwlwifi: iwl-drv: refactor image loading a bit

Refactor some parts of the image loading to be able to
extend the code for external FSEQ image loading more
easily.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241228223206.224ac6599bbe.Iadc1974d633eec09797522f7d3fa543ea18bd7f6@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2024-12-28 22:34:09 +02:00
parent 4c83e41c3f
commit 5f36bb50d2

View File

@@ -137,8 +137,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
memset(&drv->fw, 0, sizeof(drv->fw));
}
static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
struct fw_sec *sec)
static int iwl_alloc_fw_desc(struct fw_desc *desc, struct fw_sec *sec)
{
void *data;
@@ -318,17 +317,6 @@ struct iwl_firmware_pieces {
size_t n_mem_tlv;
};
/*
* These functions are just to extract uCode section data from the pieces
* structure.
*/
static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces,
enum iwl_ucode_type type,
int sec)
{
return &pieces->img[type].sec[sec];
}
static void alloc_sec_data(struct iwl_firmware_pieces *pieces,
enum iwl_ucode_type type,
int sec)
@@ -389,22 +377,18 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces,
/*
* Gets uCode section from tlv.
*/
static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
const void *data, enum iwl_ucode_type type,
int size)
static int iwl_store_ucode_sec(struct fw_img_parsing *img,
const void *data, int size)
{
struct fw_img_parsing *img;
struct fw_sec *sec;
const struct fw_sec_parsing *sec_parse;
size_t alloc_size;
if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
return -1;
if (WARN_ON(!img || !data))
return -EINVAL;
sec_parse = (const struct fw_sec_parsing *)data;
img = &pieces->img[type];
alloc_size = sizeof(*img->sec) * (img->sec_counter + 1);
sec = krealloc(img->sec, alloc_size, GFP_KERNEL);
if (!sec)
@@ -900,18 +884,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
le32_to_cpup((const __le32 *)tlv_data);
break;
case IWL_UCODE_TLV_SEC_RT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_REGULAR],
tlv_data, tlv_len);
drv->fw.type = IWL_FW_MVM;
break;
case IWL_UCODE_TLV_SEC_INIT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_INIT],
tlv_data, tlv_len);
drv->fw.type = IWL_FW_MVM;
break;
case IWL_UCODE_TLV_SEC_WOWLAN:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_WOWLAN],
tlv_data, tlv_len);
drv->fw.type = IWL_FW_MVM;
break;
case IWL_UCODE_TLV_DEF_CALIB:
@@ -932,18 +916,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
FW_PHY_CFG_RX_CHAIN_POS;
break;
case IWL_UCODE_TLV_SECURE_SEC_RT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_REGULAR],
tlv_data, tlv_len);
drv->fw.type = IWL_FW_MVM;
break;
case IWL_UCODE_TLV_SECURE_SEC_INIT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_INIT],
tlv_data, tlv_len);
drv->fw.type = IWL_FW_MVM;
break;
case IWL_UCODE_TLV_SECURE_SEC_WOWLAN:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_WOWLAN],
tlv_data, tlv_len);
drv->fw.type = IWL_FW_MVM;
break;
case IWL_UCODE_TLV_NUM_OF_CPU:
@@ -1110,9 +1094,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
}
case IWL_UCODE_TLV_SEC_RT_USNIFFER:
*usniffer_images = true;
iwl_store_ucode_sec(pieces, tlv_data,
IWL_UCODE_REGULAR_USNIFFER,
tlv_len);
iwl_store_ucode_sec(&pieces->img[IWL_UCODE_REGULAR_USNIFFER],
tlv_data, tlv_len);
break;
case IWL_UCODE_TLV_PAGING:
if (tlv_len != sizeof(u32))
@@ -1337,24 +1320,29 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -EINVAL;
}
static int iwl_alloc_ucode_mem(struct fw_img *out, struct fw_img_parsing *img)
{
struct fw_desc *sec;
sec = kcalloc(img->sec_counter, sizeof(*sec), GFP_KERNEL);
if (!sec)
return -ENOMEM;
out->sec = sec;
out->num_sec = img->sec_counter;
for (int i = 0; i < out->num_sec; i++)
if (iwl_alloc_fw_desc(&sec[i], &img->sec[i]))
return -ENOMEM;
return 0;
}
static int iwl_alloc_ucode(struct iwl_drv *drv,
struct iwl_firmware_pieces *pieces,
enum iwl_ucode_type type)
{
int i;
struct fw_desc *sec;
sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL);
if (!sec)
return -ENOMEM;
drv->fw.img[type].sec = sec;
drv->fw.img[type].num_sec = pieces->img[type].sec_counter;
for (i = 0; i < pieces->img[type].sec_counter; i++)
if (iwl_alloc_fw_desc(drv, &sec[i], get_sec(pieces, type, i)))
return -ENOMEM;
return 0;
return iwl_alloc_ucode_mem(&drv->fw.img[type], &pieces->img[type]);
}
static int validate_sec_sizes(struct iwl_drv *drv,