1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /*
3  * Copyright (C) 2017 Intel Deutschland GmbH
4  * Copyright (C) 2018-2021 Intel Corporation
5  */
6 #ifndef __iwl_fw_acpi__
7 #define __iwl_fw_acpi__
8 
9 #include <linux/acpi.h>
10 #include "fw/api/commands.h"
11 #include "fw/api/power.h"
12 #include "fw/api/phy.h"
13 #include "fw/api/nvm-reg.h"
14 #include "fw/img.h"
15 #include "iwl-trans.h"
16 
17 
18 #define ACPI_WRDS_METHOD	"WRDS"
19 #define ACPI_EWRD_METHOD	"EWRD"
20 #define ACPI_WGDS_METHOD	"WGDS"
21 #define ACPI_WRDD_METHOD	"WRDD"
22 #define ACPI_SPLC_METHOD	"SPLC"
23 #define ACPI_ECKV_METHOD	"ECKV"
24 #define ACPI_PPAG_METHOD	"PPAG"
25 #define ACPI_WTAS_METHOD	"WTAS"
26 
27 #define ACPI_WIFI_DOMAIN	(0x07)
28 
29 #define ACPI_SAR_PROFILE_NUM		4
30 
31 #define ACPI_NUM_GEO_PROFILES		3
32 #define ACPI_GEO_PER_CHAIN_SIZE		3
33 
34 #define ACPI_SAR_NUM_CHAINS_REV0	2
35 #define ACPI_SAR_NUM_CHAINS_REV1	2
36 #define ACPI_SAR_NUM_CHAINS_REV2	4
37 #define ACPI_SAR_NUM_SUB_BANDS_REV0	5
38 #define ACPI_SAR_NUM_SUB_BANDS_REV1	11
39 #define ACPI_SAR_NUM_SUB_BANDS_REV2	11
40 
41 #define ACPI_WRDS_WIFI_DATA_SIZE_REV0	(ACPI_SAR_NUM_CHAINS_REV0 * \
42 					 ACPI_SAR_NUM_SUB_BANDS_REV0 + 2)
43 #define ACPI_WRDS_WIFI_DATA_SIZE_REV1	(ACPI_SAR_NUM_CHAINS_REV1 * \
44 					 ACPI_SAR_NUM_SUB_BANDS_REV1 + 2)
45 #define ACPI_WRDS_WIFI_DATA_SIZE_REV2	(ACPI_SAR_NUM_CHAINS_REV2 * \
46 					 ACPI_SAR_NUM_SUB_BANDS_REV2 + 2)
47 #define ACPI_EWRD_WIFI_DATA_SIZE_REV0	((ACPI_SAR_PROFILE_NUM - 1) * \
48 					 ACPI_SAR_NUM_CHAINS_REV0 * \
49 					 ACPI_SAR_NUM_SUB_BANDS_REV0 + 3)
50 #define ACPI_EWRD_WIFI_DATA_SIZE_REV1	((ACPI_SAR_PROFILE_NUM - 1) * \
51 					 ACPI_SAR_NUM_CHAINS_REV1 * \
52 					 ACPI_SAR_NUM_SUB_BANDS_REV1 + 3)
53 #define ACPI_EWRD_WIFI_DATA_SIZE_REV2	((ACPI_SAR_PROFILE_NUM - 1) * \
54 					 ACPI_SAR_NUM_CHAINS_REV2 * \
55 					 ACPI_SAR_NUM_SUB_BANDS_REV2 + 3)
56 
57 /* revision 0 and 1 are identical, except for the semantics in the FW */
58 #define ACPI_GEO_NUM_BANDS_REV0		2
59 #define ACPI_GEO_NUM_BANDS_REV2		3
60 #define ACPI_GEO_NUM_CHAINS		2
61 
62 #define ACPI_WGDS_WIFI_DATA_SIZE_REV0	(ACPI_NUM_GEO_PROFILES *   \
63 					 ACPI_GEO_NUM_BANDS_REV0 * \
64 					 ACPI_GEO_PER_CHAIN_SIZE + 1)
65 #define ACPI_WGDS_WIFI_DATA_SIZE_REV2	(ACPI_NUM_GEO_PROFILES *   \
66 					 ACPI_GEO_NUM_BANDS_REV2 * \
67 					 ACPI_GEO_PER_CHAIN_SIZE + 1)
68 
69 #define ACPI_WRDD_WIFI_DATA_SIZE	2
70 #define ACPI_SPLC_WIFI_DATA_SIZE	2
71 #define ACPI_ECKV_WIFI_DATA_SIZE	2
72 
73 /*
74  * 1 type, 1 enabled, 1 block list size, 16 block list array
75  */
76 #define APCI_WTAS_BLACK_LIST_MAX	16
77 #define ACPI_WTAS_WIFI_DATA_SIZE	(3 + APCI_WTAS_BLACK_LIST_MAX)
78 
79 #define ACPI_PPAG_WIFI_DATA_SIZE_V1	((IWL_NUM_CHAIN_LIMITS * \
80 					  IWL_NUM_SUB_BANDS_V1) + 2)
81 #define ACPI_PPAG_WIFI_DATA_SIZE_V2	((IWL_NUM_CHAIN_LIMITS * \
82 					  IWL_NUM_SUB_BANDS_V2) + 2)
83 
84 /* PPAG gain value bounds in 1/8 dBm */
85 #define ACPI_PPAG_MIN_LB -16
86 #define ACPI_PPAG_MAX_LB 24
87 #define ACPI_PPAG_MIN_HB -16
88 #define ACPI_PPAG_MAX_HB 40
89 
90 /*
91  * The profile for revision 2 is a superset of revision 1, which is in
92  * turn a superset of revision 0.  So we can store all revisions
93  * inside revision 2, which is what we represent here.
94  */
95 struct iwl_sar_profile_chain {
96 	u8 subbands[ACPI_SAR_NUM_SUB_BANDS_REV2];
97 };
98 
99 struct iwl_sar_profile {
100 	bool enabled;
101 	struct iwl_sar_profile_chain chains[ACPI_SAR_NUM_CHAINS_REV2];
102 };
103 
104 /* Same thing as with SAR, all revisions fit in revision 2 */
105 struct iwl_geo_profile_band {
106 	u8 max;
107 	u8 chains[ACPI_GEO_NUM_CHAINS];
108 };
109 
110 struct iwl_geo_profile {
111 	struct iwl_geo_profile_band bands[ACPI_GEO_NUM_BANDS_REV2];
112 };
113 
114 enum iwl_dsm_funcs_rev_0 {
115 	DSM_FUNC_QUERY = 0,
116 	DSM_FUNC_DISABLE_SRD = 1,
117 	DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
118 	DSM_FUNC_11AX_ENABLEMENT = 6,
119 	DSM_FUNC_ENABLE_UNII4_CHAN = 7
120 };
121 
122 enum iwl_dsm_values_srd {
123 	DSM_VALUE_SRD_ACTIVE,
124 	DSM_VALUE_SRD_PASSIVE,
125 	DSM_VALUE_SRD_DISABLE,
126 	DSM_VALUE_SRD_MAX
127 };
128 
129 enum iwl_dsm_values_indonesia {
130 	DSM_VALUE_INDONESIA_DISABLE,
131 	DSM_VALUE_INDONESIA_ENABLE,
132 	DSM_VALUE_INDONESIA_RESERVED,
133 	DSM_VALUE_INDONESIA_MAX
134 };
135 
136 /* DSM RFI uses a different GUID, so need separate definitions */
137 
138 #define DSM_RFI_FUNC_ENABLE 3
139 
140 enum iwl_dsm_values_rfi {
141 	DSM_VALUE_RFI_ENABLE,
142 	DSM_VALUE_RFI_DISABLE,
143 	DSM_VALUE_RFI_MAX
144 };
145 
146 #ifdef CONFIG_ACPI
147 
148 struct iwl_fw_runtime;
149 
150 extern const guid_t iwl_guid;
151 extern const guid_t iwl_rfi_guid;
152 
153 void *iwl_acpi_get_object(struct device *dev, acpi_string method);
154 
155 int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func,
156 			const guid_t *guid, u8 *value);
157 
158 int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
159 			 const guid_t *guid, u32 *value);
160 
161 union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
162 					 union acpi_object *data,
163 					 int data_size, int *tbl_rev);
164 
165 /**
166  * iwl_acpi_get_mcc - read MCC from ACPI, if available
167  *
168  * @dev: the struct device
169  * @mcc: output buffer (3 bytes) that will get the MCC
170  *
171  * This function tries to read the current MCC from ACPI if available.
172  */
173 int iwl_acpi_get_mcc(struct device *dev, char *mcc);
174 
175 u64 iwl_acpi_get_pwr_limit(struct device *dev);
176 
177 /*
178  * iwl_acpi_get_eckv - read external clock validation from ACPI, if available
179  *
180  * @dev: the struct device
181  * @extl_clk: output var (2 bytes) that will get the clk indication.
182  *
183  * This function tries to read the external clock indication
184  * from ACPI if available.
185  */
186 int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk);
187 
188 int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt,
189 			   __le16 *per_chain, u32 n_tables, u32 n_subbands,
190 			   int prof_a, int prof_b);
191 
192 int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt);
193 
194 int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt);
195 
196 int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt);
197 
198 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
199 
200 int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
201 		     struct iwl_per_chain_offset *table, u32 n_bands);
202 
203 int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array,
204 		     int *block_list_size);
205 
206 __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
207 
208 #else /* CONFIG_ACPI */
209 
210 static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method)
211 {
212 	return ERR_PTR(-ENOENT);
213 }
214 
215 static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev,
216 					    int func, union acpi_object *args)
217 {
218 	return ERR_PTR(-ENOENT);
219 }
220 
221 static inline int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func,
222 				      const guid_t *guid, u8 *value)
223 {
224 	return -ENOENT;
225 }
226 
227 static inline int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
228 				       const guid_t *guid, u32 *value)
229 {
230 	return -ENOENT;
231 }
232 
233 static inline union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
234 						       union acpi_object *data,
235 						       int data_size,
236 						       int *tbl_rev)
237 {
238 	return ERR_PTR(-ENOENT);
239 }
240 
241 static inline int iwl_acpi_get_mcc(struct device *dev, char *mcc)
242 {
243 	return -ENOENT;
244 }
245 
246 static inline u64 iwl_acpi_get_pwr_limit(struct device *dev)
247 {
248 	return 0;
249 }
250 
251 static inline int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk)
252 {
253 	return -ENOENT;
254 }
255 
256 static inline int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt,
257 			   __le16 *per_chain, u32 n_tables, u32 n_subbands,
258 			   int prof_a, int prof_b)
259 {
260 	return -ENOENT;
261 }
262 
263 static inline int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt)
264 {
265 	return -ENOENT;
266 }
267 
268 static inline int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
269 {
270 	return -ENOENT;
271 }
272 
273 static inline int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
274 {
275 	return 1;
276 }
277 
278 static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
279 {
280 	return false;
281 }
282 
283 static inline int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
284 				   __le32 *block_list_array,
285 				   int *block_list_size)
286 {
287 	return -ENOENT;
288 }
289 
290 static inline __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
291 {
292 	return 0;
293 }
294 
295 #endif /* CONFIG_ACPI */
296 #endif /* __iwl_fw_acpi__ */
297