From: Emmanuel Grumbach Date: Thu, 19 Mar 2026 18:48:48 +0000 (+0200) Subject: wifi: iwlwifi: uefi: open code the parsing of the WGDS table X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de985774e2175483bfffb5598bea4e39c12a181a;p=thirdparty%2Flinux.git wifi: iwlwifi: uefi: open code the parsing of the WGDS table We will soon add support for UNII-9 band in the WGDS table. We need to decouple the UEFI code from the firmware runtime code. The firmware runtime is just a software object which will need to grow and UEFI objects need a new revision to grow. Existing systems will keep the same UEFI objects. Just like PPAG and SAR, stop using structures to parse the UEFI tables since the layout depends on the revision. The support for the new revision will be added in the next patch, for now, just do the ground work. Signed-off-by: Emmanuel Grumbach Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260319204647.140706e6e91f.I83ca04932bc21aa358119890001e876ced1e1bda@changeid --- diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 3d3d698bacd0c..ccac503851753 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -593,10 +593,11 @@ out: int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_wgds *data; - int i, ret = 0; + int ret = 0; data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_WGDS_NAME, - "WGDS", sizeof(*data), NULL); + "WGDS", UEFI_WGDS_TABLE_SIZE_REV3, + NULL); if (IS_ERR(data)) return -EINVAL; @@ -615,10 +616,32 @@ int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt) goto out; } + if (WARN_ON(BIOS_GEO_MAX_PROFILE_NUM > + ARRAY_SIZE(fwrt->geo_profiles) || + UEFI_GEO_NUM_BANDS_REV3 > + ARRAY_SIZE(fwrt->geo_profiles[0].bands) || + BIOS_GEO_NUM_CHAINS > + ARRAY_SIZE(fwrt->geo_profiles[0].bands[0].chains))) { + ret = -EINVAL; + goto out; + } + fwrt->geo_rev = data->revision; - for (i = 0; i < data->num_profiles; i++) - memcpy(&fwrt->geo_profiles[i], &data->geo_profiles[i], - sizeof(struct iwl_geo_profile)); + for (int prof = 0; prof < data->num_profiles; prof++) { + const u8 *val = &data->vals[UEFI_WGDS_PROFILE_SIZE_REV3 * prof]; + struct iwl_geo_profile *geo_prof = &fwrt->geo_profiles[prof]; + + for (int subband = 0; + subband < UEFI_GEO_NUM_BANDS_REV3; + subband++) { + geo_prof->bands[subband].max = *val++; + + for (int chain = 0; + chain < BIOS_GEO_NUM_CHAINS; + chain++) + geo_prof->bands[subband].chains[chain] = *val++; + } + } fwrt->geo_num_profiles = data->num_profiles; fwrt->geo_enabled = true; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index aa5a4c5a73922..3959937242d8f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -81,6 +81,8 @@ struct uefi_cnv_common_step_data { #define UEFI_SAR_MAX_CHAINS_PER_PROFILE 4 +#define UEFI_GEO_NUM_BANDS_REV3 3 + /* * struct uefi_cnv_var_wrds - WRDS table as defined in UEFI * @@ -145,14 +147,26 @@ struct uefi_cnv_var_ewrd { * @revision: the revision of the table * @num_profiles: the number of geo profiles we have in the table. * The first 3 are mandatory, and can have up to 8. - * @geo_profiles: a per-profile table of the offsets to add to SAR values. + * @vals: a per-profile table of the offsets to add to SAR values. This is an + * array of profiles, each profile is an array of + * &struct iwl_geo_profile_band, one for each subband. + * There are %UEFI_GEO_NUM_BANDS_REV3 subbands. */ struct uefi_cnv_var_wgds { u8 revision; u8 num_profiles; - struct iwl_geo_profile geo_profiles[BIOS_GEO_MAX_PROFILE_NUM]; + u8 vals[]; } __packed; +/* struct iwl_geo_profile_band is 3 bytes-long, but since it is not packed, + * we can't use sizeof() + */ +#define UEFI_WGDS_PROFILE_SIZE_REV3 (sizeof(u8) * 3 * UEFI_GEO_NUM_BANDS_REV3) + +#define UEFI_WGDS_TABLE_SIZE_REV3 \ + (offsetof(struct uefi_cnv_var_wgds, vals) + \ + UEFI_WGDS_PROFILE_SIZE_REV3 * BIOS_GEO_MAX_PROFILE_NUM) + /* * struct uefi_cnv_var_ppag - PPAG table as defined in UEFI * @revision: the revision of the table