{
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;
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);
} __packed;
#define UEFI_SAR_MAX_SUB_BANDS_NUM 11
+#define UEFI_PPAG_SUB_BANDS_NUM 11
#define UEFI_SAR_MAX_CHAINS_PER_PROFILE 4
/*
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