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
35 /* PPAG gain value bounds in 1/8 dBm */
36 #define IWL_PPAG_MIN_LB -16
37 #define IWL_PPAG_MAX_LB 24
38 #define IWL_PPAG_MIN_HB -16
39 #define IWL_PPAG_MAX_HB 40
40
41 #define IWL_PPAG_ETSI_CHINA_MASK 3
42 #define IWL_PPAG_REV3_MASK 0x7FF
43
44 #define IWL_WTAS_ENABLED_MSK BIT(0)
45 #define IWL_WTAS_OVERRIDE_IEC_MSK BIT(1)
46 #define IWL_WTAS_ENABLE_IEC_MSK BIT(2)
47 #define IWL_WTAS_CANADA_UHB_MSK BIT(15)
48 #define IWL_WTAS_USA_UHB_MSK BIT(16)
49
50 struct iwl_tas_selection_data {
51 u8 override_tas_iec:1,
52 enable_tas_iec:1,
53 usa_tas_uhb_allowed:1,
54 canada_tas_uhb_allowed:1;
55 };
56
57 #define BIOS_MCC_CHINA 0x434e
58
59 /*
60 * The profile for revision 2 is a superset of revision 1, which is in
61 * turn a superset of revision 0. So we can store all revisions
62 * inside revision 2, which is what we represent here.
63 */
64
65 /*
66 * struct iwl_sar_profile_chain - per-chain values of a SAR profile
67 * @subbands: the SAR value for each subband
68 */
69 struct iwl_sar_profile_chain {
70 u8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
71 };
72
73 /*
74 * struct iwl_sar_profile - SAR profile from SAR tables
75 * @enabled: whether the profile is enabled or not
76 * @chains: per-chain SAR values
77 */
78 struct iwl_sar_profile {
79 bool enabled;
80 struct iwl_sar_profile_chain chains[BIOS_SAR_MAX_CHAINS_PER_PROFILE];
81 };
82
83 /* Same thing as with SAR, all revisions fit in revision 2 */
84
85 /*
86 * struct iwl_geo_profile_band - per-band geo SAR offsets
87 * @max: the max tx power allowed for the band
88 * @chains: SAR offsets values for each chain
89 */
90 struct iwl_geo_profile_band {
91 u8 max;
92 u8 chains[BIOS_GEO_NUM_CHAINS];
93 };
94
95 /*
96 * struct iwl_geo_profile - geo profile
97 * @bands: per-band table of the SAR offsets
98 */
99 struct iwl_geo_profile {
100 struct iwl_geo_profile_band bands[BIOS_GEO_MAX_NUM_BANDS];
101 };
102
103 /* Same thing as with SAR, all revisions fit in revision 2 */
104 struct iwl_ppag_chain {
105 s8 subbands[BIOS_PPAG_MAX_SUB_BANDS_NUM];
106 };
107
108 struct iwl_tas_data {
109 u8 block_list_size;
110 u16 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
111 u8 table_source;
112 u8 table_revision;
113 u32 tas_selection;
114 };
115
116 /* For DSM revision 0 and 4 */
117 enum iwl_dsm_funcs {
118 DSM_FUNC_QUERY = 0,
119 DSM_FUNC_DISABLE_SRD = 1,
120 DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
121 DSM_FUNC_ENABLE_6E = 3,
122 DSM_FUNC_REGULATORY_CONFIG = 4,
123 DSM_FUNC_11AX_ENABLEMENT = 6,
124 DSM_FUNC_ENABLE_UNII4_CHAN = 7,
125 DSM_FUNC_ACTIVATE_CHANNEL = 8,
126 DSM_FUNC_FORCE_DISABLE_CHANNELS = 9,
127 DSM_FUNC_ENERGY_DETECTION_THRESHOLD = 10,
128 DSM_FUNC_RFI_CONFIG = 11,
129 DSM_FUNC_ENABLE_11BE = 12,
130 DSM_FUNC_ENABLE_11BN = 13,
131 DSM_FUNC_ENABLE_UNII_9 = 14,
132 DSM_FUNC_NUM_FUNCS,
133 };
134
135 enum iwl_dsm_values_srd {
136 DSM_VALUE_SRD_ACTIVE,
137 DSM_VALUE_SRD_PASSIVE,
138 DSM_VALUE_SRD_DISABLE,
139 DSM_VALUE_SRD_MAX
140 };
141
142 enum iwl_dsm_values_indonesia {
143 DSM_VALUE_INDONESIA_DISABLE,
144 DSM_VALUE_INDONESIA_ENABLE,
145 DSM_VALUE_INDONESIA_RESERVED,
146 DSM_VALUE_INDONESIA_MAX
147 };
148
149 enum iwl_dsm_unii4_bitmap {
150 DSM_VALUE_UNII4_US_OVERRIDE_MSK = BIT(0),
151 DSM_VALUE_UNII4_US_EN_MSK = BIT(1),
152 DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK = BIT(2),
153 DSM_VALUE_UNII4_ETSI_EN_MSK = BIT(3),
154 DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK = BIT(4),
155 DSM_VALUE_UNII4_CANADA_EN_MSK = BIT(5),
156 };
157
158 #define DSM_UNII4_ALLOW_BITMAP (DSM_VALUE_UNII4_US_OVERRIDE_MSK |\
159 DSM_VALUE_UNII4_US_EN_MSK |\
160 DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK |\
161 DSM_VALUE_UNII4_ETSI_EN_MSK |\
162 DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK |\
163 DSM_VALUE_UNII4_CANADA_EN_MSK)
164
165 #define DSM_11AX_ALLOW_BITMAP 0xF
166 #define DSM_EDT_ALLOWED_BITMAP 0x7ffff0
167 #define DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP 0x7FF
168
169 enum iwl_dsm_values_rfi {
170 DSM_VALUE_RFI_DLVR_DISABLE = BIT(0),
171 DSM_VALUE_RFI_DDR_DISABLE = BIT(1),
172 };
173
174 #define DSM_VALUE_RFI_DISABLE (DSM_VALUE_RFI_DLVR_DISABLE |\
175 DSM_VALUE_RFI_DDR_DISABLE)
176
177 bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt);
178
179 enum iwl_dsm_masks_reg {
180 DSM_MASK_CHINA_22_REG = BIT(2)
181 };
182
183 struct iwl_fw_runtime;
184
185 /* Print the PPAG table as read from BIOS */
186 void iwl_bios_print_ppag(struct iwl_fw_runtime *fwrt, int n_subbands);
187
188 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
189
190 int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
191 struct iwl_per_chain_offset *table,
192 u32 n_bands, u32 n_profiles);
193
194 int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
195 __le16 *per_chain, u32 n_tables, u32 n_subbands,
196 int prof_a, int prof_b);
197
198 bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);
199
200 bool iwl_is_tas_approved(void);
201 bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc);
202
203 struct iwl_tas_selection_data
204 iwl_parse_tas_selection(const u32 tas_selection, const u8 tbl_rev);
205
206 int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
207
208 int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt);
209
210 int iwl_bios_get_wgds_table(struct iwl_fw_runtime *fwrt);
211
212 int iwl_bios_get_ppag_table(struct iwl_fw_runtime *fwrt);
213
214 int iwl_bios_get_tas_table(struct iwl_fw_runtime *fwrt,
215 struct iwl_tas_data *data);
216
217 int iwl_bios_get_pwr_limit(struct iwl_fw_runtime *fwrt,
218 u64 *dflt_pwr_limit);
219
220 int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
221 int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk);
222 int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value);
223
224 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
225 u32 *value);
226
iwl_bios_get_ppag_flags(const u32 ppag_modes,const u8 ppag_bios_rev)227 static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
228 const u8 ppag_bios_rev)
229 {
230 /* For revision 4 and above driver is pipe */
231 if (ppag_bios_rev >= 4)
232 return ppag_modes;
233
234 return ppag_modes & (ppag_bios_rev < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
235 IWL_PPAG_REV3_MASK);
236 }
237
238 bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc);
239
240 #define IWL_DSBR_FW_MODIFIED_URM_MASK BIT(8)
241 #define IWL_DSBR_PERMANENT_URM_MASK BIT(9)
242
243 int iwl_bios_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value);
244 int iwl_bios_get_phy_filters(struct iwl_fw_runtime *fwrt);
245
iwl_bios_setup_step(struct iwl_trans * trans,struct iwl_fw_runtime * fwrt)246 static inline void iwl_bios_setup_step(struct iwl_trans *trans,
247 struct iwl_fw_runtime *fwrt)
248 {
249 u32 dsbr;
250
251 if (!trans->mac_cfg->integrated)
252 return;
253
254 if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ)
255 return;
256
257 if (iwl_bios_get_dsbr(fwrt, &dsbr))
258 dsbr = 0;
259
260 trans->conf.dsbr_urm_fw_dependent =
261 !!(dsbr & IWL_DSBR_FW_MODIFIED_URM_MASK);
262 trans->conf.dsbr_urm_permanent =
263 !!(dsbr & IWL_DSBR_PERMANENT_URM_MASK);
264 }
265 #endif /* __fw_regulatory_h__ */
266