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
iwl_acpi_get_object(struct device * dev,acpi_string method)210 static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method)
211 {
212 return ERR_PTR(-ENOENT);
213 }
214
iwl_acpi_get_dsm_object(struct device * dev,int rev,int func,union acpi_object * args)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
iwl_acpi_get_dsm_u8(struct device * dev,int rev,int func,const guid_t * guid,u8 * value)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
iwl_acpi_get_dsm_u32(struct device * dev,int rev,int func,const guid_t * guid,u32 * value)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
iwl_acpi_get_wifi_pkg(struct device * dev,union acpi_object * data,int data_size,int * tbl_rev)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
iwl_acpi_get_mcc(struct device * dev,char * mcc)241 static inline int iwl_acpi_get_mcc(struct device *dev, char *mcc)
242 {
243 return -ENOENT;
244 }
245
iwl_acpi_get_pwr_limit(struct device * dev)246 static inline u64 iwl_acpi_get_pwr_limit(struct device *dev)
247 {
248 return 0;
249 }
250
iwl_acpi_get_eckv(struct device * dev,u32 * extl_clk)251 static inline int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk)
252 {
253 return -ENOENT;
254 }
255
iwl_sar_select_profile(struct iwl_fw_runtime * fwrt,__le16 * per_chain,u32 n_tables,u32 n_subbands,int prof_a,int prof_b)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
iwl_sar_get_wrds_table(struct iwl_fw_runtime * fwrt)263 static inline int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt)
264 {
265 return -ENOENT;
266 }
267
iwl_sar_get_ewrd_table(struct iwl_fw_runtime * fwrt)268 static inline int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
269 {
270 return -ENOENT;
271 }
272
iwl_sar_get_wgds_table(struct iwl_fw_runtime * fwrt)273 static inline int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
274 {
275 return 1;
276 }
277
iwl_sar_geo_support(struct iwl_fw_runtime * fwrt)278 static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
279 {
280 return false;
281 }
282
iwl_acpi_get_tas(struct iwl_fw_runtime * fwrt,__le32 * block_list_array,int * block_list_size)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
iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime * fwrt)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