xref: /linux/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h (revision 2395f2a298eec2abdb148d51fe2e0ccac431237f)
1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /*
3  * Copyright (C) 2023-2026 Intel Corporation
4  */
5 
6 #ifndef __fw_regulatory_h__
7 #define __fw_regulatory_h__
8 
9 #include "fw/img.h"
10 #include "fw/api/commands.h"
11 #include "fw/api/power.h"
12 #include "fw/api/phy.h"
13 #include "fw/api/config.h"
14 #include "fw/api/nvm-reg.h"
15 #include "iwl-trans.h"
16 
17 #define BIOS_SAR_MAX_PROFILE_NUM	4
18 /*
19  * Each SAR profile has (up to, depends on the table revision) 4 chains:
20  * chain A, chain B, chain A when in CDB, chain B when in CDB
21  */
22 #define BIOS_SAR_MAX_CHAINS_PER_PROFILE 4
23 #define BIOS_SAR_NUM_CHAINS             2
24 #define BIOS_SAR_MAX_SUB_BANDS_NUM      12
25 #define BIOS_PPAG_MAX_SUB_BANDS_NUM     12
26 
27 #define BIOS_GEO_NUM_CHAINS		2
28 #define BIOS_GEO_MAX_NUM_BANDS		4
29 #define BIOS_GEO_MAX_PROFILE_NUM	8
30 #define BIOS_GEO_MIN_PROFILE_NUM	3
31 
32 #define IWL_SAR_ENABLE_MSK		BIT(0)
33 #define IWL_REDUCE_POWER_FLAGS_POS	1
34 #define IWL_BIOS_REVISION_UNSET		0xFF
35 
36 /* PPAG gain value bounds in 1/8 dBm */
37 #define IWL_PPAG_MIN_LB	-16
38 #define IWL_PPAG_MAX_LB 24
39 #define IWL_PPAG_MIN_HB -16
40 #define IWL_PPAG_MAX_HB 40
41 
42 #define IWL_PPAG_ETSI_CHINA_MASK	3
43 #define IWL_PPAG_REV3_MASK		0x7FF
44 
45 #define IWL_WTAS_ENABLED_MSK		BIT(0)
46 #define IWL_WTAS_OVERRIDE_IEC_MSK	BIT(1)
47 #define IWL_WTAS_ENABLE_IEC_MSK		BIT(2)
48 #define IWL_WTAS_CANADA_UHB_MSK		BIT(15)
49 #define IWL_WTAS_USA_UHB_MSK		BIT(16)
50 
51 /**
52  * enum iwl_uefi_cnv_guid_status - lock status of the connectivity
53  * UEFI tables
54  * @UEFI_CNV_GUID_UNLOCKED: the tables are unlocked
55  * @UEFI_CNV_GUID_LOCKED: the tables are locked
56  * @UEFI_CNV_GUID_TEST_MODE: the tables are locked in test mode
57  * @UEFI_CNV_GUID_UNKNOWN: the lock status could not be determined.
58  *	This value is a driver internal, not a possible BIOS reported one
59  */
60 enum iwl_uefi_cnv_guid_status {
61 	UEFI_CNV_GUID_UNLOCKED = 0,
62 	UEFI_CNV_GUID_LOCKED = 1,
63 	UEFI_CNV_GUID_TEST_MODE = 2,
64 	UEFI_CNV_GUID_UNKNOWN = 3,
65 };
66 
67 struct iwl_tas_selection_data {
68 	u8 override_tas_iec:1,
69 	   enable_tas_iec:1,
70 	   usa_tas_uhb_allowed:1,
71 	   canada_tas_uhb_allowed:1;
72 };
73 
74 #define BIOS_MCC_CHINA 0x434e
75 
76 /*
77  * The profile for revision 2 is a superset of revision 1, which is in
78  * turn a superset of revision 0.  So we can store all revisions
79  * inside revision 2, which is what we represent here.
80  */
81 
82 /*
83  * struct iwl_sar_profile_chain - per-chain values of a SAR profile
84  * @subbands: the SAR value for each subband
85  */
86 struct iwl_sar_profile_chain {
87 	u8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
88 };
89 
90 /*
91  * struct iwl_sar_profile - SAR profile from SAR tables
92  * @enabled: whether the profile is enabled or not
93  * @chains: per-chain SAR values
94  */
95 struct iwl_sar_profile {
96 	bool enabled;
97 	struct iwl_sar_profile_chain chains[BIOS_SAR_MAX_CHAINS_PER_PROFILE];
98 };
99 
100 /* Same thing as with SAR, all revisions fit in revision 2 */
101 
102 /*
103  * struct iwl_geo_profile_band - per-band geo SAR offsets
104  * @max: the max tx power allowed for the band
105  * @chains: SAR offsets values for each chain
106  */
107 struct iwl_geo_profile_band {
108 	u8 max;
109 	u8 chains[BIOS_GEO_NUM_CHAINS];
110 };
111 
112 /*
113  * struct iwl_geo_profile - geo profile
114  * @bands: per-band table of the SAR offsets
115  */
116 struct iwl_geo_profile {
117 	struct iwl_geo_profile_band bands[BIOS_GEO_MAX_NUM_BANDS];
118 };
119 
120 /* Same thing as with SAR, all revisions fit in revision 2 */
121 struct iwl_ppag_chain {
122 	s8 subbands[BIOS_PPAG_MAX_SUB_BANDS_NUM];
123 };
124 
125 struct iwl_tas_data {
126 	u8 block_list_size;
127 	u16 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
128 	u8 table_source;
129 	u8 table_revision;
130 	u32 tas_selection;
131 };
132 
133 /* For DSM revision 0 and 4 */
134 enum iwl_dsm_funcs {
135 	DSM_FUNC_QUERY = 0,
136 	DSM_FUNC_DISABLE_SRD = 1,
137 	DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
138 	DSM_FUNC_ENABLE_6E = 3,
139 	DSM_FUNC_REGULATORY_CONFIG = 4,
140 	DSM_FUNC_11AX_ENABLEMENT = 6,
141 	DSM_FUNC_ENABLE_UNII4_CHAN = 7,
142 	DSM_FUNC_ACTIVATE_CHANNEL = 8,
143 	DSM_FUNC_FORCE_DISABLE_CHANNELS = 9,
144 	DSM_FUNC_ENERGY_DETECTION_THRESHOLD = 10,
145 	DSM_FUNC_RFI_CONFIG = 11,
146 	DSM_FUNC_ENABLE_11BE = 12,
147 	DSM_FUNC_ENABLE_11BN = 13,
148 	DSM_FUNC_ENABLE_UNII_9 = 14,
149 	DSM_FUNC_NUM_FUNCS,
150 };
151 
152 enum iwl_dsm_values_srd {
153 	DSM_VALUE_SRD_ACTIVE,
154 	DSM_VALUE_SRD_PASSIVE,
155 	DSM_VALUE_SRD_DISABLE,
156 	DSM_VALUE_SRD_MAX
157 };
158 
159 enum iwl_dsm_values_indonesia {
160 	DSM_VALUE_INDONESIA_DISABLE,
161 	DSM_VALUE_INDONESIA_ENABLE,
162 	DSM_VALUE_INDONESIA_RESERVED,
163 	DSM_VALUE_INDONESIA_MAX
164 };
165 
166 enum iwl_dsm_unii4_bitmap {
167 	DSM_VALUE_UNII4_US_OVERRIDE_MSK		= BIT(0),
168 	DSM_VALUE_UNII4_US_EN_MSK		= BIT(1),
169 	DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK	= BIT(2),
170 	DSM_VALUE_UNII4_ETSI_EN_MSK		= BIT(3),
171 	DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK	= BIT(4),
172 	DSM_VALUE_UNII4_CANADA_EN_MSK		= BIT(5),
173 };
174 
175 #define DSM_UNII4_ALLOW_BITMAP (DSM_VALUE_UNII4_US_OVERRIDE_MSK		|\
176 				DSM_VALUE_UNII4_US_EN_MSK		|\
177 				DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK	|\
178 				DSM_VALUE_UNII4_ETSI_EN_MSK		|\
179 				DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK	|\
180 				DSM_VALUE_UNII4_CANADA_EN_MSK)
181 
182 #define DSM_11AX_ALLOW_BITMAP				0xF
183 #define DSM_EDT_ALLOWED_BITMAP				0x7ffff0
184 #define DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP	0x7FF
185 
186 enum iwl_dsm_values_rfi {
187 	DSM_VALUE_RFI_DLVR_DISABLE	= BIT(0),
188 	DSM_VALUE_RFI_DDR_DISABLE	= BIT(1),
189 };
190 
191 #define DSM_VALUE_RFI_DISABLE	(DSM_VALUE_RFI_DLVR_DISABLE |\
192 				 DSM_VALUE_RFI_DDR_DISABLE)
193 
194 bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt);
195 
196 enum iwl_dsm_masks_reg {
197 	DSM_MASK_CHINA_22_REG = BIT(2)
198 };
199 
200 struct iwl_fw_runtime;
201 
202 /* Print the PPAG table as read from BIOS */
203 void iwl_bios_print_ppag(struct iwl_fw_runtime *fwrt, int n_subbands);
204 
205 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
206 
207 int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
208 			   struct iwl_per_chain_offset *table,
209 			   u32 n_bands, u32 n_profiles);
210 
211 int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
212 			 __le16 *per_chain, u32 n_tables, u32 n_subbands,
213 			 int prof_a, int prof_b,
214 			 const struct iwl_sar_profile *profiles,
215 			 bool is_standalone);
216 
217 bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);
218 
219 bool iwl_is_tas_approved(void);
220 bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc);
221 
222 struct iwl_tas_selection_data
223 iwl_parse_tas_selection(const u32 tas_selection, const u8 tbl_rev);
224 
225 int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
226 
227 int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt);
228 
229 int iwl_bios_get_wsss_table(struct iwl_fw_runtime *fwrt);
230 
231 int iwl_bios_get_ewss_table(struct iwl_fw_runtime *fwrt);
232 
233 int iwl_bios_get_wgds_table(struct iwl_fw_runtime *fwrt);
234 
235 int iwl_bios_get_ppag_table(struct iwl_fw_runtime *fwrt);
236 
237 int iwl_bios_get_tas_table(struct iwl_fw_runtime *fwrt,
238 			   struct iwl_tas_data *data);
239 
240 int iwl_bios_get_pwr_limit(struct iwl_fw_runtime *fwrt,
241 			   u64 *dflt_pwr_limit);
242 
243 int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
244 int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk);
245 int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value);
246 
247 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
248 		     u32 *value);
249 
250 static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
251 					  const u8 ppag_bios_rev)
252 {
253 	/* For revision 4 and above driver is pipe */
254 	if (ppag_bios_rev >= 4)
255 		return ppag_modes;
256 
257 	return ppag_modes & (ppag_bios_rev < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
258 						 IWL_PPAG_REV3_MASK);
259 }
260 
261 bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc);
262 
263 #define IWL_DSBR_FW_MODIFIED_URM_MASK	BIT(8)
264 #define IWL_DSBR_PERMANENT_URM_MASK	BIT(9)
265 
266 int iwl_bios_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value);
267 int iwl_bios_get_phy_filters(struct iwl_fw_runtime *fwrt);
268 void iwl_bios_get_guid_lock_status(struct iwl_fw_runtime *fwrt);
269 
270 static inline void iwl_bios_setup_step(struct iwl_trans *trans,
271 				       struct iwl_fw_runtime *fwrt)
272 {
273 	u32 dsbr;
274 
275 	if (!trans->mac_cfg->integrated)
276 		return;
277 
278 	if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ)
279 		return;
280 
281 	if (iwl_bios_get_dsbr(fwrt, &dsbr))
282 		dsbr = 0;
283 
284 	trans->conf.dsbr_urm_fw_dependent =
285 		!!(dsbr & IWL_DSBR_FW_MODIFIED_URM_MASK);
286 	trans->conf.dsbr_urm_permanent =
287 		!!(dsbr & IWL_DSBR_PERMANENT_URM_MASK);
288 }
289 #endif /* __fw_regulatory_h__ */
290