xref: /linux/drivers/net/wireless/intel/iwlwifi/fw/uefi.h (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /*
3  * Copyright(c) 2021-2026 Intel Corporation
4  */
5 #ifndef __iwl_fw_uefi__
6 #define __iwl_fw_uefi__
7 
8 #include "fw/regulatory.h"
9 
10 #define IWL_UEFI_OEM_PNVM_NAME		L"UefiCnvWlanOemSignedPnvm"
11 #define IWL_UEFI_REDUCED_POWER_NAME	L"UefiCnvWlanReducedPower"
12 #define IWL_UEFI_SGOM_NAME		L"UefiCnvWlanSarGeoOffsetMapping"
13 #define IWL_UEFI_STEP_NAME		L"UefiCnvCommonSTEP"
14 #define IWL_UEFI_UATS_NAME		L"CnvUefiWlanUATS"
15 #define IWL_UEFI_WRDS_NAME		L"UefiCnvWlanWRDS"
16 #define IWL_UEFI_EWRD_NAME		L"UefiCnvWlanEWRD"
17 #define IWL_UEFI_WGDS_NAME		L"UefiCnvWlanWGDS"
18 #define IWL_UEFI_PPAG_NAME		L"UefiCnvWlanPPAG"
19 #define IWL_UEFI_WTAS_NAME		L"UefiCnvWlanWTAS"
20 #define IWL_UEFI_SPLC_NAME		L"UefiCnvWlanSPLC"
21 #define IWL_UEFI_WRDD_NAME		L"UefiCnvWlanWRDD"
22 #define IWL_UEFI_ECKV_NAME		L"UefiCnvCommonECKV"
23 #define IWL_UEFI_DSM_NAME		L"UefiCnvWlanGeneralCfg"
24 #define IWL_UEFI_WBEM_NAME		L"UefiCnvWlanWBEM"
25 #define IWL_UEFI_PUNCTURING_NAME	L"UefiCnvWlanPuncturing"
26 #define IWL_UEFI_DSBR_NAME		L"UefiCnvCommonDSBR"
27 #define IWL_UEFI_WPFC_NAME		L"WPFC"
28 #define IWL_UEFI_UNEB_NAME		L"CnvUefiWlanUNEB"
29 
30 
31 #define IWL_SGOM_MAP_SIZE		339
32 #define IWL_UATS_MAP_SIZE		339
33 
34 #define IWL_UEFI_MIN_WTAS_REVISION	1
35 #define IWL_UEFI_MAX_WTAS_REVISION	2
36 #define IWL_UEFI_SPLC_REVISION		0
37 #define IWL_UEFI_WRDD_REVISION		0
38 #define IWL_UEFI_ECKV_REVISION		0
39 #define IWL_UEFI_WBEM_REVISION		0
40 #define IWL_UEFI_DSM_REVISION		4
41 #define IWL_UEFI_PUNCTURING_REVISION	0
42 #define IWL_UEFI_DSBR_REVISION		1
43 
44 struct pnvm_sku_package {
45 	u8 rev;
46 	u32 total_size;
47 	u8 n_skus;
48 	u32 reserved[2];
49 	u8 data[];
50 } __packed;
51 
52 struct uefi_cnv_wlan_sgom_data {
53 	u8 revision;
54 	u8 offset_map[IWL_SGOM_MAP_SIZE - 1];
55 } __packed;
56 
57 struct uefi_cnv_wlan_uats_data {
58 	u8 revision;
59 	u8 mcc_to_ap_type_map[IWL_UATS_MAP_SIZE - 1];
60 } __packed;
61 
62 /* UNEB's layout is identical to UATS's */
63 #define uefi_cnv_wlan_uneb_data uefi_cnv_wlan_uats_data
64 
65 struct uefi_cnv_common_step_data {
66 	u8 revision;
67 	u8 step_mode;
68 	u8 cnvi_eq_channel;
69 	u8 cnvr_eq_channel;
70 	u8 radio1;
71 	u8 radio2;
72 } __packed;
73 
74 #define UEFI_PPAG_SUB_BANDS_NUM_REV4	11
75 #define UEFI_PPAG_SUB_BANDS_NUM_REV5	12
76 #define UEFI_PPAG_NUM_CHAINS		2
77 
78 #define UEFI_SAR_SUB_BANDS_NUM_REV2	11
79 #define UEFI_SAR_SUB_BANDS_NUM_REV3	12
80 
81 #define UEFI_SAR_MAX_CHAINS_PER_PROFILE	4
82 
83 #define UEFI_GEO_NUM_BANDS_REV3		3
84 #define UEFI_GEO_NUM_BANDS_REV4		4
85 
86 /**
87  * struct uefi_cnv_var_wrds - WRDS table as defined in UEFI
88  *
89  * @revision: the revision of the table
90  * @mode: is WRDS enbaled/disabled
91  * @vals: values for sar profile #1 as an array:
92  *	vals[chain * num_of_subbands + subband] will return the right value.
93  *	num_of_subbands depends on the revision. For revision 3, it is
94  *	%UEFI_SAR_SUB_BANDS_NUM_REV3, for earlier revision, it is
95  *	%UEFI_SAR_SUB_BANDS_NUM_REV2.
96  *	The max number of chains is currently 2
97  */
98 struct uefi_cnv_var_wrds {
99 	u8 revision;
100 	u32 mode;
101 	u8 vals[];
102 } __packed;
103 
104 #define UEFI_SAR_PROFILE_SIZE_REV2			\
105 	(sizeof(u8) * UEFI_SAR_MAX_CHAINS_PER_PROFILE *	\
106 	 UEFI_SAR_SUB_BANDS_NUM_REV2)
107 
108 #define UEFI_SAR_PROFILE_SIZE_REV3			\
109 	(sizeof(u8) * UEFI_SAR_MAX_CHAINS_PER_PROFILE *	\
110 	 UEFI_SAR_SUB_BANDS_NUM_REV3)
111 
112 #define UEFI_SAR_WRDS_TABLE_SIZE_REV2			\
113 	(offsetof(struct uefi_cnv_var_wrds, vals) +	\
114 	 UEFI_SAR_PROFILE_SIZE_REV2)
115 
116 #define UEFI_SAR_WRDS_TABLE_SIZE_REV3			\
117 	(offsetof(struct uefi_cnv_var_wrds, vals) +	\
118 	 UEFI_SAR_PROFILE_SIZE_REV3)
119 
120 /**
121  * struct uefi_cnv_var_ewrd - EWRD table as defined in UEFI
122  * @revision: the revision of the table
123  * @mode: is WRDS enbaled/disabled
124  * @num_profiles: how many additional profiles we have in this table (0-3)
125  * @vals: the additional SAR profiles (#2-#4) as an array of SAR profiles.
126  *	A SAR profile is defined the &struct uefi_cnv_var_wrds::vals. The size
127  *	of each profile depends on the number of subbands which depends on the
128  *	revision. This is explained in &struct uefi_cnv_var_wrds.
129  */
130 struct uefi_cnv_var_ewrd {
131 	u8 revision;
132 	u32 mode;
133 	u32 num_profiles;
134 	u8 vals[];
135 } __packed;
136 
137 #define UEFI_SAR_EWRD_TABLE_SIZE_REV2				\
138 	(offsetof(struct uefi_cnv_var_ewrd, vals) +		\
139 	 UEFI_SAR_PROFILE_SIZE_REV2 * (BIOS_SAR_MAX_PROFILE_NUM - 1))
140 
141 #define UEFI_SAR_EWRD_TABLE_SIZE_REV3				\
142 	(offsetof(struct uefi_cnv_var_ewrd, vals) +		\
143 	 UEFI_SAR_PROFILE_SIZE_REV3 * (BIOS_SAR_MAX_PROFILE_NUM - 1))
144 
145 /**
146  * struct uefi_cnv_var_wgds - WGDS table as defined in UEFI
147  * @revision: the revision of the table
148  * @num_profiles: the number of geo profiles we have in the table.
149  *	The first 3 are mandatory, and can have up to 8.
150  * @vals: a per-profile table of the offsets to add to SAR values. This is an
151  *	array of profiles, each profile is an array of
152  *	&struct iwl_geo_profile_band, one for each subband.
153  *	There are %UEFI_GEO_NUM_BANDS_REV3 or %UEFI_GEO_NUM_BANDS_REV4 subbands
154  *	depending on the revision.
155  */
156 struct uefi_cnv_var_wgds {
157 	u8 revision;
158 	u8 num_profiles;
159 	u8 vals[];
160 } __packed;
161 
162 /* struct iwl_geo_profile_band is 3 bytes-long, but since it is not packed,
163  * we can't use sizeof()
164  */
165 #define UEFI_WGDS_PROFILE_SIZE_REV3 (sizeof(u8) * 3 * UEFI_GEO_NUM_BANDS_REV3)
166 
167 #define UEFI_WGDS_PROFILE_SIZE_REV4 (sizeof(u8) * 3 * UEFI_GEO_NUM_BANDS_REV4)
168 
169 #define UEFI_WGDS_TABLE_SIZE_REV3				\
170 	(offsetof(struct uefi_cnv_var_wgds, vals) +		\
171 	 UEFI_WGDS_PROFILE_SIZE_REV3 * BIOS_GEO_MAX_PROFILE_NUM)
172 
173 #define UEFI_WGDS_TABLE_SIZE_REV4				\
174 	(offsetof(struct uefi_cnv_var_wgds, vals) +		\
175 	 UEFI_WGDS_PROFILE_SIZE_REV4 * BIOS_GEO_MAX_PROFILE_NUM)
176 
177 /**
178  * struct uefi_cnv_var_ppag - PPAG table as defined in UEFI
179  * @revision: the revision of the table
180  * @ppag_modes: values from &enum iwl_ppag_flags
181  * @vals: the PPAG values per chain and band as an array.
182  *	vals[chain * num_of_subbands + subband] will return the right value.
183  *	num_of_subbands depends on the revision. For revision 5, it is
184  *	%UEFI_PPAG_SUB_BANDS_NUM_REV5, for earlier revision it is
185  *	%UEFI_PPAG_SUB_BANDS_NUM_REV4.
186  *	the max number of chains is currently 2
187  */
188 struct uefi_cnv_var_ppag {
189 	u8 revision;
190 	u32 ppag_modes;
191 	s8 vals[];
192 } __packed;
193 
194 #define UEFI_PPAG_DATA_SIZE_V4				\
195 	(offsetof(struct uefi_cnv_var_ppag, vals) +	\
196 	sizeof(s8) * UEFI_PPAG_NUM_CHAINS * UEFI_PPAG_SUB_BANDS_NUM_REV4)
197 #define UEFI_PPAG_DATA_SIZE_V5				\
198 	(offsetof(struct uefi_cnv_var_ppag, vals) +	\
199 	sizeof(s8) * UEFI_PPAG_NUM_CHAINS * UEFI_PPAG_SUB_BANDS_NUM_REV5)
200 
201 /**
202  * struct uefi_cnv_var_wtas - WTAS tabled as defined in UEFI
203  * @revision: the revision of the table
204  * @tas_selection: different options of TAS enablement.
205  * @black_list_size: the number of defined entried in the black list
206  * @black_list: a list of countries that are not allowed to use the TAS feature
207  */
208 struct uefi_cnv_var_wtas {
209 	u8 revision;
210 	u32 tas_selection;
211 	u8 black_list_size;
212 	u16 black_list[IWL_WTAS_BLACK_LIST_MAX];
213 } __packed;
214 
215 /**
216  * struct uefi_cnv_var_splc - SPLC tabled as defined in UEFI
217  * @revision: the revision of the table
218  * @default_pwr_limit: The default maximum power per device
219  */
220 struct uefi_cnv_var_splc {
221 	u8 revision;
222 	u32 default_pwr_limit;
223 } __packed;
224 
225 /**
226  * struct uefi_cnv_var_wrdd - WRDD table as defined in UEFI
227  * @revision: the revision of the table
228  * @mcc: country identifier as defined in ISO/IEC 3166-1 Alpha 2 code
229  */
230 struct uefi_cnv_var_wrdd {
231 	u8 revision;
232 	u32 mcc;
233 } __packed;
234 
235 /**
236  * struct uefi_cnv_var_eckv - ECKV table as defined in UEFI
237  * @revision: the revision of the table
238  * @ext_clock_valid: indicates if external 32KHz clock is valid
239  */
240 struct uefi_cnv_var_eckv {
241 	u8 revision;
242 	u32 ext_clock_valid;
243 } __packed;
244 
245 #define UEFI_MAX_DSM_FUNCS 32
246 
247 /**
248  * struct uefi_cnv_var_general_cfg - DSM-like table as defined in UEFI
249  * @revision: the revision of the table
250  * @functions: payload of the different DSM functions
251  */
252 struct uefi_cnv_var_general_cfg {
253 	u8 revision;
254 	u32 functions[UEFI_MAX_DSM_FUNCS];
255 } __packed;
256 
257 #define IWL_UEFI_WBEM_REV0_MASK (BIT(0) | BIT(1))
258 
259 /**
260  * struct uefi_cnv_wlan_wbem_data - Bandwidth enablement per MCC as defined
261  *	in UEFI
262  * @revision: the revision of the table
263  * @wbem_320mhz_per_mcc: enablement of 320MHz bandwidth per MCC
264  *	bit 0 - if set, 320MHz is enabled for Japan
265  *	bit 1 - if set, 320MHz is enabled for South Korea
266  *	bit 2- 31, Reserved
267  */
268 struct uefi_cnv_wlan_wbem_data {
269 	u8 revision;
270 	u32 wbem_320mhz_per_mcc;
271 } __packed;
272 
273 enum iwl_uefi_cnv_puncturing_flags {
274 	IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK	= BIT(0),
275 	IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK	= BIT(1),
276 };
277 
278 /**
279  * struct uefi_cnv_var_puncturing_data - controlling channel
280  *	puncturing for few countries.
281  * @revision: the revision of the table
282  * @puncturing: enablement of channel puncturing per mcc
283  *	see &enum iwl_uefi_cnv_puncturing_flags.
284  */
285 struct uefi_cnv_var_puncturing_data {
286 	u8 revision;
287 	u32 puncturing;
288 } __packed;
289 
290 /**
291  * struct uefi_cnv_wlan_dsbr_data - BIOS STEP configuration information
292  * @revision: the revision of the table
293  * @config: STEP configuration flags:
294  *	bit 8, switch to URM depending on FW setting
295  *	bit 9, switch to URM
296  *
297  * Platform information for STEP configuration/workarounds.
298  */
299 struct uefi_cnv_wlan_dsbr_data {
300 	u8 revision;
301 	u32 config;
302 } __packed;
303 
304 /**
305  * struct uefi_cnv_wpfc_data - BIOS Wi-Fi PHY filter Configuration
306  * @revision: the revision of the table
307  * @chains: configuration of each of the chains (a-d)
308  *
309  * specific PHY filter configuration
310  */
311 struct uefi_cnv_wpfc_data {
312 	u8 revision;
313 	u32 chains[4];
314 } __packed;
315 
316 /*
317  * This is known to be broken on v4.19 and to work on v5.4.  Until we
318  * figure out why this is the case and how to make it work, simply
319  * disable the feature in old kernels.
320  */
321 #ifdef CONFIG_EFI
322 void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len);
323 u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);
324 int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
325 				const u8 *data, size_t len,
326 				struct iwl_pnvm_image *pnvm_data,
327 				__le32 sku_id[3]);
328 void iwl_uefi_get_step_table(struct iwl_trans *trans);
329 int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
330 				 u32 tlv_len, struct iwl_pnvm_image *pnvm_data);
331 int iwl_uefi_get_wrds_table(struct iwl_fw_runtime *fwrt);
332 int iwl_uefi_get_ewrd_table(struct iwl_fw_runtime *fwrt);
333 int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt);
334 int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt);
335 int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
336 			   struct iwl_tas_data *data);
337 int iwl_uefi_get_pwr_limit(struct iwl_fw_runtime *fwrt,
338 			   u64 *dflt_pwr_limit);
339 int iwl_uefi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
340 int iwl_uefi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk);
341 int iwl_uefi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value);
342 int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
343 		     u32 *value);
344 void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt);
345 void iwl_uefi_get_uats_table(struct iwl_trans *trans,
346 			     struct iwl_fw_runtime *fwrt);
347 void iwl_uefi_get_uneb_table(struct iwl_trans *trans,
348 			     struct iwl_fw_runtime *fwrt);
349 int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt);
350 int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value);
351 int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt);
352 #else /* CONFIG_EFI */
iwl_uefi_get_pnvm(struct iwl_trans * trans,size_t * len)353 static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
354 {
355 	return ERR_PTR(-EOPNOTSUPP);
356 }
357 
358 static inline int
iwl_uefi_reduce_power_parse(struct iwl_trans * trans,const u8 * data,size_t len,struct iwl_pnvm_image * pnvm_data,__le32 sku_id[3])359 iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
360 			    const u8 *data, size_t len,
361 			    struct iwl_pnvm_image *pnvm_data,
362 			    __le32 sku_id[3])
363 {
364 	return -EOPNOTSUPP;
365 }
366 
367 static inline u8 *
iwl_uefi_get_reduced_power(struct iwl_trans * trans,size_t * len)368 iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
369 {
370 	return ERR_PTR(-EOPNOTSUPP);
371 }
372 
iwl_uefi_get_step_table(struct iwl_trans * trans)373 static inline void iwl_uefi_get_step_table(struct iwl_trans *trans)
374 {
375 }
376 
377 static inline int
iwl_uefi_handle_tlv_mem_desc(struct iwl_trans * trans,const u8 * data,u32 tlv_len,struct iwl_pnvm_image * pnvm_data)378 iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
379 			     u32 tlv_len, struct iwl_pnvm_image *pnvm_data)
380 {
381 	return 0;
382 }
383 
iwl_uefi_get_wrds_table(struct iwl_fw_runtime * fwrt)384 static inline int iwl_uefi_get_wrds_table(struct iwl_fw_runtime *fwrt)
385 {
386 	return -ENOENT;
387 }
388 
iwl_uefi_get_ewrd_table(struct iwl_fw_runtime * fwrt)389 static inline int iwl_uefi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
390 {
391 	return -ENOENT;
392 }
393 
iwl_uefi_get_wgds_table(struct iwl_fw_runtime * fwrt)394 static inline int iwl_uefi_get_wgds_table(struct iwl_fw_runtime *fwrt)
395 {
396 	return -ENOENT;
397 }
398 
iwl_uefi_get_ppag_table(struct iwl_fw_runtime * fwrt)399 static inline int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt)
400 {
401 	return -ENOENT;
402 }
403 
iwl_uefi_get_tas_table(struct iwl_fw_runtime * fwrt,struct iwl_tas_data * data)404 static inline int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
405 					 struct iwl_tas_data *data)
406 {
407 	return -ENOENT;
408 }
409 
iwl_uefi_get_pwr_limit(struct iwl_fw_runtime * fwrt,u64 * dflt_pwr_limit)410 static inline int iwl_uefi_get_pwr_limit(struct iwl_fw_runtime *fwrt,
411 					 u64 *dflt_pwr_limit)
412 {
413 	*dflt_pwr_limit = 0;
414 	return 0;
415 }
416 
iwl_uefi_get_mcc(struct iwl_fw_runtime * fwrt,char * mcc)417 static inline int iwl_uefi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc)
418 {
419 	return -ENOENT;
420 }
421 
iwl_uefi_get_eckv(struct iwl_fw_runtime * fwrt,u32 * extl_clk)422 static inline int iwl_uefi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk)
423 {
424 	return -ENOENT;
425 }
426 
iwl_uefi_get_wbem(struct iwl_fw_runtime * fwrt,u32 * value)427 static inline int iwl_uefi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value)
428 {
429 	return -ENOENT;
430 }
431 
iwl_uefi_get_dsm(struct iwl_fw_runtime * fwrt,enum iwl_dsm_funcs func,u32 * value)432 static inline int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt,
433 				   enum iwl_dsm_funcs func, u32 *value)
434 {
435 	return -ENOENT;
436 }
437 
438 static inline
iwl_uefi_get_sgom_table(struct iwl_trans * trans,struct iwl_fw_runtime * fwrt)439 void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt)
440 {
441 }
442 
443 static inline void
iwl_uefi_get_uats_table(struct iwl_trans * trans,struct iwl_fw_runtime * fwrt)444 iwl_uefi_get_uats_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt)
445 {
446 }
447 
448 static inline void
iwl_uefi_get_uneb_table(struct iwl_trans * trans,struct iwl_fw_runtime * fwrt)449 iwl_uefi_get_uneb_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt)
450 {
451 }
452 
453 static inline
iwl_uefi_get_puncturing(struct iwl_fw_runtime * fwrt)454 int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt)
455 {
456 	return 0;
457 }
458 
459 static inline
iwl_uefi_get_dsbr(struct iwl_fw_runtime * fwrt,u32 * value)460 int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value)
461 {
462 	return -ENOENT;
463 }
464 
iwl_uefi_get_phy_filters(struct iwl_fw_runtime * fwrt)465 static inline int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt)
466 {
467 	return -ENOENT;
468 }
469 #endif /* CONFIG_EFI */
470 #endif /* __iwl_fw_uefi__ */
471