xref: /freebsd/sys/contrib/dev/iwlwifi/fw/regulatory.h (revision a4128aad8503277614f2d214011ef60a19447b83)
1*a4128aadSBjoern A. Zeeb /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2*a4128aadSBjoern A. Zeeb /*
3*a4128aadSBjoern A. Zeeb  * Copyright (C) 2023-2024 Intel Corporation
4*a4128aadSBjoern A. Zeeb  */
5*a4128aadSBjoern A. Zeeb 
6*a4128aadSBjoern A. Zeeb #ifndef __fw_regulatory_h__
7*a4128aadSBjoern A. Zeeb #define __fw_regulatory_h__
8*a4128aadSBjoern A. Zeeb 
9*a4128aadSBjoern A. Zeeb #include "fw/img.h"
10*a4128aadSBjoern A. Zeeb #include "fw/api/commands.h"
11*a4128aadSBjoern A. Zeeb #include "fw/api/power.h"
12*a4128aadSBjoern A. Zeeb #include "fw/api/phy.h"
13*a4128aadSBjoern A. Zeeb #include "fw/api/config.h"
14*a4128aadSBjoern A. Zeeb #include "fw/api/nvm-reg.h"
15*a4128aadSBjoern A. Zeeb #include "fw/img.h"
16*a4128aadSBjoern A. Zeeb #include "iwl-trans.h"
17*a4128aadSBjoern A. Zeeb 
18*a4128aadSBjoern A. Zeeb #define BIOS_SAR_MAX_PROFILE_NUM	4
19*a4128aadSBjoern A. Zeeb /*
20*a4128aadSBjoern A. Zeeb  * Each SAR profile has (up to, depends on the table revision) 4 chains:
21*a4128aadSBjoern A. Zeeb  * chain A, chain B, chain A when in CDB, chain B when in CDB
22*a4128aadSBjoern A. Zeeb  */
23*a4128aadSBjoern A. Zeeb #define BIOS_SAR_MAX_CHAINS_PER_PROFILE 4
24*a4128aadSBjoern A. Zeeb #define BIOS_SAR_NUM_CHAINS             2
25*a4128aadSBjoern A. Zeeb #define BIOS_SAR_MAX_SUB_BANDS_NUM      11
26*a4128aadSBjoern A. Zeeb 
27*a4128aadSBjoern A. Zeeb #define BIOS_GEO_NUM_CHAINS		2
28*a4128aadSBjoern A. Zeeb #define BIOS_GEO_MAX_NUM_BANDS		3
29*a4128aadSBjoern A. Zeeb #define BIOS_GEO_MAX_PROFILE_NUM	8
30*a4128aadSBjoern A. Zeeb #define BIOS_GEO_MIN_PROFILE_NUM	3
31*a4128aadSBjoern A. Zeeb 
32*a4128aadSBjoern A. Zeeb #define IWL_SAR_ENABLE_MSK		BIT(0)
33*a4128aadSBjoern A. Zeeb 
34*a4128aadSBjoern A. Zeeb /* PPAG gain value bounds in 1/8 dBm */
35*a4128aadSBjoern A. Zeeb #define IWL_PPAG_MIN_LB	-16
36*a4128aadSBjoern A. Zeeb #define IWL_PPAG_MAX_LB 24
37*a4128aadSBjoern A. Zeeb #define IWL_PPAG_MIN_HB -16
38*a4128aadSBjoern A. Zeeb #define IWL_PPAG_MAX_HB 40
39*a4128aadSBjoern A. Zeeb 
40*a4128aadSBjoern A. Zeeb #define IWL_PPAG_ETSI_CHINA_MASK	3
41*a4128aadSBjoern A. Zeeb #define IWL_PPAG_REV3_MASK		0x7FF
42*a4128aadSBjoern A. Zeeb 
43*a4128aadSBjoern A. Zeeb #define IWL_WTAS_ENABLED_MSK		0x1
44*a4128aadSBjoern A. Zeeb #define IWL_WTAS_OVERRIDE_IEC_MSK	0x2
45*a4128aadSBjoern A. Zeeb #define IWL_WTAS_ENABLE_IEC_MSK	0x4
46*a4128aadSBjoern A. Zeeb #define IWL_WTAS_USA_UHB_MSK		BIT(16)
47*a4128aadSBjoern A. Zeeb 
48*a4128aadSBjoern A. Zeeb /*
49*a4128aadSBjoern A. Zeeb  * The profile for revision 2 is a superset of revision 1, which is in
50*a4128aadSBjoern A. Zeeb  * turn a superset of revision 0.  So we can store all revisions
51*a4128aadSBjoern A. Zeeb  * inside revision 2, which is what we represent here.
52*a4128aadSBjoern A. Zeeb  */
53*a4128aadSBjoern A. Zeeb 
54*a4128aadSBjoern A. Zeeb /*
55*a4128aadSBjoern A. Zeeb  * struct iwl_sar_profile_chain - per-chain values of a SAR profile
56*a4128aadSBjoern A. Zeeb  * @subbands: the SAR value for each subband
57*a4128aadSBjoern A. Zeeb  */
58*a4128aadSBjoern A. Zeeb struct iwl_sar_profile_chain {
59*a4128aadSBjoern A. Zeeb 	u8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
60*a4128aadSBjoern A. Zeeb };
61*a4128aadSBjoern A. Zeeb 
62*a4128aadSBjoern A. Zeeb /*
63*a4128aadSBjoern A. Zeeb  * struct iwl_sar_profile - SAR profile from SAR tables
64*a4128aadSBjoern A. Zeeb  * @enabled: whether the profile is enabled or not
65*a4128aadSBjoern A. Zeeb  * @chains: per-chain SAR values
66*a4128aadSBjoern A. Zeeb  */
67*a4128aadSBjoern A. Zeeb struct iwl_sar_profile {
68*a4128aadSBjoern A. Zeeb 	bool enabled;
69*a4128aadSBjoern A. Zeeb 	struct iwl_sar_profile_chain chains[BIOS_SAR_MAX_CHAINS_PER_PROFILE];
70*a4128aadSBjoern A. Zeeb };
71*a4128aadSBjoern A. Zeeb 
72*a4128aadSBjoern A. Zeeb /* Same thing as with SAR, all revisions fit in revision 2 */
73*a4128aadSBjoern A. Zeeb 
74*a4128aadSBjoern A. Zeeb /*
75*a4128aadSBjoern A. Zeeb  * struct iwl_geo_profile_band - per-band geo SAR offsets
76*a4128aadSBjoern A. Zeeb  * @max: the max tx power allowed for the band
77*a4128aadSBjoern A. Zeeb  * @chains: SAR offsets values for each chain
78*a4128aadSBjoern A. Zeeb  */
79*a4128aadSBjoern A. Zeeb struct iwl_geo_profile_band {
80*a4128aadSBjoern A. Zeeb 	u8 max;
81*a4128aadSBjoern A. Zeeb 	u8 chains[BIOS_GEO_NUM_CHAINS];
82*a4128aadSBjoern A. Zeeb };
83*a4128aadSBjoern A. Zeeb 
84*a4128aadSBjoern A. Zeeb /*
85*a4128aadSBjoern A. Zeeb  * struct iwl_geo_profile - geo profile
86*a4128aadSBjoern A. Zeeb  * @bands: per-band table of the SAR offsets
87*a4128aadSBjoern A. Zeeb  */
88*a4128aadSBjoern A. Zeeb struct iwl_geo_profile {
89*a4128aadSBjoern A. Zeeb 	struct iwl_geo_profile_band bands[BIOS_GEO_MAX_NUM_BANDS];
90*a4128aadSBjoern A. Zeeb };
91*a4128aadSBjoern A. Zeeb 
92*a4128aadSBjoern A. Zeeb /* Same thing as with SAR, all revisions fit in revision 2 */
93*a4128aadSBjoern A. Zeeb struct iwl_ppag_chain {
94*a4128aadSBjoern A. Zeeb 	s8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
95*a4128aadSBjoern A. Zeeb };
96*a4128aadSBjoern A. Zeeb 
97*a4128aadSBjoern A. Zeeb struct iwl_tas_data {
98*a4128aadSBjoern A. Zeeb 	__le32 block_list_size;
99*a4128aadSBjoern A. Zeeb 	__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
100*a4128aadSBjoern A. Zeeb 	u8 override_tas_iec;
101*a4128aadSBjoern A. Zeeb 	u8 enable_tas_iec;
102*a4128aadSBjoern A. Zeeb 	u8 usa_tas_uhb_allowed;
103*a4128aadSBjoern A. Zeeb };
104*a4128aadSBjoern A. Zeeb 
105*a4128aadSBjoern A. Zeeb /* For DSM revision 0 and 4 */
106*a4128aadSBjoern A. Zeeb enum iwl_dsm_funcs {
107*a4128aadSBjoern A. Zeeb 	DSM_FUNC_QUERY = 0,
108*a4128aadSBjoern A. Zeeb 	DSM_FUNC_DISABLE_SRD = 1,
109*a4128aadSBjoern A. Zeeb 	DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
110*a4128aadSBjoern A. Zeeb 	DSM_FUNC_ENABLE_6E = 3,
111*a4128aadSBjoern A. Zeeb 	DSM_FUNC_REGULATORY_CONFIG = 4,
112*a4128aadSBjoern A. Zeeb 	DSM_FUNC_11AX_ENABLEMENT = 6,
113*a4128aadSBjoern A. Zeeb 	DSM_FUNC_ENABLE_UNII4_CHAN = 7,
114*a4128aadSBjoern A. Zeeb 	DSM_FUNC_ACTIVATE_CHANNEL = 8,
115*a4128aadSBjoern A. Zeeb 	DSM_FUNC_FORCE_DISABLE_CHANNELS = 9,
116*a4128aadSBjoern A. Zeeb 	DSM_FUNC_ENERGY_DETECTION_THRESHOLD = 10,
117*a4128aadSBjoern A. Zeeb 	DSM_FUNC_RFI_CONFIG = 11,
118*a4128aadSBjoern A. Zeeb 	DSM_FUNC_ENABLE_11BE = 12,
119*a4128aadSBjoern A. Zeeb 	DSM_FUNC_NUM_FUNCS = 13,
120*a4128aadSBjoern A. Zeeb };
121*a4128aadSBjoern A. Zeeb 
122*a4128aadSBjoern A. Zeeb enum iwl_dsm_values_srd {
123*a4128aadSBjoern A. Zeeb 	DSM_VALUE_SRD_ACTIVE,
124*a4128aadSBjoern A. Zeeb 	DSM_VALUE_SRD_PASSIVE,
125*a4128aadSBjoern A. Zeeb 	DSM_VALUE_SRD_DISABLE,
126*a4128aadSBjoern A. Zeeb 	DSM_VALUE_SRD_MAX
127*a4128aadSBjoern A. Zeeb };
128*a4128aadSBjoern A. Zeeb 
129*a4128aadSBjoern A. Zeeb enum iwl_dsm_values_indonesia {
130*a4128aadSBjoern A. Zeeb 	DSM_VALUE_INDONESIA_DISABLE,
131*a4128aadSBjoern A. Zeeb 	DSM_VALUE_INDONESIA_ENABLE,
132*a4128aadSBjoern A. Zeeb 	DSM_VALUE_INDONESIA_RESERVED,
133*a4128aadSBjoern A. Zeeb 	DSM_VALUE_INDONESIA_MAX
134*a4128aadSBjoern A. Zeeb };
135*a4128aadSBjoern A. Zeeb 
136*a4128aadSBjoern A. Zeeb enum iwl_dsm_unii4_bitmap {
137*a4128aadSBjoern A. Zeeb 	DSM_VALUE_UNII4_US_OVERRIDE_MSK		= BIT(0),
138*a4128aadSBjoern A. Zeeb 	DSM_VALUE_UNII4_US_EN_MSK		= BIT(1),
139*a4128aadSBjoern A. Zeeb 	DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK	= BIT(2),
140*a4128aadSBjoern A. Zeeb 	DSM_VALUE_UNII4_ETSI_EN_MSK		= BIT(3),
141*a4128aadSBjoern A. Zeeb 	DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK	= BIT(4),
142*a4128aadSBjoern A. Zeeb 	DSM_VALUE_UNII4_CANADA_EN_MSK		= BIT(5),
143*a4128aadSBjoern A. Zeeb };
144*a4128aadSBjoern A. Zeeb 
145*a4128aadSBjoern A. Zeeb #define DSM_UNII4_ALLOW_BITMAP_CMD_V8 (DSM_VALUE_UNII4_US_OVERRIDE_MSK | \
146*a4128aadSBjoern A. Zeeb 				       DSM_VALUE_UNII4_US_EN_MSK | \
147*a4128aadSBjoern A. Zeeb 				       DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK | \
148*a4128aadSBjoern A. Zeeb 				       DSM_VALUE_UNII4_ETSI_EN_MSK)
149*a4128aadSBjoern A. Zeeb #define DSM_UNII4_ALLOW_BITMAP (DSM_UNII4_ALLOW_BITMAP_CMD_V8 | \
150*a4128aadSBjoern A. Zeeb 				DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | \
151*a4128aadSBjoern A. Zeeb 				DSM_VALUE_UNII4_CANADA_EN_MSK)
152*a4128aadSBjoern A. Zeeb 
153*a4128aadSBjoern A. Zeeb enum iwl_dsm_values_rfi {
154*a4128aadSBjoern A. Zeeb 	DSM_VALUE_RFI_DLVR_DISABLE	= BIT(0),
155*a4128aadSBjoern A. Zeeb 	DSM_VALUE_RFI_DDR_DISABLE	= BIT(1),
156*a4128aadSBjoern A. Zeeb };
157*a4128aadSBjoern A. Zeeb 
158*a4128aadSBjoern A. Zeeb #define DSM_VALUE_RFI_DISABLE	(DSM_VALUE_RFI_DLVR_DISABLE |\
159*a4128aadSBjoern A. Zeeb 				 DSM_VALUE_RFI_DDR_DISABLE)
160*a4128aadSBjoern A. Zeeb 
161*a4128aadSBjoern A. Zeeb enum iwl_dsm_masks_reg {
162*a4128aadSBjoern A. Zeeb 	DSM_MASK_CHINA_22_REG = BIT(2)
163*a4128aadSBjoern A. Zeeb };
164*a4128aadSBjoern A. Zeeb 
165*a4128aadSBjoern A. Zeeb struct iwl_fw_runtime;
166*a4128aadSBjoern A. Zeeb 
167*a4128aadSBjoern A. Zeeb bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
168*a4128aadSBjoern A. Zeeb 
169*a4128aadSBjoern A. Zeeb int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
170*a4128aadSBjoern A. Zeeb 			   struct iwl_per_chain_offset *table,
171*a4128aadSBjoern A. Zeeb 			   u32 n_bands, u32 n_profiles);
172*a4128aadSBjoern A. Zeeb 
173*a4128aadSBjoern A. Zeeb int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
174*a4128aadSBjoern A. Zeeb 			 __le16 *per_chain, u32 n_tables, u32 n_subbands,
175*a4128aadSBjoern A. Zeeb 			 int prof_a, int prof_b);
176*a4128aadSBjoern A. Zeeb 
177*a4128aadSBjoern A. Zeeb int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
178*a4128aadSBjoern A. Zeeb 			union iwl_ppag_table_cmd *cmd,
179*a4128aadSBjoern A. Zeeb 			int *cmd_size);
180*a4128aadSBjoern A. Zeeb 
181*a4128aadSBjoern A. Zeeb bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);
182*a4128aadSBjoern A. Zeeb 
183*a4128aadSBjoern A. Zeeb bool iwl_is_tas_approved(void);
184*a4128aadSBjoern A. Zeeb 
185*a4128aadSBjoern A. Zeeb int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
186*a4128aadSBjoern A. Zeeb 			    struct iwl_tas_data *tas_data,
187*a4128aadSBjoern A. Zeeb 			    const u32 tas_selection);
188*a4128aadSBjoern A. Zeeb 
189*a4128aadSBjoern A. Zeeb int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
190*a4128aadSBjoern A. Zeeb 
191*a4128aadSBjoern A. Zeeb int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt);
192*a4128aadSBjoern A. Zeeb 
193*a4128aadSBjoern A. Zeeb int iwl_bios_get_wgds_table(struct iwl_fw_runtime *fwrt);
194*a4128aadSBjoern A. Zeeb 
195*a4128aadSBjoern A. Zeeb int iwl_bios_get_ppag_table(struct iwl_fw_runtime *fwrt);
196*a4128aadSBjoern A. Zeeb 
197*a4128aadSBjoern A. Zeeb int iwl_bios_get_tas_table(struct iwl_fw_runtime *fwrt,
198*a4128aadSBjoern A. Zeeb 			   struct iwl_tas_data *data);
199*a4128aadSBjoern A. Zeeb 
200*a4128aadSBjoern A. Zeeb int iwl_bios_get_pwr_limit(struct iwl_fw_runtime *fwrt,
201*a4128aadSBjoern A. Zeeb 			   u64 *dflt_pwr_limit);
202*a4128aadSBjoern A. Zeeb 
203*a4128aadSBjoern A. Zeeb int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
204*a4128aadSBjoern A. Zeeb int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk);
205*a4128aadSBjoern A. Zeeb int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value);
206*a4128aadSBjoern A. Zeeb 
207*a4128aadSBjoern A. Zeeb int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
208*a4128aadSBjoern A. Zeeb 			 struct iwl_lari_config_change_cmd *cmd,
209*a4128aadSBjoern A. Zeeb 			 size_t *cmd_size);
210*a4128aadSBjoern A. Zeeb 
211*a4128aadSBjoern A. Zeeb int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
212*a4128aadSBjoern A. Zeeb 		     u32 *value);
213*a4128aadSBjoern A. Zeeb 
214*a4128aadSBjoern A. Zeeb static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
215*a4128aadSBjoern A. Zeeb 					  const u8 ppag_ver)
216*a4128aadSBjoern A. Zeeb {
217*a4128aadSBjoern A. Zeeb 	return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
218*a4128aadSBjoern A. Zeeb 					    IWL_PPAG_REV3_MASK);
219*a4128aadSBjoern A. Zeeb }
220*a4128aadSBjoern A. Zeeb #endif /* __fw_regulatory_h__ */
221