From: Emmanuel Grumbach The structure in firmware runtime will need to grow because we're adding a subband for UNII-9. This means that we will soon no longer be able to just memcpy the data from the UEFI table. The layout of the array will change. Tediously copy the data byte-byte to make sure things get to the right place even when we'll increase the number of subbands. Make it easier for the uefi_cnv_var_ppag structure to grow by simpiflying the layout it becomes an array of s8. The layout of the structure becomes less obvious from the structure's declaration, but then the code is more flexible. Don't use UEFI_SAR_MAX_SUB_BANDS_NUM for the number of bands for PPAG. Of course, SAR related structures will grow in future patches, but decouple SAR and PPAG to make the work easier. Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 23 ++++++++++++++++---- drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 16 +++++--------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index d4e1ab1f7c84..38f9d9adf90e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -571,9 +571,11 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_ppag *data; int ret = 0; + int data_sz = sizeof(*data) + sizeof(data->vals[0]) * + IWL_NUM_CHAIN_LIMITS * UEFI_PPAG_SUB_BANDS_NUM; data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_PPAG_NAME, - "PPAG", sizeof(*data), NULL); + "PPAG", data_sz, NULL); if (IS_ERR(data)) return -EINVAL; @@ -589,9 +591,22 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt) fwrt->ppag_flags = iwl_bios_get_ppag_flags(data->ppag_modes, fwrt->ppag_bios_rev); - BUILD_BUG_ON(sizeof(fwrt->ppag_chains) != sizeof(data->ppag_chains)); - memcpy(&fwrt->ppag_chains, &data->ppag_chains, - sizeof(data->ppag_chains)); + /* + * Make sure fwrt has enough room to hold + * data coming from the UEFI table + */ + BUILD_BUG_ON(ARRAY_SIZE(fwrt->ppag_chains) * + ARRAY_SIZE(fwrt->ppag_chains[0].subbands) < + IWL_NUM_CHAIN_LIMITS * UEFI_PPAG_SUB_BANDS_NUM); + + for (int chain = 0; chain < IWL_NUM_CHAIN_LIMITS; chain++) { + for (int subband = 0; + subband < UEFI_PPAG_SUB_BANDS_NUM; + subband++) + fwrt->ppag_chains[chain].subbands[subband] = + data->vals[chain * UEFI_PPAG_SUB_BANDS_NUM + subband]; + } + fwrt->ppag_bios_source = BIOS_SOURCE_UEFI; out: kfree(data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index c6940a3c03ea..4f0ce068a589 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -77,6 +77,7 @@ struct uefi_cnv_common_step_data { } __packed; #define UEFI_SAR_MAX_SUB_BANDS_NUM 11 +#define UEFI_PPAG_SUB_BANDS_NUM 11 #define UEFI_SAR_MAX_CHAINS_PER_PROFILE 4 /* @@ -136,24 +137,19 @@ struct uefi_cnv_var_wgds { struct iwl_geo_profile geo_profiles[BIOS_GEO_MAX_PROFILE_NUM]; } __packed; -/* - * struct uefi_ppag_chain - PPAG table for a specific chain - * @subbands: the PPAG values for band - */ -struct uefi_ppag_chain { - s8 subbands[UEFI_SAR_MAX_SUB_BANDS_NUM]; -}; - /* * struct uefi_cnv_var_ppag - PPAG table as defined in UEFI * @revision: the revision of the table * @ppag_modes: values from &enum iwl_ppag_flags - * @ppag_chains: the PPAG values per chain and band + * @vals: the PPAG values per chain and band as an array. + * vals[chain * num_of_subbands + subband] will return the right value. + * num_of_subbands is %UEFI_PPAG_SUB_BANDS_NUM. + * the max number of chains is currently 2 */ struct uefi_cnv_var_ppag { u8 revision; u32 ppag_modes; - struct uefi_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS]; + s8 vals[]; } __packed; /* struct uefi_cnv_var_wtas - WTAS tabled as defined in UEFI -- 2.34.1