From: Emmanuel Grumbach Date: Thu, 19 Mar 2026 18:48:49 +0000 (+0200) Subject: wifi: iwlwifi: uefi: add support for WGDS rev4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c30e4e03721dc75adfff6b4c2ad671dab71f319c;p=thirdparty%2Flinux.git wifi: iwlwifi: uefi: add support for WGDS rev4 This new revision includes support for UNII-9. It adds a subband. Signed-off-by: Emmanuel Grumbach Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260319204647.ad8e49c3a9e1.I51170ba78a706f976e93918d6473185d41e4306d@changeid --- diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h index a3684514c904d..6fffc032efd31 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h @@ -25,7 +25,7 @@ #define BIOS_PPAG_MAX_SUB_BANDS_NUM 12 #define BIOS_GEO_NUM_CHAINS 2 -#define BIOS_GEO_MAX_NUM_BANDS 3 +#define BIOS_GEO_MAX_NUM_BANDS 4 #define BIOS_GEO_MAX_PROFILE_NUM 8 #define BIOS_GEO_MIN_PROFILE_NUM 3 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index ccac503851753..f73340c7d5379 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -593,21 +593,39 @@ out: int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_wgds *data; + unsigned long expected_size; + unsigned long size; + int profile_size; + int n_subbands; int ret = 0; data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_WGDS_NAME, "WGDS", UEFI_WGDS_TABLE_SIZE_REV3, - NULL); + &size); if (IS_ERR(data)) return -EINVAL; - if (data->revision != IWL_UEFI_WGDS_REVISION) { + switch (data->revision) { + case 3: + expected_size = UEFI_WGDS_TABLE_SIZE_REV3; + n_subbands = UEFI_GEO_NUM_BANDS_REV3; + break; + case 4: + expected_size = UEFI_WGDS_TABLE_SIZE_REV4; + n_subbands = UEFI_GEO_NUM_BANDS_REV4; + break; + default: ret = -EINVAL; IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI WGDS revision:%d\n", data->revision); goto out; } + if (size != expected_size) { + ret = -EINVAL; + goto out; + } + if (data->num_profiles < BIOS_GEO_MIN_PROFILE_NUM || data->num_profiles > BIOS_GEO_MAX_PROFILE_NUM) { ret = -EINVAL; @@ -618,8 +636,7 @@ int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt) 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) || + n_subbands > ARRAY_SIZE(fwrt->geo_profiles[0].bands) || BIOS_GEO_NUM_CHAINS > ARRAY_SIZE(fwrt->geo_profiles[0].bands[0].chains))) { ret = -EINVAL; @@ -627,13 +644,12 @@ int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt) } fwrt->geo_rev = data->revision; + profile_size = 3 * n_subbands; for (int prof = 0; prof < data->num_profiles; prof++) { - const u8 *val = &data->vals[UEFI_WGDS_PROFILE_SIZE_REV3 * prof]; + const u8 *val = &data->vals[profile_size * prof]; struct iwl_geo_profile *geo_prof = &fwrt->geo_profiles[prof]; - for (int subband = 0; - subband < UEFI_GEO_NUM_BANDS_REV3; - subband++) { + for (int subband = 0; subband < n_subbands; subband++) { geo_prof->bands[subband].max = *val++; for (int chain = 0; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index 3959937242d8f..0d3dac65178cb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -31,7 +31,6 @@ #define IWL_SGOM_MAP_SIZE 339 #define IWL_UATS_MAP_SIZE 339 -#define IWL_UEFI_WGDS_REVISION 3 #define IWL_UEFI_MIN_WTAS_REVISION 1 #define IWL_UEFI_MAX_WTAS_REVISION 2 #define IWL_UEFI_SPLC_REVISION 0 @@ -82,6 +81,7 @@ struct uefi_cnv_common_step_data { #define UEFI_SAR_MAX_CHAINS_PER_PROFILE 4 #define UEFI_GEO_NUM_BANDS_REV3 3 +#define UEFI_GEO_NUM_BANDS_REV4 4 /* * struct uefi_cnv_var_wrds - WRDS table as defined in UEFI @@ -150,7 +150,8 @@ struct uefi_cnv_var_ewrd { * @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. + * There are %UEFI_GEO_NUM_BANDS_REV3 or %UEFI_GEO_NUM_BANDS_REV4 subbands + * depending on the revision. */ struct uefi_cnv_var_wgds { u8 revision; @@ -163,10 +164,16 @@ struct uefi_cnv_var_wgds { */ #define UEFI_WGDS_PROFILE_SIZE_REV3 (sizeof(u8) * 3 * UEFI_GEO_NUM_BANDS_REV3) +#define UEFI_WGDS_PROFILE_SIZE_REV4 (sizeof(u8) * 3 * UEFI_GEO_NUM_BANDS_REV4) + #define UEFI_WGDS_TABLE_SIZE_REV3 \ (offsetof(struct uefi_cnv_var_wgds, vals) + \ UEFI_WGDS_PROFILE_SIZE_REV3 * BIOS_GEO_MAX_PROFILE_NUM) +#define UEFI_WGDS_TABLE_SIZE_REV4 \ + (offsetof(struct uefi_cnv_var_wgds, vals) + \ + UEFI_WGDS_PROFILE_SIZE_REV4 * BIOS_GEO_MAX_PROFILE_NUM) + /* * struct uefi_cnv_var_ppag - PPAG table as defined in UEFI * @revision: the revision of the table