Linux Audio

Check our new training course

Loading...
v6.9.4
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2/*
  3 * Copyright (C) 2023 Intel Corporation
  4 */
  5#include <linux/dmi.h>
  6#include "iwl-drv.h"
  7#include "iwl-debug.h"
  8#include "regulatory.h"
  9#include "fw/runtime.h"
 10#include "fw/uefi.h"
 11
 12#define GET_BIOS_TABLE(__name, ...)					\
 13do {									\
 14	int ret = -ENOENT;						\
 15	if (fwrt->uefi_tables_lock_status > UEFI_WIFI_GUID_UNLOCKED)	\
 16		ret = iwl_uefi_get_ ## __name(__VA_ARGS__);		\
 17	if (ret < 0)							\
 18		ret = iwl_acpi_get_ ## __name(__VA_ARGS__);		\
 19	return ret;							\
 20} while (0)
 21
 22#define IWL_BIOS_TABLE_LOADER(__name)					\
 23int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt)		\
 24{GET_BIOS_TABLE(__name, fwrt); }					\
 25IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)
 26
 27#define IWL_BIOS_TABLE_LOADER_DATA(__name, data_type)			\
 28int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt,		\
 29			    data_type * data)				\
 30{GET_BIOS_TABLE(__name, fwrt, data); }					\
 31IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)
 32
 33IWL_BIOS_TABLE_LOADER(wrds_table);
 34IWL_BIOS_TABLE_LOADER(ewrd_table);
 35IWL_BIOS_TABLE_LOADER(wgds_table);
 36IWL_BIOS_TABLE_LOADER(ppag_table);
 37IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data);
 38IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64);
 39IWL_BIOS_TABLE_LOADER_DATA(mcc, char);
 40IWL_BIOS_TABLE_LOADER_DATA(eckv, u32);
 
 41
 42
 43static const struct dmi_system_id dmi_ppag_approved_list[] = {
 44	{ .ident = "HP",
 45	  .matches = {
 46			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 47		},
 48	},
 49	{ .ident = "SAMSUNG",
 50	  .matches = {
 51			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
 52		},
 53	},
 54	{ .ident = "MSFT",
 55	  .matches = {
 56			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 57		},
 58	},
 59	{ .ident = "ASUS",
 60	  .matches = {
 61			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 62		},
 63	},
 64	{ .ident = "GOOGLE-HP",
 65	  .matches = {
 66			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 67			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
 68		},
 69	},
 70	{ .ident = "GOOGLE-ASUS",
 71	  .matches = {
 72			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 73			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
 74		},
 75	},
 76	{ .ident = "GOOGLE-SAMSUNG",
 77	  .matches = {
 78			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 79			DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
 80		},
 81	},
 82	{ .ident = "DELL",
 83	  .matches = {
 84			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 85		},
 86	},
 87	{ .ident = "DELL",
 88	  .matches = {
 89			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
 90		},
 91	},
 92	{ .ident = "RAZER",
 93	  .matches = {
 94			DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
 95		},
 96	},
 97	{ .ident = "Honor",
 98	  .matches = {
 99			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
100		},
101	},
102	{}
103};
104
105static const struct dmi_system_id dmi_tas_approved_list[] = {
106	{ .ident = "HP",
107	  .matches = {
108			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
109		},
110	},
111	{ .ident = "SAMSUNG",
112	  .matches = {
113			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
114		},
115	},
116		{ .ident = "LENOVO",
117	  .matches = {
118			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
119		},
120	},
121	{ .ident = "DELL",
122	  .matches = {
123			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
124		},
125	},
126	{ .ident = "MSFT",
127	  .matches = {
128			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
129		},
130	},
131	{ .ident = "Acer",
132	  .matches = {
133			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
134		},
135	},
136	{ .ident = "ASUS",
137	  .matches = {
138			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
139		},
140	},
141	{ .ident = "GOOGLE-HP",
142	  .matches = {
143			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
144			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
145		},
146	},
147	{ .ident = "MSI",
148	  .matches = {
149			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
150		},
151	},
152	{ .ident = "Honor",
153	  .matches = {
154			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
155		},
156	},
157	/* keep last */
158	{}
159};
160
161bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
162{
163	/*
164	 * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on
165	 * earlier firmware versions.  Unfortunately, we don't have a
166	 * TLV API flag to rely on, so rely on the major version which
167	 * is in the first byte of ucode_ver.  This was implemented
168	 * initially on version 38 and then backported to 17.  It was
169	 * also backported to 29, but only for 7265D devices.  The
170	 * intention was to have it in 36 as well, but not all 8000
171	 * family got this feature enabled.  The 8000 family is the
172	 * only one using version 36, so skip this version entirely.
173	 */
174	return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 ||
175		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 &&
176		 fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) ||
177		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
178		 ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
179		  CSR_HW_REV_TYPE_7265D));
180}
181IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
182
183int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
184			   struct iwl_per_chain_offset *table,
185			   u32 n_bands, u32 n_profiles)
186{
187	int i, j;
188
189	if (!fwrt->geo_enabled)
190		return -ENODATA;
191
192	if (!iwl_sar_geo_support(fwrt))
193		return -EOPNOTSUPP;
194
195	for (i = 0; i < n_profiles; i++) {
196		for (j = 0; j < n_bands; j++) {
197			struct iwl_per_chain_offset *chain =
198				&table[i * n_bands + j];
199
200			chain->max_tx_power =
201				cpu_to_le16(fwrt->geo_profiles[i].bands[j].max);
202			chain->chain_a =
203				fwrt->geo_profiles[i].bands[j].chains[0];
204			chain->chain_b =
205				fwrt->geo_profiles[i].bands[j].chains[1];
206			IWL_DEBUG_RADIO(fwrt,
207					"SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
208					i, j,
209					fwrt->geo_profiles[i].bands[j].chains[0],
210					fwrt->geo_profiles[i].bands[j].chains[1],
211					fwrt->geo_profiles[i].bands[j].max);
212		}
213	}
214
215	return 0;
216}
217IWL_EXPORT_SYMBOL(iwl_sar_geo_fill_table);
218
219static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
220			      __le16 *per_chain, u32 n_subbands,
221			      int prof_a, int prof_b)
222{
223	int profs[BIOS_SAR_NUM_CHAINS] = { prof_a, prof_b };
224	int i, j;
225
226	for (i = 0; i < BIOS_SAR_NUM_CHAINS; i++) {
227		struct iwl_sar_profile *prof;
228
229		/* don't allow SAR to be disabled (profile 0 means disable) */
230		if (profs[i] == 0)
231			return -EPERM;
232
233		/* we are off by one, so allow up to BIOS_SAR_MAX_PROFILE_NUM */
234		if (profs[i] > BIOS_SAR_MAX_PROFILE_NUM)
235			return -EINVAL;
236
237		/* profiles go from 1 to 4, so decrement to access the array */
238		prof = &fwrt->sar_profiles[profs[i] - 1];
239
240		/* if the profile is disabled, do nothing */
241		if (!prof->enabled) {
242			IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n",
243					profs[i]);
244			/*
245			 * if one of the profiles is disabled, we
246			 * ignore all of them and return 1 to
247			 * differentiate disabled from other failures.
248			 */
249			return 1;
250		}
251
252		IWL_DEBUG_INFO(fwrt,
253			       "SAR EWRD: chain %d profile index %d\n",
254			       i, profs[i]);
255		IWL_DEBUG_RADIO(fwrt, "  Chain[%d]:\n", i);
256		for (j = 0; j < n_subbands; j++) {
257			per_chain[i * n_subbands + j] =
258				cpu_to_le16(prof->chains[i].subbands[j]);
259			IWL_DEBUG_RADIO(fwrt, "    Band[%d] = %d * .125dBm\n",
260					j, prof->chains[i].subbands[j]);
261		}
262	}
263
264	return 0;
265}
266
267int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
268			 __le16 *per_chain, u32 n_tables, u32 n_subbands,
269			 int prof_a, int prof_b)
270{
271	int i, ret = 0;
272
273	for (i = 0; i < n_tables; i++) {
274		ret = iwl_sar_fill_table(fwrt,
275			&per_chain[i * n_subbands * BIOS_SAR_NUM_CHAINS],
276			n_subbands, prof_a, prof_b);
277		if (ret)
278			break;
279	}
280
281	return ret;
282}
283IWL_EXPORT_SYMBOL(iwl_sar_fill_profile);
284
285static bool iwl_ppag_value_valid(struct iwl_fw_runtime *fwrt, int chain,
286				 int subband)
287{
288	s8 ppag_val = fwrt->ppag_chains[chain].subbands[subband];
289
290	if ((subband == 0 &&
291	     (ppag_val > IWL_PPAG_MAX_LB || ppag_val < IWL_PPAG_MIN_LB)) ||
292	    (subband != 0 &&
293	     (ppag_val > IWL_PPAG_MAX_HB || ppag_val < IWL_PPAG_MIN_HB))) {
294		IWL_DEBUG_RADIO(fwrt, "Invalid PPAG value: %d\n", ppag_val);
295		return false;
296	}
297	return true;
298}
299
300int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
301			union iwl_ppag_table_cmd *cmd, int *cmd_size)
302{
303	u8 cmd_ver;
304	int i, j, num_sub_bands;
305	s8 *gain;
306	bool send_ppag_always;
307
308	/* many firmware images for JF lie about this */
309	if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
310	    CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
311		return -EOPNOTSUPP;
312
313	if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
314		IWL_DEBUG_RADIO(fwrt,
315				"PPAG capability not supported by FW, command not sent.\n");
316		return -EINVAL;
317	}
318
319	cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
320					WIDE_ID(PHY_OPS_GROUP,
321						PER_PLATFORM_ANT_GAIN_CMD), 1);
322	/*
323	 * Starting from ver 4, driver needs to send the PPAG CMD regardless
324	 * if PPAG is enabled/disabled or valid/invalid.
325	 */
326	send_ppag_always = cmd_ver > 3;
327
328	/* Don't send PPAG if it is disabled */
329	if (!send_ppag_always && !fwrt->ppag_flags) {
330		IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n");
331		return -EINVAL;
332	}
333
334	/* The 'flags' field is the same in v1 and in v2 so we can just
335	 * use v1 to access it.
336	 */
337	cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);
338
339	IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);
340	if (cmd_ver == 1) {
341		num_sub_bands = IWL_NUM_SUB_BANDS_V1;
342		gain = cmd->v1.gain[0];
343		*cmd_size = sizeof(cmd->v1);
344		if (fwrt->ppag_ver >= 1) {
345			/* in this case FW supports revision 0 */
346			IWL_DEBUG_RADIO(fwrt,
347					"PPAG table rev is %d, send truncated table\n",
348					fwrt->ppag_ver);
349		}
350	} else if (cmd_ver >= 2 && cmd_ver <= 5) {
351		num_sub_bands = IWL_NUM_SUB_BANDS_V2;
352		gain = cmd->v2.gain[0];
353		*cmd_size = sizeof(cmd->v2);
354		if (fwrt->ppag_ver == 0) {
355			/* in this case FW supports revisions 1,2 or 3 */
356			IWL_DEBUG_RADIO(fwrt,
357					"PPAG table rev is 0, send padded table\n");
358		}
359	} else {
360		IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");
361		return -EINVAL;
362	}
363
364	/* ppag mode */
365	IWL_DEBUG_RADIO(fwrt,
366			"PPAG MODE bits were read from bios: %d\n",
367			le32_to_cpu(cmd->v1.flags));
368
369	if (cmd_ver == 5)
370		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);
371	else if (cmd_ver < 5)
372		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK);
373
374	if ((cmd_ver == 1 &&
375	     !fw_has_capa(&fwrt->fw->ucode_capa,
376			  IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
377	    (cmd_ver == 2 && fwrt->ppag_ver >= 2)) {
378		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
379		IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
380	} else {
381		IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");
382	}
383
384	IWL_DEBUG_RADIO(fwrt,
385			"PPAG MODE bits going to be sent: %d\n",
386			le32_to_cpu(cmd->v1.flags));
387
388	for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
389		for (j = 0; j < num_sub_bands; j++) {
390			if (!send_ppag_always &&
391			    !iwl_ppag_value_valid(fwrt, i, j))
392				return -EINVAL;
393
394			gain[i * num_sub_bands + j] =
395				fwrt->ppag_chains[i].subbands[j];
396			IWL_DEBUG_RADIO(fwrt,
397					"PPAG table: chain[%d] band[%d]: gain = %d\n",
398					i, j, gain[i * num_sub_bands + j]);
399		}
400	}
401
402	return 0;
403}
404IWL_EXPORT_SYMBOL(iwl_fill_ppag_table);
405
406bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt)
407{
408	if (!dmi_check_system(dmi_ppag_approved_list)) {
409		IWL_DEBUG_RADIO(fwrt,
410				"System vendor '%s' is not in the approved list, disabling PPAG.\n",
411				dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>");
412		fwrt->ppag_flags = 0;
413		return false;
414	}
415
416	return true;
417}
418IWL_EXPORT_SYMBOL(iwl_is_ppag_approved);
419
420bool iwl_is_tas_approved(void)
421{
422	return dmi_check_system(dmi_tas_approved_list);
423}
424IWL_EXPORT_SYMBOL(iwl_is_tas_approved);
425
426int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
427			    struct iwl_tas_data *tas_data,
428			    const u32 tas_selection)
429{
430	u8 override_iec = u32_get_bits(tas_selection,
431				       IWL_WTAS_OVERRIDE_IEC_MSK);
432	u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK);
433	u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK);
434	int enabled = tas_selection & IWL_WTAS_ENABLED_MSK;
435
436	IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
437			tas_selection);
438
439	tas_data->usa_tas_uhb_allowed = usa_tas_uhb;
440	tas_data->override_tas_iec = override_iec;
441	tas_data->enable_tas_iec = enabled_iec;
442
443	return enabled;
444}
445
446__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
447{
448	int ret;
449	u32 val;
450	__le32 config_bitmap = 0;
451
452	switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) {
453	case IWL_CFG_RF_TYPE_HR1:
454	case IWL_CFG_RF_TYPE_HR2:
455	case IWL_CFG_RF_TYPE_JF1:
456	case IWL_CFG_RF_TYPE_JF2:
457		ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2,
458				       &val);
459
460		if (!ret && val == DSM_VALUE_INDONESIA_ENABLE)
461			config_bitmap |=
462			    cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK);
463		break;
464	default:
465		break;
466	}
467
468	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val);
469	if (!ret) {
470		if (val == DSM_VALUE_SRD_PASSIVE)
471			config_bitmap |=
472				cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK);
473		else if (val == DSM_VALUE_SRD_DISABLE)
474			config_bitmap |=
475				cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
476	}
477
478	if (fw_has_capa(&fwrt->fw->ucode_capa,
479			IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) {
480		ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG,
481				       &val);
482		/*
483		 * China 2022 enable if the BIOS object does not exist or
484		 * if it is enabled in BIOS.
485		 */
486		if (ret < 0 || val & DSM_MASK_CHINA_22_REG)
487			config_bitmap |=
488				cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK);
489	}
490
491	return config_bitmap;
492}
493IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
495int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
496		     u32 *value)
497{
498	GET_BIOS_TABLE(dsm, fwrt, func, value);
499}
500IWL_EXPORT_SYMBOL(iwl_bios_get_dsm);
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2/*
  3 * Copyright (C) 2023 Intel Corporation
  4 */
  5#include <linux/dmi.h>
  6#include "iwl-drv.h"
  7#include "iwl-debug.h"
  8#include "regulatory.h"
  9#include "fw/runtime.h"
 10#include "fw/uefi.h"
 11
 12#define GET_BIOS_TABLE(__name, ...)					\
 13do {									\
 14	int ret = -ENOENT;						\
 15	if (fwrt->uefi_tables_lock_status > UEFI_WIFI_GUID_UNLOCKED)	\
 16		ret = iwl_uefi_get_ ## __name(__VA_ARGS__);		\
 17	if (ret < 0)							\
 18		ret = iwl_acpi_get_ ## __name(__VA_ARGS__);		\
 19	return ret;							\
 20} while (0)
 21
 22#define IWL_BIOS_TABLE_LOADER(__name)					\
 23int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt)		\
 24{GET_BIOS_TABLE(__name, fwrt); }					\
 25IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)
 26
 27#define IWL_BIOS_TABLE_LOADER_DATA(__name, data_type)			\
 28int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt,		\
 29			    data_type * data)				\
 30{GET_BIOS_TABLE(__name, fwrt, data); }					\
 31IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)
 32
 33IWL_BIOS_TABLE_LOADER(wrds_table);
 34IWL_BIOS_TABLE_LOADER(ewrd_table);
 35IWL_BIOS_TABLE_LOADER(wgds_table);
 36IWL_BIOS_TABLE_LOADER(ppag_table);
 37IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data);
 38IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64);
 39IWL_BIOS_TABLE_LOADER_DATA(mcc, char);
 40IWL_BIOS_TABLE_LOADER_DATA(eckv, u32);
 41IWL_BIOS_TABLE_LOADER_DATA(wbem, u32);
 42
 43
 44static const struct dmi_system_id dmi_ppag_approved_list[] = {
 45	{ .ident = "HP",
 46	  .matches = {
 47			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
 48		},
 49	},
 50	{ .ident = "SAMSUNG",
 51	  .matches = {
 52			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
 53		},
 54	},
 55	{ .ident = "MSFT",
 56	  .matches = {
 57			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 58		},
 59	},
 60	{ .ident = "ASUS",
 61	  .matches = {
 62			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 63		},
 64	},
 65	{ .ident = "GOOGLE-HP",
 66	  .matches = {
 67			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 68			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
 69		},
 70	},
 71	{ .ident = "GOOGLE-ASUS",
 72	  .matches = {
 73			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 74			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
 75		},
 76	},
 77	{ .ident = "GOOGLE-SAMSUNG",
 78	  .matches = {
 79			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 80			DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
 81		},
 82	},
 83	{ .ident = "DELL",
 84	  .matches = {
 85			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 86		},
 87	},
 88	{ .ident = "DELL",
 89	  .matches = {
 90			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
 91		},
 92	},
 93	{ .ident = "RAZER",
 94	  .matches = {
 95			DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
 96		},
 97	},
 98	{ .ident = "Honor",
 99	  .matches = {
100			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
101		},
102	},
103	{}
104};
105
106static const struct dmi_system_id dmi_tas_approved_list[] = {
107	{ .ident = "HP",
108	  .matches = {
109			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
110		},
111	},
112	{ .ident = "SAMSUNG",
113	  .matches = {
114			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
115		},
116	},
117		{ .ident = "LENOVO",
118	  .matches = {
119			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
120		},
121	},
122	{ .ident = "DELL",
123	  .matches = {
124			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
125		},
126	},
127	{ .ident = "MSFT",
128	  .matches = {
129			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
130		},
131	},
132	{ .ident = "Acer",
133	  .matches = {
134			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
135		},
136	},
137	{ .ident = "ASUS",
138	  .matches = {
139			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
140		},
141	},
142	{ .ident = "GOOGLE-HP",
143	  .matches = {
144			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
145			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
146		},
147	},
148	{ .ident = "MSI",
149	  .matches = {
150			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
151		},
152	},
153	{ .ident = "Honor",
154	  .matches = {
155			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
156		},
157	},
158	/* keep last */
159	{}
160};
161
162bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
163{
164	/*
165	 * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on
166	 * earlier firmware versions.  Unfortunately, we don't have a
167	 * TLV API flag to rely on, so rely on the major version which
168	 * is in the first byte of ucode_ver.  This was implemented
169	 * initially on version 38 and then backported to 17.  It was
170	 * also backported to 29, but only for 7265D devices.  The
171	 * intention was to have it in 36 as well, but not all 8000
172	 * family got this feature enabled.  The 8000 family is the
173	 * only one using version 36, so skip this version entirely.
174	 */
175	return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 ||
176		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 &&
177		 fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) ||
178		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
179		 ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
180		  CSR_HW_REV_TYPE_7265D));
181}
182IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
183
184int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
185			   struct iwl_per_chain_offset *table,
186			   u32 n_bands, u32 n_profiles)
187{
188	int i, j;
189
190	if (!fwrt->geo_enabled)
191		return -ENODATA;
192
193	if (!iwl_sar_geo_support(fwrt))
194		return -EOPNOTSUPP;
195
196	for (i = 0; i < n_profiles; i++) {
197		for (j = 0; j < n_bands; j++) {
198			struct iwl_per_chain_offset *chain =
199				&table[i * n_bands + j];
200
201			chain->max_tx_power =
202				cpu_to_le16(fwrt->geo_profiles[i].bands[j].max);
203			chain->chain_a =
204				fwrt->geo_profiles[i].bands[j].chains[0];
205			chain->chain_b =
206				fwrt->geo_profiles[i].bands[j].chains[1];
207			IWL_DEBUG_RADIO(fwrt,
208					"SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
209					i, j,
210					fwrt->geo_profiles[i].bands[j].chains[0],
211					fwrt->geo_profiles[i].bands[j].chains[1],
212					fwrt->geo_profiles[i].bands[j].max);
213		}
214	}
215
216	return 0;
217}
218IWL_EXPORT_SYMBOL(iwl_sar_geo_fill_table);
219
220static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
221			      __le16 *per_chain, u32 n_subbands,
222			      int prof_a, int prof_b)
223{
224	int profs[BIOS_SAR_NUM_CHAINS] = { prof_a, prof_b };
225	int i, j;
226
227	for (i = 0; i < BIOS_SAR_NUM_CHAINS; i++) {
228		struct iwl_sar_profile *prof;
229
230		/* don't allow SAR to be disabled (profile 0 means disable) */
231		if (profs[i] == 0)
232			return -EPERM;
233
234		/* we are off by one, so allow up to BIOS_SAR_MAX_PROFILE_NUM */
235		if (profs[i] > BIOS_SAR_MAX_PROFILE_NUM)
236			return -EINVAL;
237
238		/* profiles go from 1 to 4, so decrement to access the array */
239		prof = &fwrt->sar_profiles[profs[i] - 1];
240
241		/* if the profile is disabled, do nothing */
242		if (!prof->enabled) {
243			IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n",
244					profs[i]);
245			/*
246			 * if one of the profiles is disabled, we
247			 * ignore all of them and return 1 to
248			 * differentiate disabled from other failures.
249			 */
250			return 1;
251		}
252
253		IWL_DEBUG_INFO(fwrt,
254			       "SAR EWRD: chain %d profile index %d\n",
255			       i, profs[i]);
256		IWL_DEBUG_RADIO(fwrt, "  Chain[%d]:\n", i);
257		for (j = 0; j < n_subbands; j++) {
258			per_chain[i * n_subbands + j] =
259				cpu_to_le16(prof->chains[i].subbands[j]);
260			IWL_DEBUG_RADIO(fwrt, "    Band[%d] = %d * .125dBm\n",
261					j, prof->chains[i].subbands[j]);
262		}
263	}
264
265	return 0;
266}
267
268int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
269			 __le16 *per_chain, u32 n_tables, u32 n_subbands,
270			 int prof_a, int prof_b)
271{
272	int i, ret = 0;
273
274	for (i = 0; i < n_tables; i++) {
275		ret = iwl_sar_fill_table(fwrt,
276			&per_chain[i * n_subbands * BIOS_SAR_NUM_CHAINS],
277			n_subbands, prof_a, prof_b);
278		if (ret)
279			break;
280	}
281
282	return ret;
283}
284IWL_EXPORT_SYMBOL(iwl_sar_fill_profile);
285
286static bool iwl_ppag_value_valid(struct iwl_fw_runtime *fwrt, int chain,
287				 int subband)
288{
289	s8 ppag_val = fwrt->ppag_chains[chain].subbands[subband];
290
291	if ((subband == 0 &&
292	     (ppag_val > IWL_PPAG_MAX_LB || ppag_val < IWL_PPAG_MIN_LB)) ||
293	    (subband != 0 &&
294	     (ppag_val > IWL_PPAG_MAX_HB || ppag_val < IWL_PPAG_MIN_HB))) {
295		IWL_DEBUG_RADIO(fwrt, "Invalid PPAG value: %d\n", ppag_val);
296		return false;
297	}
298	return true;
299}
300
301int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
302			union iwl_ppag_table_cmd *cmd, int *cmd_size)
303{
304	u8 cmd_ver;
305	int i, j, num_sub_bands;
306	s8 *gain;
307	bool send_ppag_always;
308
309	/* many firmware images for JF lie about this */
310	if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
311	    CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
312		return -EOPNOTSUPP;
313
314	if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
315		IWL_DEBUG_RADIO(fwrt,
316				"PPAG capability not supported by FW, command not sent.\n");
317		return -EINVAL;
318	}
319
320	cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
321					WIDE_ID(PHY_OPS_GROUP,
322						PER_PLATFORM_ANT_GAIN_CMD), 1);
323	/*
324	 * Starting from ver 4, driver needs to send the PPAG CMD regardless
325	 * if PPAG is enabled/disabled or valid/invalid.
326	 */
327	send_ppag_always = cmd_ver > 3;
328
329	/* Don't send PPAG if it is disabled */
330	if (!send_ppag_always && !fwrt->ppag_flags) {
331		IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n");
332		return -EINVAL;
333	}
334
335	/* The 'flags' field is the same in v1 and in v2 so we can just
336	 * use v1 to access it.
337	 */
338	cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);
339
340	IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);
341	if (cmd_ver == 1) {
342		num_sub_bands = IWL_NUM_SUB_BANDS_V1;
343		gain = cmd->v1.gain[0];
344		*cmd_size = sizeof(cmd->v1);
345		if (fwrt->ppag_ver >= 1) {
346			/* in this case FW supports revision 0 */
347			IWL_DEBUG_RADIO(fwrt,
348					"PPAG table rev is %d, send truncated table\n",
349					fwrt->ppag_ver);
350		}
351	} else if (cmd_ver >= 2 && cmd_ver <= 6) {
352		num_sub_bands = IWL_NUM_SUB_BANDS_V2;
353		gain = cmd->v2.gain[0];
354		*cmd_size = sizeof(cmd->v2);
355		if (fwrt->ppag_ver == 0) {
356			/* in this case FW supports revisions 1,2 or 3 */
357			IWL_DEBUG_RADIO(fwrt,
358					"PPAG table rev is 0, send padded table\n");
359		}
360	} else {
361		IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");
362		return -EINVAL;
363	}
364
365	/* ppag mode */
366	IWL_DEBUG_RADIO(fwrt,
367			"PPAG MODE bits were read from bios: %d\n",
368			le32_to_cpu(cmd->v1.flags));
369
370	if (cmd_ver == 5)
371		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);
372	else if (cmd_ver < 5)
373		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK);
374
375	if ((cmd_ver == 1 &&
376	     !fw_has_capa(&fwrt->fw->ucode_capa,
377			  IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
378	    (cmd_ver == 2 && fwrt->ppag_ver >= 2)) {
379		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
380		IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
381	} else {
382		IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");
383	}
384
385	IWL_DEBUG_RADIO(fwrt,
386			"PPAG MODE bits going to be sent: %d\n",
387			le32_to_cpu(cmd->v1.flags));
388
389	for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
390		for (j = 0; j < num_sub_bands; j++) {
391			if (!send_ppag_always &&
392			    !iwl_ppag_value_valid(fwrt, i, j))
393				return -EINVAL;
394
395			gain[i * num_sub_bands + j] =
396				fwrt->ppag_chains[i].subbands[j];
397			IWL_DEBUG_RADIO(fwrt,
398					"PPAG table: chain[%d] band[%d]: gain = %d\n",
399					i, j, gain[i * num_sub_bands + j]);
400		}
401	}
402
403	return 0;
404}
405IWL_EXPORT_SYMBOL(iwl_fill_ppag_table);
406
407bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt)
408{
409	if (!dmi_check_system(dmi_ppag_approved_list)) {
410		IWL_DEBUG_RADIO(fwrt,
411				"System vendor '%s' is not in the approved list, disabling PPAG.\n",
412				dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>");
413		fwrt->ppag_flags = 0;
414		return false;
415	}
416
417	return true;
418}
419IWL_EXPORT_SYMBOL(iwl_is_ppag_approved);
420
421bool iwl_is_tas_approved(void)
422{
423	return dmi_check_system(dmi_tas_approved_list);
424}
425IWL_EXPORT_SYMBOL(iwl_is_tas_approved);
426
427int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
428			    struct iwl_tas_data *tas_data,
429			    const u32 tas_selection)
430{
431	u8 override_iec = u32_get_bits(tas_selection,
432				       IWL_WTAS_OVERRIDE_IEC_MSK);
433	u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK);
434	u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK);
435	int enabled = tas_selection & IWL_WTAS_ENABLED_MSK;
436
437	IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
438			tas_selection);
439
440	tas_data->usa_tas_uhb_allowed = usa_tas_uhb;
441	tas_data->override_tas_iec = override_iec;
442	tas_data->enable_tas_iec = enabled_iec;
443
444	return enabled;
445}
446
447static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
448{
449	int ret;
450	u32 val;
451	__le32 config_bitmap = 0;
452
453	switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) {
454	case IWL_CFG_RF_TYPE_HR1:
455	case IWL_CFG_RF_TYPE_HR2:
456	case IWL_CFG_RF_TYPE_JF1:
457	case IWL_CFG_RF_TYPE_JF2:
458		ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2,
459				       &val);
460
461		if (!ret && val == DSM_VALUE_INDONESIA_ENABLE)
462			config_bitmap |=
463			    cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK);
464		break;
465	default:
466		break;
467	}
468
469	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val);
470	if (!ret) {
471		if (val == DSM_VALUE_SRD_PASSIVE)
472			config_bitmap |=
473				cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK);
474		else if (val == DSM_VALUE_SRD_DISABLE)
475			config_bitmap |=
476				cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
477	}
478
479	if (fw_has_capa(&fwrt->fw->ucode_capa,
480			IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) {
481		ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG,
482				       &val);
483		/*
484		 * China 2022 enable if the BIOS object does not exist or
485		 * if it is enabled in BIOS.
486		 */
487		if (ret < 0 || val & DSM_MASK_CHINA_22_REG)
488			config_bitmap |=
489				cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK);
490	}
491
492	return config_bitmap;
493}
494
495static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver)
496{
497	size_t cmd_size;
498
499	switch (cmd_ver) {
500	case 12:
501	case 11:
502		cmd_size = sizeof(struct iwl_lari_config_change_cmd);
503		break;
504	case 10:
505		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v10);
506		break;
507	case 9:
508	case 8:
509	case 7:
510		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7);
511		break;
512	case 6:
513		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6);
514		break;
515	case 5:
516		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5);
517		break;
518	case 4:
519		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4);
520		break;
521	case 3:
522		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3);
523		break;
524	case 2:
525		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v2);
526		break;
527	default:
528		cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1);
529		break;
530	}
531	return cmd_size;
532}
533
534int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
535			 struct iwl_lari_config_change_cmd *cmd,
536			 size_t *cmd_size)
537{
538	int ret;
539	u32 value;
540	u8 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
541					   WIDE_ID(REGULATORY_AND_NVM_GROUP,
542						   LARI_CONFIG_CHANGE), 1);
543
544	memset(cmd, 0, sizeof(*cmd));
545	*cmd_size = iwl_get_lari_config_cmd_size(cmd_ver);
546
547	cmd->config_bitmap = iwl_get_lari_config_bitmap(fwrt);
548
549	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value);
550	if (!ret)
551		cmd->oem_11ax_allow_bitmap = cpu_to_le32(value);
552
553	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
554	if (!ret) {
555		if (cmd_ver < 9)
556			value &= DSM_UNII4_ALLOW_BITMAP_CMD_V8;
557		else
558			value &= DSM_UNII4_ALLOW_BITMAP;
559
560		cmd->oem_unii4_allow_bitmap = cpu_to_le32(value);
561	}
562
563	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
564	if (!ret) {
565		if (cmd_ver < 8)
566			value &= ~ACTIVATE_5G2_IN_WW_MASK;
567		if (cmd_ver < 12)
568			value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11;
569
570		cmd->chan_state_active_bitmap = cpu_to_le32(value);
571	}
572
573	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value);
574	if (!ret)
575		cmd->oem_uhb_allow_bitmap = cpu_to_le32(value);
576
577	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value);
578	if (!ret)
579		cmd->force_disable_channels_bitmap = cpu_to_le32(value);
580
581	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
582			       &value);
583	if (!ret)
584		cmd->edt_bitmap = cpu_to_le32(value);
585
586	ret = iwl_bios_get_wbem(fwrt, &value);
587	if (!ret)
588		cmd->oem_320mhz_allow_bitmap = cpu_to_le32(value);
589
590	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value);
591	if (!ret)
592		cmd->oem_11be_allow_bitmap = cpu_to_le32(value);
593
594	if (cmd->config_bitmap ||
595	    cmd->oem_uhb_allow_bitmap ||
596	    cmd->oem_11ax_allow_bitmap ||
597	    cmd->oem_unii4_allow_bitmap ||
598	    cmd->chan_state_active_bitmap ||
599	    cmd->force_disable_channels_bitmap ||
600	    cmd->edt_bitmap ||
601	    cmd->oem_320mhz_allow_bitmap ||
602	    cmd->oem_11be_allow_bitmap) {
603		IWL_DEBUG_RADIO(fwrt,
604				"sending LARI_CONFIG_CHANGE, config_bitmap=0x%x, oem_11ax_allow_bitmap=0x%x\n",
605				le32_to_cpu(cmd->config_bitmap),
606				le32_to_cpu(cmd->oem_11ax_allow_bitmap));
607		IWL_DEBUG_RADIO(fwrt,
608				"sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, chan_state_active_bitmap=0x%x, cmd_ver=%d\n",
609				le32_to_cpu(cmd->oem_unii4_allow_bitmap),
610				le32_to_cpu(cmd->chan_state_active_bitmap),
611				cmd_ver);
612		IWL_DEBUG_RADIO(fwrt,
613				"sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n",
614				le32_to_cpu(cmd->oem_uhb_allow_bitmap),
615				le32_to_cpu(cmd->force_disable_channels_bitmap));
616		IWL_DEBUG_RADIO(fwrt,
617				"sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x, oem_320mhz_allow_bitmap=0x%x\n",
618				le32_to_cpu(cmd->edt_bitmap),
619				le32_to_cpu(cmd->oem_320mhz_allow_bitmap));
620		IWL_DEBUG_RADIO(fwrt,
621				"sending LARI_CONFIG_CHANGE, oem_11be_allow_bitmap=0x%x\n",
622				le32_to_cpu(cmd->oem_11be_allow_bitmap));
623	} else {
624		return 1;
625	}
626
627	return 0;
628}
629IWL_EXPORT_SYMBOL(iwl_fill_lari_config);
630
631int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
632		     u32 *value)
633{
634	GET_BIOS_TABLE(dsm, fwrt, func, value);
635}
636IWL_EXPORT_SYMBOL(iwl_bios_get_dsm);
637
638bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc)
639{
640	/* Some kind of regulatory mess means we need to currently disallow
641	 * puncturing in the US and Canada unless enabled in BIOS.
642	 */
643	switch (mcc) {
644	case IWL_MCC_US:
645		return puncturing & IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK;
646	case IWL_MCC_CANADA:
647		return puncturing & IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK;
648	default:
649		return true;
650	}
651}
652IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios);