xref: /linux/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h (revision 9410645520e9b820069761f3450ef6661418e279)
12594e4d9SMiri Korenblit /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
22594e4d9SMiri Korenblit /*
36b3e87ccSAnjaneyulu  * Copyright (C) 2023-2024 Intel Corporation
42594e4d9SMiri Korenblit  */
52594e4d9SMiri Korenblit 
62594e4d9SMiri Korenblit #ifndef __fw_regulatory_h__
72594e4d9SMiri Korenblit #define __fw_regulatory_h__
82594e4d9SMiri Korenblit 
92594e4d9SMiri Korenblit #include "fw/img.h"
102594e4d9SMiri Korenblit #include "fw/api/commands.h"
112594e4d9SMiri Korenblit #include "fw/api/power.h"
122594e4d9SMiri Korenblit #include "fw/api/phy.h"
132594e4d9SMiri Korenblit #include "fw/api/config.h"
1422d0d333SAnjaneyulu #include "fw/api/nvm-reg.h"
152594e4d9SMiri Korenblit #include "fw/img.h"
162594e4d9SMiri Korenblit #include "iwl-trans.h"
172594e4d9SMiri Korenblit 
182594e4d9SMiri Korenblit #define BIOS_SAR_MAX_PROFILE_NUM	4
192594e4d9SMiri Korenblit /*
202594e4d9SMiri Korenblit  * Each SAR profile has (up to, depends on the table revision) 4 chains:
212594e4d9SMiri Korenblit  * chain A, chain B, chain A when in CDB, chain B when in CDB
222594e4d9SMiri Korenblit  */
232594e4d9SMiri Korenblit #define BIOS_SAR_MAX_CHAINS_PER_PROFILE 4
242594e4d9SMiri Korenblit #define BIOS_SAR_NUM_CHAINS             2
252594e4d9SMiri Korenblit #define BIOS_SAR_MAX_SUB_BANDS_NUM      11
262594e4d9SMiri Korenblit 
272594e4d9SMiri Korenblit #define BIOS_GEO_NUM_CHAINS		2
282594e4d9SMiri Korenblit #define BIOS_GEO_MAX_NUM_BANDS		3
292594e4d9SMiri Korenblit #define BIOS_GEO_MAX_PROFILE_NUM	8
302594e4d9SMiri Korenblit #define BIOS_GEO_MIN_PROFILE_NUM	3
312594e4d9SMiri Korenblit 
322594e4d9SMiri Korenblit #define IWL_SAR_ENABLE_MSK		BIT(0)
332594e4d9SMiri Korenblit 
3409059c67SMiri Korenblit /* PPAG gain value bounds in 1/8 dBm */
3509059c67SMiri Korenblit #define IWL_PPAG_MIN_LB	-16
3609059c67SMiri Korenblit #define IWL_PPAG_MAX_LB 24
3709059c67SMiri Korenblit #define IWL_PPAG_MIN_HB -16
3809059c67SMiri Korenblit #define IWL_PPAG_MAX_HB 40
3909059c67SMiri Korenblit 
4009059c67SMiri Korenblit #define IWL_PPAG_ETSI_CHINA_MASK	3
413d801a75SAnjaneyulu #define IWL_PPAG_REV3_MASK		0x7FF
4209059c67SMiri Korenblit 
43ad5a85d8SMiri Korenblit #define IWL_WTAS_ENABLED_MSK		0x1
44ad5a85d8SMiri Korenblit #define IWL_WTAS_OVERRIDE_IEC_MSK	0x2
45ad5a85d8SMiri Korenblit #define IWL_WTAS_ENABLE_IEC_MSK	0x4
46ad5a85d8SMiri Korenblit #define IWL_WTAS_USA_UHB_MSK		BIT(16)
47ad5a85d8SMiri Korenblit 
48*ff5aabe7SAnjaneyulu #define BIOS_MCC_CHINA 0x434e
49*ff5aabe7SAnjaneyulu 
502594e4d9SMiri Korenblit /*
512594e4d9SMiri Korenblit  * The profile for revision 2 is a superset of revision 1, which is in
522594e4d9SMiri Korenblit  * turn a superset of revision 0.  So we can store all revisions
532594e4d9SMiri Korenblit  * inside revision 2, which is what we represent here.
542594e4d9SMiri Korenblit  */
552594e4d9SMiri Korenblit 
562594e4d9SMiri Korenblit /*
572594e4d9SMiri Korenblit  * struct iwl_sar_profile_chain - per-chain values of a SAR profile
582594e4d9SMiri Korenblit  * @subbands: the SAR value for each subband
592594e4d9SMiri Korenblit  */
602594e4d9SMiri Korenblit struct iwl_sar_profile_chain {
612594e4d9SMiri Korenblit 	u8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
622594e4d9SMiri Korenblit };
632594e4d9SMiri Korenblit 
642594e4d9SMiri Korenblit /*
652594e4d9SMiri Korenblit  * struct iwl_sar_profile - SAR profile from SAR tables
662594e4d9SMiri Korenblit  * @enabled: whether the profile is enabled or not
672594e4d9SMiri Korenblit  * @chains: per-chain SAR values
682594e4d9SMiri Korenblit  */
692594e4d9SMiri Korenblit struct iwl_sar_profile {
702594e4d9SMiri Korenblit 	bool enabled;
712594e4d9SMiri Korenblit 	struct iwl_sar_profile_chain chains[BIOS_SAR_MAX_CHAINS_PER_PROFILE];
722594e4d9SMiri Korenblit };
732594e4d9SMiri Korenblit 
742594e4d9SMiri Korenblit /* Same thing as with SAR, all revisions fit in revision 2 */
752594e4d9SMiri Korenblit 
762594e4d9SMiri Korenblit /*
772594e4d9SMiri Korenblit  * struct iwl_geo_profile_band - per-band geo SAR offsets
782594e4d9SMiri Korenblit  * @max: the max tx power allowed for the band
792594e4d9SMiri Korenblit  * @chains: SAR offsets values for each chain
802594e4d9SMiri Korenblit  */
812594e4d9SMiri Korenblit struct iwl_geo_profile_band {
822594e4d9SMiri Korenblit 	u8 max;
832594e4d9SMiri Korenblit 	u8 chains[BIOS_GEO_NUM_CHAINS];
842594e4d9SMiri Korenblit };
852594e4d9SMiri Korenblit 
862594e4d9SMiri Korenblit /*
872594e4d9SMiri Korenblit  * struct iwl_geo_profile - geo profile
882594e4d9SMiri Korenblit  * @bands: per-band table of the SAR offsets
892594e4d9SMiri Korenblit  */
902594e4d9SMiri Korenblit struct iwl_geo_profile {
912594e4d9SMiri Korenblit 	struct iwl_geo_profile_band bands[BIOS_GEO_MAX_NUM_BANDS];
922594e4d9SMiri Korenblit };
932594e4d9SMiri Korenblit 
9409059c67SMiri Korenblit /* Same thing as with SAR, all revisions fit in revision 2 */
9509059c67SMiri Korenblit struct iwl_ppag_chain {
9609059c67SMiri Korenblit 	s8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
9709059c67SMiri Korenblit };
9809059c67SMiri Korenblit 
993bc67e7cSMiri Korenblit struct iwl_tas_data {
1003bc67e7cSMiri Korenblit 	__le32 block_list_size;
1013bc67e7cSMiri Korenblit 	__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
1023bc67e7cSMiri Korenblit 	u8 override_tas_iec;
1033bc67e7cSMiri Korenblit 	u8 enable_tas_iec;
1043bc67e7cSMiri Korenblit 	u8 usa_tas_uhb_allowed;
1053bc67e7cSMiri Korenblit };
1062594e4d9SMiri Korenblit 
107dc4fe750SMiri Korenblit /* For DSM revision 0 and 4 */
108dc4fe750SMiri Korenblit enum iwl_dsm_funcs {
109dc4fe750SMiri Korenblit 	DSM_FUNC_QUERY = 0,
110dc4fe750SMiri Korenblit 	DSM_FUNC_DISABLE_SRD = 1,
111dc4fe750SMiri Korenblit 	DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
112dc4fe750SMiri Korenblit 	DSM_FUNC_ENABLE_6E = 3,
113dc4fe750SMiri Korenblit 	DSM_FUNC_REGULATORY_CONFIG = 4,
114dc4fe750SMiri Korenblit 	DSM_FUNC_11AX_ENABLEMENT = 6,
115dc4fe750SMiri Korenblit 	DSM_FUNC_ENABLE_UNII4_CHAN = 7,
116dc4fe750SMiri Korenblit 	DSM_FUNC_ACTIVATE_CHANNEL = 8,
117dc4fe750SMiri Korenblit 	DSM_FUNC_FORCE_DISABLE_CHANNELS = 9,
118dc4fe750SMiri Korenblit 	DSM_FUNC_ENERGY_DETECTION_THRESHOLD = 10,
119dc4fe750SMiri Korenblit 	DSM_FUNC_RFI_CONFIG = 11,
12048443a4aSAnjaneyulu 	DSM_FUNC_ENABLE_11BE = 12,
12148443a4aSAnjaneyulu 	DSM_FUNC_NUM_FUNCS = 13,
122dc4fe750SMiri Korenblit };
123dc4fe750SMiri Korenblit 
124dc4fe750SMiri Korenblit enum iwl_dsm_values_srd {
125dc4fe750SMiri Korenblit 	DSM_VALUE_SRD_ACTIVE,
126dc4fe750SMiri Korenblit 	DSM_VALUE_SRD_PASSIVE,
127dc4fe750SMiri Korenblit 	DSM_VALUE_SRD_DISABLE,
128dc4fe750SMiri Korenblit 	DSM_VALUE_SRD_MAX
129dc4fe750SMiri Korenblit };
130dc4fe750SMiri Korenblit 
131dc4fe750SMiri Korenblit enum iwl_dsm_values_indonesia {
132dc4fe750SMiri Korenblit 	DSM_VALUE_INDONESIA_DISABLE,
133dc4fe750SMiri Korenblit 	DSM_VALUE_INDONESIA_ENABLE,
134dc4fe750SMiri Korenblit 	DSM_VALUE_INDONESIA_RESERVED,
135dc4fe750SMiri Korenblit 	DSM_VALUE_INDONESIA_MAX
136dc4fe750SMiri Korenblit };
137dc4fe750SMiri Korenblit 
1386b3e87ccSAnjaneyulu enum iwl_dsm_unii4_bitmap {
1396b3e87ccSAnjaneyulu 	DSM_VALUE_UNII4_US_OVERRIDE_MSK		= BIT(0),
1406b3e87ccSAnjaneyulu 	DSM_VALUE_UNII4_US_EN_MSK		= BIT(1),
1416b3e87ccSAnjaneyulu 	DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK	= BIT(2),
1426b3e87ccSAnjaneyulu 	DSM_VALUE_UNII4_ETSI_EN_MSK		= BIT(3),
1436b3e87ccSAnjaneyulu 	DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK	= BIT(4),
1446b3e87ccSAnjaneyulu 	DSM_VALUE_UNII4_CANADA_EN_MSK		= BIT(5),
1456b3e87ccSAnjaneyulu };
1466b3e87ccSAnjaneyulu 
1476b3e87ccSAnjaneyulu #define DSM_UNII4_ALLOW_BITMAP_CMD_V8 (DSM_VALUE_UNII4_US_OVERRIDE_MSK | \
1486b3e87ccSAnjaneyulu 				       DSM_VALUE_UNII4_US_EN_MSK | \
1496b3e87ccSAnjaneyulu 				       DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK | \
1506b3e87ccSAnjaneyulu 				       DSM_VALUE_UNII4_ETSI_EN_MSK)
1516b3e87ccSAnjaneyulu #define DSM_UNII4_ALLOW_BITMAP (DSM_UNII4_ALLOW_BITMAP_CMD_V8 | \
1526b3e87ccSAnjaneyulu 				DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | \
1536b3e87ccSAnjaneyulu 				DSM_VALUE_UNII4_CANADA_EN_MSK)
1546b3e87ccSAnjaneyulu 
155dc4fe750SMiri Korenblit enum iwl_dsm_values_rfi {
156dc4fe750SMiri Korenblit 	DSM_VALUE_RFI_DLVR_DISABLE	= BIT(0),
157dc4fe750SMiri Korenblit 	DSM_VALUE_RFI_DDR_DISABLE	= BIT(1),
158dc4fe750SMiri Korenblit };
159dc4fe750SMiri Korenblit 
160dc4fe750SMiri Korenblit #define DSM_VALUE_RFI_DISABLE	(DSM_VALUE_RFI_DLVR_DISABLE |\
161dc4fe750SMiri Korenblit 				 DSM_VALUE_RFI_DDR_DISABLE)
162dc4fe750SMiri Korenblit 
163dc4fe750SMiri Korenblit enum iwl_dsm_masks_reg {
164dc4fe750SMiri Korenblit 	DSM_MASK_CHINA_22_REG = BIT(2)
165dc4fe750SMiri Korenblit };
166dc4fe750SMiri Korenblit 
1673bc67e7cSMiri Korenblit struct iwl_fw_runtime;
168ad5a85d8SMiri Korenblit 
1692594e4d9SMiri Korenblit bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
1702594e4d9SMiri Korenblit 
1712594e4d9SMiri Korenblit int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
1722594e4d9SMiri Korenblit 			   struct iwl_per_chain_offset *table,
1732594e4d9SMiri Korenblit 			   u32 n_bands, u32 n_profiles);
1742594e4d9SMiri Korenblit 
1752594e4d9SMiri Korenblit int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
1762594e4d9SMiri Korenblit 			 __le16 *per_chain, u32 n_tables, u32 n_subbands,
1772594e4d9SMiri Korenblit 			 int prof_a, int prof_b);
1782594e4d9SMiri Korenblit 
17909059c67SMiri Korenblit int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
18009059c67SMiri Korenblit 			union iwl_ppag_table_cmd *cmd,
18109059c67SMiri Korenblit 			int *cmd_size);
18209059c67SMiri Korenblit 
18309059c67SMiri Korenblit bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);
18409059c67SMiri Korenblit 
185ad5a85d8SMiri Korenblit bool iwl_is_tas_approved(void);
186ad5a85d8SMiri Korenblit 
187ad5a85d8SMiri Korenblit int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
1883bc67e7cSMiri Korenblit 			    struct iwl_tas_data *tas_data,
189ad5a85d8SMiri Korenblit 			    const u32 tas_selection);
190ad5a85d8SMiri Korenblit 
191427661e4SMiri Korenblit int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
192427661e4SMiri Korenblit 
193427661e4SMiri Korenblit int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt);
194427661e4SMiri Korenblit 
195427661e4SMiri Korenblit int iwl_bios_get_wgds_table(struct iwl_fw_runtime *fwrt);
196427661e4SMiri Korenblit 
197bc8d0a45SMiri Korenblit int iwl_bios_get_ppag_table(struct iwl_fw_runtime *fwrt);
198084e0452SMiri Korenblit 
199084e0452SMiri Korenblit int iwl_bios_get_tas_table(struct iwl_fw_runtime *fwrt,
200084e0452SMiri Korenblit 			   struct iwl_tas_data *data);
201084e0452SMiri Korenblit 
20218f52365SMiri Korenblit int iwl_bios_get_pwr_limit(struct iwl_fw_runtime *fwrt,
20318f52365SMiri Korenblit 			   u64 *dflt_pwr_limit);
204669761e8SMiri Korenblit 
205669761e8SMiri Korenblit int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
20620935f3eSMiri Korenblit int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk);
207332ff432SAnjaneyulu int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value);
208dc4fe750SMiri Korenblit 
209aa80f484SAnjaneyulu int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
210332ff432SAnjaneyulu 			 struct iwl_lari_config_change_cmd *cmd,
211aa80f484SAnjaneyulu 			 size_t *cmd_size);
212fc7214c3SMiri Korenblit 
213fc7214c3SMiri Korenblit int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
214fc7214c3SMiri Korenblit 		     u32 *value);
2153d801a75SAnjaneyulu 
iwl_bios_get_ppag_flags(const u32 ppag_modes,const u8 ppag_ver)2163d801a75SAnjaneyulu static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
2173d801a75SAnjaneyulu 					  const u8 ppag_ver)
2183d801a75SAnjaneyulu {
2193d801a75SAnjaneyulu 	return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
2203d801a75SAnjaneyulu 					    IWL_PPAG_REV3_MASK);
2213d801a75SAnjaneyulu }
222b312e357SSomashekhar(Som) 
223b312e357SSomashekhar(Som) bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc);
2242594e4d9SMiri Korenblit #endif /* __fw_regulatory_h__ */
225