xref: /freebsd/sys/contrib/dev/athk/ath12k/acpi.c (revision a96550206e4bde15bf615ff2127b80404a7ec41f)
1*a9655020SBjoern A. Zeeb // SPDX-License-Identifier: BSD-3-Clause-Clear
2*a9655020SBjoern A. Zeeb /*
3*a9655020SBjoern A. Zeeb  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4*a9655020SBjoern A. Zeeb  * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
5*a9655020SBjoern A. Zeeb  */
6*a9655020SBjoern A. Zeeb 
7*a9655020SBjoern A. Zeeb #include "core.h"
8*a9655020SBjoern A. Zeeb #include "acpi.h"
9*a9655020SBjoern A. Zeeb #include "debug.h"
10*a9655020SBjoern A. Zeeb 
ath12k_acpi_dsm_get_data(struct ath12k_base * ab,int func)11*a9655020SBjoern A. Zeeb static int ath12k_acpi_dsm_get_data(struct ath12k_base *ab, int func)
12*a9655020SBjoern A. Zeeb {
13*a9655020SBjoern A. Zeeb 	union acpi_object *obj;
14*a9655020SBjoern A. Zeeb 	acpi_handle root_handle;
15*a9655020SBjoern A. Zeeb 	int ret, i;
16*a9655020SBjoern A. Zeeb 
17*a9655020SBjoern A. Zeeb 	root_handle = ACPI_HANDLE(ab->dev);
18*a9655020SBjoern A. Zeeb 	if (!root_handle) {
19*a9655020SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_BOOT, "invalid acpi handler\n");
20*a9655020SBjoern A. Zeeb 		return -EOPNOTSUPP;
21*a9655020SBjoern A. Zeeb 	}
22*a9655020SBjoern A. Zeeb 
23*a9655020SBjoern A. Zeeb 	obj = acpi_evaluate_dsm(root_handle, ab->hw_params->acpi_guid, 0, func,
24*a9655020SBjoern A. Zeeb 				NULL);
25*a9655020SBjoern A. Zeeb 
26*a9655020SBjoern A. Zeeb 	if (!obj) {
27*a9655020SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi_evaluate_dsm() failed\n");
28*a9655020SBjoern A. Zeeb 		return -ENOENT;
29*a9655020SBjoern A. Zeeb 	}
30*a9655020SBjoern A. Zeeb 
31*a9655020SBjoern A. Zeeb 	if (obj->type == ACPI_TYPE_INTEGER) {
32*a9655020SBjoern A. Zeeb 		switch (func) {
33*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS:
34*a9655020SBjoern A. Zeeb 			ab->acpi.func_bit = obj->integer.value;
35*a9655020SBjoern A. Zeeb 			break;
36*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_DISABLE_FLAG:
37*a9655020SBjoern A. Zeeb 			ab->acpi.bit_flag = obj->integer.value;
38*a9655020SBjoern A. Zeeb 			break;
39*a9655020SBjoern A. Zeeb 		}
40*a9655020SBjoern A. Zeeb 	} else if (obj->type == ACPI_TYPE_STRING) {
41*a9655020SBjoern A. Zeeb 		switch (func) {
42*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_BDF_EXT:
43*a9655020SBjoern A. Zeeb 			if (obj->string.length <= ATH12K_ACPI_BDF_ANCHOR_STRING_LEN ||
44*a9655020SBjoern A. Zeeb 			    obj->string.length > ATH12K_ACPI_BDF_MAX_LEN ||
45*a9655020SBjoern A. Zeeb 			    memcmp(obj->string.pointer, ATH12K_ACPI_BDF_ANCHOR_STRING,
46*a9655020SBjoern A. Zeeb 				   ATH12K_ACPI_BDF_ANCHOR_STRING_LEN)) {
47*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI DSM BDF size: %d\n",
48*a9655020SBjoern A. Zeeb 					    obj->string.length);
49*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
50*a9655020SBjoern A. Zeeb 				goto out;
51*a9655020SBjoern A. Zeeb 			}
52*a9655020SBjoern A. Zeeb 
53*a9655020SBjoern A. Zeeb 			memcpy(ab->acpi.bdf_string, obj->string.pointer,
54*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
55*a9655020SBjoern A. Zeeb 
56*a9655020SBjoern A. Zeeb 			break;
57*a9655020SBjoern A. Zeeb 		}
58*a9655020SBjoern A. Zeeb 	} else if (obj->type == ACPI_TYPE_BUFFER) {
59*a9655020SBjoern A. Zeeb 		switch (func) {
60*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS:
61*a9655020SBjoern A. Zeeb 			if (obj->buffer.length < ATH12K_ACPI_DSM_FUNC_MIN_BITMAP_SIZE ||
62*a9655020SBjoern A. Zeeb 			    obj->buffer.length > ATH12K_ACPI_DSM_FUNC_MAX_BITMAP_SIZE) {
63*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI DSM func size: %d\n",
64*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
65*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
66*a9655020SBjoern A. Zeeb 				goto out;
67*a9655020SBjoern A. Zeeb 			}
68*a9655020SBjoern A. Zeeb 
69*a9655020SBjoern A. Zeeb 			ab->acpi.func_bit = 0;
70*a9655020SBjoern A. Zeeb 			for (i = 0; i < obj->buffer.length; i++)
71*a9655020SBjoern A. Zeeb 				ab->acpi.func_bit += obj->buffer.pointer[i] << (i * 8);
72*a9655020SBjoern A. Zeeb 
73*a9655020SBjoern A. Zeeb 			break;
74*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_TAS_CFG:
75*a9655020SBjoern A. Zeeb 			if (obj->buffer.length != ATH12K_ACPI_DSM_TAS_CFG_SIZE) {
76*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI DSM TAS config size: %d\n",
77*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
78*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
79*a9655020SBjoern A. Zeeb 				goto out;
80*a9655020SBjoern A. Zeeb 			}
81*a9655020SBjoern A. Zeeb 
82*a9655020SBjoern A. Zeeb 			memcpy(&ab->acpi.tas_cfg, obj->buffer.pointer,
83*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
84*a9655020SBjoern A. Zeeb 
85*a9655020SBjoern A. Zeeb 			break;
86*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_TAS_DATA:
87*a9655020SBjoern A. Zeeb 			if (obj->buffer.length != ATH12K_ACPI_DSM_TAS_DATA_SIZE) {
88*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI DSM TAS data size: %d\n",
89*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
90*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
91*a9655020SBjoern A. Zeeb 				goto out;
92*a9655020SBjoern A. Zeeb 			}
93*a9655020SBjoern A. Zeeb 
94*a9655020SBjoern A. Zeeb 			memcpy(&ab->acpi.tas_sar_power_table, obj->buffer.pointer,
95*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
96*a9655020SBjoern A. Zeeb 
97*a9655020SBjoern A. Zeeb 			break;
98*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_BIOS_SAR:
99*a9655020SBjoern A. Zeeb 			if (obj->buffer.length != ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE) {
100*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI BIOS SAR data size: %d\n",
101*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
102*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
103*a9655020SBjoern A. Zeeb 				goto out;
104*a9655020SBjoern A. Zeeb 			}
105*a9655020SBjoern A. Zeeb 
106*a9655020SBjoern A. Zeeb 			memcpy(&ab->acpi.bios_sar_data, obj->buffer.pointer,
107*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
108*a9655020SBjoern A. Zeeb 
109*a9655020SBjoern A. Zeeb 			break;
110*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_GEO_OFFSET:
111*a9655020SBjoern A. Zeeb 			if (obj->buffer.length != ATH12K_ACPI_DSM_GEO_OFFSET_DATA_SIZE) {
112*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI GEO OFFSET data size: %d\n",
113*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
114*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
115*a9655020SBjoern A. Zeeb 				goto out;
116*a9655020SBjoern A. Zeeb 			}
117*a9655020SBjoern A. Zeeb 
118*a9655020SBjoern A. Zeeb 			memcpy(&ab->acpi.geo_offset_data, obj->buffer.pointer,
119*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
120*a9655020SBjoern A. Zeeb 
121*a9655020SBjoern A. Zeeb 			break;
122*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_INDEX_CCA:
123*a9655020SBjoern A. Zeeb 			if (obj->buffer.length != ATH12K_ACPI_DSM_CCA_DATA_SIZE) {
124*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI DSM CCA data size: %d\n",
125*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
126*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
127*a9655020SBjoern A. Zeeb 				goto out;
128*a9655020SBjoern A. Zeeb 			}
129*a9655020SBjoern A. Zeeb 
130*a9655020SBjoern A. Zeeb 			memcpy(&ab->acpi.cca_data, obj->buffer.pointer,
131*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
132*a9655020SBjoern A. Zeeb 
133*a9655020SBjoern A. Zeeb 			break;
134*a9655020SBjoern A. Zeeb 		case ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE:
135*a9655020SBjoern A. Zeeb 			if (obj->buffer.length != ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE) {
136*a9655020SBjoern A. Zeeb 				ath12k_warn(ab, "invalid ACPI DSM band edge data size: %d\n",
137*a9655020SBjoern A. Zeeb 					    obj->buffer.length);
138*a9655020SBjoern A. Zeeb 				ret = -EINVAL;
139*a9655020SBjoern A. Zeeb 				goto out;
140*a9655020SBjoern A. Zeeb 			}
141*a9655020SBjoern A. Zeeb 
142*a9655020SBjoern A. Zeeb 			memcpy(&ab->acpi.band_edge_power, obj->buffer.pointer,
143*a9655020SBjoern A. Zeeb 			       obj->buffer.length);
144*a9655020SBjoern A. Zeeb 
145*a9655020SBjoern A. Zeeb 			break;
146*a9655020SBjoern A. Zeeb 		}
147*a9655020SBjoern A. Zeeb 	} else {
148*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "ACPI DSM method returned an unsupported object type: %d\n",
149*a9655020SBjoern A. Zeeb 			    obj->type);
150*a9655020SBjoern A. Zeeb 		ret = -EINVAL;
151*a9655020SBjoern A. Zeeb 		goto out;
152*a9655020SBjoern A. Zeeb 	}
153*a9655020SBjoern A. Zeeb 
154*a9655020SBjoern A. Zeeb 	ret = 0;
155*a9655020SBjoern A. Zeeb 
156*a9655020SBjoern A. Zeeb out:
157*a9655020SBjoern A. Zeeb 	ACPI_FREE(obj);
158*a9655020SBjoern A. Zeeb 	return ret;
159*a9655020SBjoern A. Zeeb }
160*a9655020SBjoern A. Zeeb 
ath12k_acpi_set_power_limit(struct ath12k_base * ab)161*a9655020SBjoern A. Zeeb static int ath12k_acpi_set_power_limit(struct ath12k_base *ab)
162*a9655020SBjoern A. Zeeb {
163*a9655020SBjoern A. Zeeb 	const u8 *tas_sar_power_table = ab->acpi.tas_sar_power_table;
164*a9655020SBjoern A. Zeeb 	int ret;
165*a9655020SBjoern A. Zeeb 
166*a9655020SBjoern A. Zeeb 	if (tas_sar_power_table[0] != ATH12K_ACPI_TAS_DATA_VERSION ||
167*a9655020SBjoern A. Zeeb 	    tas_sar_power_table[1] != ATH12K_ACPI_TAS_DATA_ENABLE) {
168*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "latest ACPI TAS data is invalid\n");
169*a9655020SBjoern A. Zeeb 		return -EINVAL;
170*a9655020SBjoern A. Zeeb 	}
171*a9655020SBjoern A. Zeeb 
172*a9655020SBjoern A. Zeeb 	ret = ath12k_wmi_set_bios_cmd(ab, WMI_BIOS_PARAM_TAS_DATA_TYPE,
173*a9655020SBjoern A. Zeeb 				      tas_sar_power_table,
174*a9655020SBjoern A. Zeeb 				      ATH12K_ACPI_DSM_TAS_DATA_SIZE);
175*a9655020SBjoern A. Zeeb 	if (ret) {
176*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to send ACPI TAS data table: %d\n", ret);
177*a9655020SBjoern A. Zeeb 		return ret;
178*a9655020SBjoern A. Zeeb 	}
179*a9655020SBjoern A. Zeeb 
180*a9655020SBjoern A. Zeeb 	return ret;
181*a9655020SBjoern A. Zeeb }
182*a9655020SBjoern A. Zeeb 
ath12k_acpi_set_bios_sar_power(struct ath12k_base * ab)183*a9655020SBjoern A. Zeeb static int ath12k_acpi_set_bios_sar_power(struct ath12k_base *ab)
184*a9655020SBjoern A. Zeeb {
185*a9655020SBjoern A. Zeeb 	int ret;
186*a9655020SBjoern A. Zeeb 
187*a9655020SBjoern A. Zeeb 	if (ab->acpi.bios_sar_data[0] != ATH12K_ACPI_POWER_LIMIT_VERSION ||
188*a9655020SBjoern A. Zeeb 	    ab->acpi.bios_sar_data[1] != ATH12K_ACPI_POWER_LIMIT_ENABLE_FLAG) {
189*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "invalid latest ACPI BIOS SAR data\n");
190*a9655020SBjoern A. Zeeb 		return -EINVAL;
191*a9655020SBjoern A. Zeeb 	}
192*a9655020SBjoern A. Zeeb 
193*a9655020SBjoern A. Zeeb 	ret = ath12k_wmi_set_bios_sar_cmd(ab, ab->acpi.bios_sar_data);
194*a9655020SBjoern A. Zeeb 	if (ret) {
195*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to set ACPI BIOS SAR table: %d\n", ret);
196*a9655020SBjoern A. Zeeb 		return ret;
197*a9655020SBjoern A. Zeeb 	}
198*a9655020SBjoern A. Zeeb 
199*a9655020SBjoern A. Zeeb 	return 0;
200*a9655020SBjoern A. Zeeb }
201*a9655020SBjoern A. Zeeb 
ath12k_acpi_dsm_notify(acpi_handle handle,u32 event,void * data)202*a9655020SBjoern A. Zeeb static void ath12k_acpi_dsm_notify(acpi_handle handle, u32 event, void *data)
203*a9655020SBjoern A. Zeeb {
204*a9655020SBjoern A. Zeeb 	int ret;
205*a9655020SBjoern A. Zeeb 	struct ath12k_base *ab = data;
206*a9655020SBjoern A. Zeeb 
207*a9655020SBjoern A. Zeeb 	if (event == ATH12K_ACPI_NOTIFY_EVENT) {
208*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "unknown acpi notify %u\n", event);
209*a9655020SBjoern A. Zeeb 		return;
210*a9655020SBjoern A. Zeeb 	}
211*a9655020SBjoern A. Zeeb 
212*a9655020SBjoern A. Zeeb 	if (!ab->acpi.acpi_tas_enable) {
213*a9655020SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi_tas_enable is false\n");
214*a9655020SBjoern A. Zeeb 		return;
215*a9655020SBjoern A. Zeeb 	}
216*a9655020SBjoern A. Zeeb 
217*a9655020SBjoern A. Zeeb 	ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_DATA);
218*a9655020SBjoern A. Zeeb 	if (ret) {
219*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to update ACPI TAS data table: %d\n", ret);
220*a9655020SBjoern A. Zeeb 		return;
221*a9655020SBjoern A. Zeeb 	}
222*a9655020SBjoern A. Zeeb 
223*a9655020SBjoern A. Zeeb 	ret = ath12k_acpi_set_power_limit(ab);
224*a9655020SBjoern A. Zeeb 	if (ret) {
225*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to set ACPI TAS power limit data: %d", ret);
226*a9655020SBjoern A. Zeeb 		return;
227*a9655020SBjoern A. Zeeb 	}
228*a9655020SBjoern A. Zeeb 
229*a9655020SBjoern A. Zeeb 	if (!ab->acpi.acpi_bios_sar_enable)
230*a9655020SBjoern A. Zeeb 		return;
231*a9655020SBjoern A. Zeeb 
232*a9655020SBjoern A. Zeeb 	ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BIOS_SAR);
233*a9655020SBjoern A. Zeeb 	if (ret) {
234*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to update BIOS SAR: %d\n", ret);
235*a9655020SBjoern A. Zeeb 		return;
236*a9655020SBjoern A. Zeeb 	}
237*a9655020SBjoern A. Zeeb 
238*a9655020SBjoern A. Zeeb 	ret = ath12k_acpi_set_bios_sar_power(ab);
239*a9655020SBjoern A. Zeeb 	if (ret) {
240*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to set BIOS SAR power limit: %d\n", ret);
241*a9655020SBjoern A. Zeeb 		return;
242*a9655020SBjoern A. Zeeb 	}
243*a9655020SBjoern A. Zeeb }
244*a9655020SBjoern A. Zeeb 
ath12k_acpi_set_bios_sar_params(struct ath12k_base * ab)245*a9655020SBjoern A. Zeeb static int ath12k_acpi_set_bios_sar_params(struct ath12k_base *ab)
246*a9655020SBjoern A. Zeeb {
247*a9655020SBjoern A. Zeeb 	int ret;
248*a9655020SBjoern A. Zeeb 
249*a9655020SBjoern A. Zeeb 	ret = ath12k_wmi_set_bios_sar_cmd(ab, ab->acpi.bios_sar_data);
250*a9655020SBjoern A. Zeeb 	if (ret) {
251*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to set ACPI BIOS SAR table: %d\n", ret);
252*a9655020SBjoern A. Zeeb 		return ret;
253*a9655020SBjoern A. Zeeb 	}
254*a9655020SBjoern A. Zeeb 
255*a9655020SBjoern A. Zeeb 	ret = ath12k_wmi_set_bios_geo_cmd(ab, ab->acpi.geo_offset_data);
256*a9655020SBjoern A. Zeeb 	if (ret) {
257*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to set ACPI BIOS GEO table: %d\n", ret);
258*a9655020SBjoern A. Zeeb 		return ret;
259*a9655020SBjoern A. Zeeb 	}
260*a9655020SBjoern A. Zeeb 
261*a9655020SBjoern A. Zeeb 	return 0;
262*a9655020SBjoern A. Zeeb }
263*a9655020SBjoern A. Zeeb 
ath12k_acpi_set_tas_params(struct ath12k_base * ab)264*a9655020SBjoern A. Zeeb static int ath12k_acpi_set_tas_params(struct ath12k_base *ab)
265*a9655020SBjoern A. Zeeb {
266*a9655020SBjoern A. Zeeb 	int ret;
267*a9655020SBjoern A. Zeeb 
268*a9655020SBjoern A. Zeeb 	ret = ath12k_wmi_set_bios_cmd(ab, WMI_BIOS_PARAM_TAS_CONFIG_TYPE,
269*a9655020SBjoern A. Zeeb 				      ab->acpi.tas_cfg,
270*a9655020SBjoern A. Zeeb 				      ATH12K_ACPI_DSM_TAS_CFG_SIZE);
271*a9655020SBjoern A. Zeeb 	if (ret) {
272*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to send ACPI TAS config table parameter: %d\n",
273*a9655020SBjoern A. Zeeb 			    ret);
274*a9655020SBjoern A. Zeeb 		return ret;
275*a9655020SBjoern A. Zeeb 	}
276*a9655020SBjoern A. Zeeb 
277*a9655020SBjoern A. Zeeb 	ret = ath12k_wmi_set_bios_cmd(ab, WMI_BIOS_PARAM_TAS_DATA_TYPE,
278*a9655020SBjoern A. Zeeb 				      ab->acpi.tas_sar_power_table,
279*a9655020SBjoern A. Zeeb 				      ATH12K_ACPI_DSM_TAS_DATA_SIZE);
280*a9655020SBjoern A. Zeeb 	if (ret) {
281*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to send ACPI TAS data table parameter: %d\n",
282*a9655020SBjoern A. Zeeb 			    ret);
283*a9655020SBjoern A. Zeeb 		return ret;
284*a9655020SBjoern A. Zeeb 	}
285*a9655020SBjoern A. Zeeb 
286*a9655020SBjoern A. Zeeb 	return 0;
287*a9655020SBjoern A. Zeeb }
288*a9655020SBjoern A. Zeeb 
ath12k_acpi_get_disable_rfkill(struct ath12k_base * ab)289*a9655020SBjoern A. Zeeb bool ath12k_acpi_get_disable_rfkill(struct ath12k_base *ab)
290*a9655020SBjoern A. Zeeb {
291*a9655020SBjoern A. Zeeb 	return ab->acpi.acpi_disable_rfkill;
292*a9655020SBjoern A. Zeeb }
293*a9655020SBjoern A. Zeeb 
ath12k_acpi_get_disable_11be(struct ath12k_base * ab)294*a9655020SBjoern A. Zeeb bool ath12k_acpi_get_disable_11be(struct ath12k_base *ab)
295*a9655020SBjoern A. Zeeb {
296*a9655020SBjoern A. Zeeb 	return ab->acpi.acpi_disable_11be;
297*a9655020SBjoern A. Zeeb }
298*a9655020SBjoern A. Zeeb 
ath12k_acpi_set_dsm_func(struct ath12k_base * ab)299*a9655020SBjoern A. Zeeb void ath12k_acpi_set_dsm_func(struct ath12k_base *ab)
300*a9655020SBjoern A. Zeeb {
301*a9655020SBjoern A. Zeeb 	int ret;
302*a9655020SBjoern A. Zeeb 	u8 *buf;
303*a9655020SBjoern A. Zeeb 
304*a9655020SBjoern A. Zeeb 	if (!ab->hw_params->acpi_guid)
305*a9655020SBjoern A. Zeeb 		/* not supported with this hardware */
306*a9655020SBjoern A. Zeeb 		return;
307*a9655020SBjoern A. Zeeb 
308*a9655020SBjoern A. Zeeb 	if (ab->acpi.acpi_tas_enable) {
309*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_set_tas_params(ab);
310*a9655020SBjoern A. Zeeb 		if (ret) {
311*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to send ACPI TAS parameters: %d\n", ret);
312*a9655020SBjoern A. Zeeb 			return;
313*a9655020SBjoern A. Zeeb 		}
314*a9655020SBjoern A. Zeeb 	}
315*a9655020SBjoern A. Zeeb 
316*a9655020SBjoern A. Zeeb 	if (ab->acpi.acpi_bios_sar_enable) {
317*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_set_bios_sar_params(ab);
318*a9655020SBjoern A. Zeeb 		if (ret) {
319*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to send ACPI BIOS SAR: %d\n", ret);
320*a9655020SBjoern A. Zeeb 			return;
321*a9655020SBjoern A. Zeeb 		}
322*a9655020SBjoern A. Zeeb 	}
323*a9655020SBjoern A. Zeeb 
324*a9655020SBjoern A. Zeeb 	if (ab->acpi.acpi_cca_enable) {
325*a9655020SBjoern A. Zeeb 		buf = ab->acpi.cca_data + ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET;
326*a9655020SBjoern A. Zeeb 		ret = ath12k_wmi_set_bios_cmd(ab,
327*a9655020SBjoern A. Zeeb 					      WMI_BIOS_PARAM_CCA_THRESHOLD_TYPE,
328*a9655020SBjoern A. Zeeb 					      buf,
329*a9655020SBjoern A. Zeeb 					      ATH12K_ACPI_CCA_THR_OFFSET_LEN);
330*a9655020SBjoern A. Zeeb 		if (ret) {
331*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to set ACPI DSM CCA threshold: %d\n",
332*a9655020SBjoern A. Zeeb 				    ret);
333*a9655020SBjoern A. Zeeb 			return;
334*a9655020SBjoern A. Zeeb 		}
335*a9655020SBjoern A. Zeeb 	}
336*a9655020SBjoern A. Zeeb 
337*a9655020SBjoern A. Zeeb 	if (ab->acpi.acpi_band_edge_enable) {
338*a9655020SBjoern A. Zeeb 		ret = ath12k_wmi_set_bios_cmd(ab,
339*a9655020SBjoern A. Zeeb 					      WMI_BIOS_PARAM_TYPE_BANDEDGE,
340*a9655020SBjoern A. Zeeb 					      ab->acpi.band_edge_power,
341*a9655020SBjoern A. Zeeb 					      sizeof(ab->acpi.band_edge_power));
342*a9655020SBjoern A. Zeeb 		if (ret) {
343*a9655020SBjoern A. Zeeb 			ath12k_warn(ab,
344*a9655020SBjoern A. Zeeb 				    "failed to set ACPI DSM band edge channel power: %d\n",
345*a9655020SBjoern A. Zeeb 				    ret);
346*a9655020SBjoern A. Zeeb 			return;
347*a9655020SBjoern A. Zeeb 		}
348*a9655020SBjoern A. Zeeb 	}
349*a9655020SBjoern A. Zeeb }
350*a9655020SBjoern A. Zeeb 
ath12k_acpi_start(struct ath12k_base * ab)351*a9655020SBjoern A. Zeeb int ath12k_acpi_start(struct ath12k_base *ab)
352*a9655020SBjoern A. Zeeb {
353*a9655020SBjoern A. Zeeb 	acpi_status status;
354*a9655020SBjoern A. Zeeb 	int ret;
355*a9655020SBjoern A. Zeeb 
356*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_tas_enable = false;
357*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_disable_11be = false;
358*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_disable_rfkill = false;
359*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_bios_sar_enable = false;
360*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_cca_enable = false;
361*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_band_edge_enable = false;
362*a9655020SBjoern A. Zeeb 	ab->acpi.acpi_enable_bdf = false;
363*a9655020SBjoern A. Zeeb 	ab->acpi.bdf_string[0] = '\0';
364*a9655020SBjoern A. Zeeb 
365*a9655020SBjoern A. Zeeb 	if (!ab->hw_params->acpi_guid)
366*a9655020SBjoern A. Zeeb 		/* not supported with this hardware */
367*a9655020SBjoern A. Zeeb 		return 0;
368*a9655020SBjoern A. Zeeb 
369*a9655020SBjoern A. Zeeb 	ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS);
370*a9655020SBjoern A. Zeeb 	if (ret) {
371*a9655020SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_BOOT, "failed to get ACPI DSM data: %d\n", ret);
372*a9655020SBjoern A. Zeeb 		return ret;
373*a9655020SBjoern A. Zeeb 	}
374*a9655020SBjoern A. Zeeb 
375*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_DISABLE_FLAG)) {
376*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_DISABLE_FLAG);
377*a9655020SBjoern A. Zeeb 		if (ret) {
378*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI DISABLE FLAG: %d\n", ret);
379*a9655020SBjoern A. Zeeb 			return ret;
380*a9655020SBjoern A. Zeeb 		}
381*a9655020SBjoern A. Zeeb 
382*a9655020SBjoern A. Zeeb 		if (ATH12K_ACPI_CHEK_BIT_VALID(ab->acpi,
383*a9655020SBjoern A. Zeeb 					       ATH12K_ACPI_DSM_DISABLE_11BE_BIT))
384*a9655020SBjoern A. Zeeb 			ab->acpi.acpi_disable_11be = true;
385*a9655020SBjoern A. Zeeb 
386*a9655020SBjoern A. Zeeb 		if (!ATH12K_ACPI_CHEK_BIT_VALID(ab->acpi,
387*a9655020SBjoern A. Zeeb 						ATH12K_ACPI_DSM_DISABLE_RFKILL_BIT))
388*a9655020SBjoern A. Zeeb 			ab->acpi.acpi_disable_rfkill = true;
389*a9655020SBjoern A. Zeeb 	}
390*a9655020SBjoern A. Zeeb 
391*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BDF_EXT)) {
392*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BDF_EXT);
393*a9655020SBjoern A. Zeeb 		if (ret || ab->acpi.bdf_string[0] == '\0') {
394*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI BDF EXT: %d\n", ret);
395*a9655020SBjoern A. Zeeb 			return ret;
396*a9655020SBjoern A. Zeeb 		}
397*a9655020SBjoern A. Zeeb 
398*a9655020SBjoern A. Zeeb 		ab->acpi.acpi_enable_bdf = true;
399*a9655020SBjoern A. Zeeb 	}
400*a9655020SBjoern A. Zeeb 
401*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_CFG)) {
402*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_CFG);
403*a9655020SBjoern A. Zeeb 		if (ret) {
404*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI TAS config table: %d\n", ret);
405*a9655020SBjoern A. Zeeb 			return ret;
406*a9655020SBjoern A. Zeeb 		}
407*a9655020SBjoern A. Zeeb 	}
408*a9655020SBjoern A. Zeeb 
409*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_DATA)) {
410*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_DATA);
411*a9655020SBjoern A. Zeeb 		if (ret) {
412*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI TAS data table: %d\n", ret);
413*a9655020SBjoern A. Zeeb 			return ret;
414*a9655020SBjoern A. Zeeb 		}
415*a9655020SBjoern A. Zeeb 
416*a9655020SBjoern A. Zeeb 		if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_CFG) &&
417*a9655020SBjoern A. Zeeb 		    ab->acpi.tas_sar_power_table[0] == ATH12K_ACPI_TAS_DATA_VERSION &&
418*a9655020SBjoern A. Zeeb 		    ab->acpi.tas_sar_power_table[1] == ATH12K_ACPI_TAS_DATA_ENABLE)
419*a9655020SBjoern A. Zeeb 			ab->acpi.acpi_tas_enable = true;
420*a9655020SBjoern A. Zeeb 	}
421*a9655020SBjoern A. Zeeb 
422*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BIOS_SAR)) {
423*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BIOS_SAR);
424*a9655020SBjoern A. Zeeb 		if (ret) {
425*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI bios sar data: %d\n", ret);
426*a9655020SBjoern A. Zeeb 			return ret;
427*a9655020SBjoern A. Zeeb 		}
428*a9655020SBjoern A. Zeeb 	}
429*a9655020SBjoern A. Zeeb 
430*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_GEO_OFFSET)) {
431*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_GEO_OFFSET);
432*a9655020SBjoern A. Zeeb 		if (ret) {
433*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI geo offset data: %d\n", ret);
434*a9655020SBjoern A. Zeeb 			return ret;
435*a9655020SBjoern A. Zeeb 		}
436*a9655020SBjoern A. Zeeb 
437*a9655020SBjoern A. Zeeb 		if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BIOS_SAR) &&
438*a9655020SBjoern A. Zeeb 		    ab->acpi.bios_sar_data[0] == ATH12K_ACPI_POWER_LIMIT_VERSION &&
439*a9655020SBjoern A. Zeeb 		    ab->acpi.bios_sar_data[1] == ATH12K_ACPI_POWER_LIMIT_ENABLE_FLAG &&
440*a9655020SBjoern A. Zeeb 		    !ab->acpi.acpi_tas_enable)
441*a9655020SBjoern A. Zeeb 			ab->acpi.acpi_bios_sar_enable = true;
442*a9655020SBjoern A. Zeeb 	}
443*a9655020SBjoern A. Zeeb 
444*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_CCA)) {
445*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_INDEX_CCA);
446*a9655020SBjoern A. Zeeb 		if (ret) {
447*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI DSM CCA threshold configuration: %d\n",
448*a9655020SBjoern A. Zeeb 				    ret);
449*a9655020SBjoern A. Zeeb 			return ret;
450*a9655020SBjoern A. Zeeb 		}
451*a9655020SBjoern A. Zeeb 
452*a9655020SBjoern A. Zeeb 		if (ab->acpi.cca_data[0] == ATH12K_ACPI_CCA_THR_VERSION &&
453*a9655020SBjoern A. Zeeb 		    ab->acpi.cca_data[ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET] ==
454*a9655020SBjoern A. Zeeb 		    ATH12K_ACPI_CCA_THR_ENABLE_FLAG)
455*a9655020SBjoern A. Zeeb 			ab->acpi.acpi_cca_enable = true;
456*a9655020SBjoern A. Zeeb 	}
457*a9655020SBjoern A. Zeeb 
458*a9655020SBjoern A. Zeeb 	if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi,
459*a9655020SBjoern A. Zeeb 				       ATH12K_ACPI_FUNC_BIT_BAND_EDGE_CHAN_POWER)) {
460*a9655020SBjoern A. Zeeb 		ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE);
461*a9655020SBjoern A. Zeeb 		if (ret) {
462*a9655020SBjoern A. Zeeb 			ath12k_warn(ab, "failed to get ACPI DSM band edge channel power: %d\n",
463*a9655020SBjoern A. Zeeb 				    ret);
464*a9655020SBjoern A. Zeeb 			return ret;
465*a9655020SBjoern A. Zeeb 		}
466*a9655020SBjoern A. Zeeb 
467*a9655020SBjoern A. Zeeb 		if (ab->acpi.band_edge_power[0] == ATH12K_ACPI_BAND_EDGE_VERSION &&
468*a9655020SBjoern A. Zeeb 		    ab->acpi.band_edge_power[1] == ATH12K_ACPI_BAND_EDGE_ENABLE_FLAG)
469*a9655020SBjoern A. Zeeb 			ab->acpi.acpi_band_edge_enable = true;
470*a9655020SBjoern A. Zeeb 	}
471*a9655020SBjoern A. Zeeb 
472*a9655020SBjoern A. Zeeb 	status = acpi_install_notify_handler(ACPI_HANDLE(ab->dev),
473*a9655020SBjoern A. Zeeb 					     ACPI_DEVICE_NOTIFY,
474*a9655020SBjoern A. Zeeb 					     ath12k_acpi_dsm_notify, ab);
475*a9655020SBjoern A. Zeeb 	if (ACPI_FAILURE(status)) {
476*a9655020SBjoern A. Zeeb 		ath12k_warn(ab, "failed to install DSM notify callback: %d\n", status);
477*a9655020SBjoern A. Zeeb 		return -EIO;
478*a9655020SBjoern A. Zeeb 	}
479*a9655020SBjoern A. Zeeb 
480*a9655020SBjoern A. Zeeb 	ab->acpi.started = true;
481*a9655020SBjoern A. Zeeb 
482*a9655020SBjoern A. Zeeb 	return 0;
483*a9655020SBjoern A. Zeeb }
484*a9655020SBjoern A. Zeeb 
ath12k_acpi_check_bdf_variant_name(struct ath12k_base * ab)485*a9655020SBjoern A. Zeeb int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab)
486*a9655020SBjoern A. Zeeb {
487*a9655020SBjoern A. Zeeb 	size_t max_len = sizeof(ab->qmi.target.bdf_ext);
488*a9655020SBjoern A. Zeeb 
489*a9655020SBjoern A. Zeeb 	if (!ab->acpi.acpi_enable_bdf)
490*a9655020SBjoern A. Zeeb 		return -ENODATA;
491*a9655020SBjoern A. Zeeb 
492*a9655020SBjoern A. Zeeb 	if (strscpy(ab->qmi.target.bdf_ext, ab->acpi.bdf_string + 4, max_len) < 0)
493*a9655020SBjoern A. Zeeb 		ath12k_dbg(ab, ATH12K_DBG_BOOT,
494*a9655020SBjoern A. Zeeb 			   "acpi bdf variant longer than the buffer (variant: %s)\n",
495*a9655020SBjoern A. Zeeb 			   ab->acpi.bdf_string);
496*a9655020SBjoern A. Zeeb 
497*a9655020SBjoern A. Zeeb 	return 0;
498*a9655020SBjoern A. Zeeb }
499*a9655020SBjoern A. Zeeb 
ath12k_acpi_stop(struct ath12k_base * ab)500*a9655020SBjoern A. Zeeb void ath12k_acpi_stop(struct ath12k_base *ab)
501*a9655020SBjoern A. Zeeb {
502*a9655020SBjoern A. Zeeb 	if (!ab->acpi.started)
503*a9655020SBjoern A. Zeeb 		return;
504*a9655020SBjoern A. Zeeb 
505*a9655020SBjoern A. Zeeb 	acpi_remove_notify_handler(ACPI_HANDLE(ab->dev),
506*a9655020SBjoern A. Zeeb 				   ACPI_DEVICE_NOTIFY,
507*a9655020SBjoern A. Zeeb 				   ath12k_acpi_dsm_notify);
508*a9655020SBjoern A. Zeeb 
509*a9655020SBjoern A. Zeeb 	memset(&ab->acpi, 0, sizeof(ab->acpi));
510*a9655020SBjoern A. Zeeb }
511