xref: /linux/drivers/net/wireless/realtek/rtw89/acpi.c (revision fb7399cf2d0b33825b8039f95c45395c7deba25c)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2021-2023  Realtek Corporation
3  */
4 
5 #include <linux/acpi.h>
6 #include <linux/uuid.h>
7 
8 #include "acpi.h"
9 #include "debug.h"
10 
11 static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00,
12 					   0x82, 0xBD, 0xFE, 0x86,
13 					   0x07, 0x80, 0x3A, 0xA7);
14 
15 static u32 rtw89_acpi_traversal_object(struct rtw89_dev *rtwdev,
16 				       const union acpi_object *obj, u8 *pos)
17 {
18 	const union acpi_object *elm;
19 	unsigned int i;
20 	u32 sub_len;
21 	u32 len = 0;
22 	u8 *tmp;
23 
24 	switch (obj->type) {
25 	case ACPI_TYPE_INTEGER:
26 		if (pos)
27 			pos[len] = obj->integer.value;
28 
29 		len++;
30 		break;
31 	case ACPI_TYPE_BUFFER:
32 		if (unlikely(obj->buffer.length == 0)) {
33 			rtw89_debug(rtwdev, RTW89_DBG_ACPI,
34 				    "%s: invalid buffer type\n", __func__);
35 			goto err;
36 		}
37 
38 		if (pos)
39 			memcpy(pos, obj->buffer.pointer, obj->buffer.length);
40 
41 		len += obj->buffer.length;
42 		break;
43 	case ACPI_TYPE_PACKAGE:
44 		if (unlikely(obj->package.count == 0)) {
45 			rtw89_debug(rtwdev, RTW89_DBG_ACPI,
46 				    "%s: invalid package type\n", __func__);
47 			goto err;
48 		}
49 
50 		for (i = 0; i < obj->package.count; i++) {
51 			elm = &obj->package.elements[i];
52 			tmp = pos ? pos + len : NULL;
53 
54 			sub_len = rtw89_acpi_traversal_object(rtwdev, elm, tmp);
55 			if (unlikely(sub_len == 0))
56 				goto err;
57 
58 			len += sub_len;
59 		}
60 		break;
61 	default:
62 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: unhandled type: %d\n",
63 			    __func__, obj->type);
64 		goto err;
65 	}
66 
67 	return len;
68 
69 err:
70 	return 0;
71 }
72 
73 static u32 rtw89_acpi_calculate_object_length(struct rtw89_dev *rtwdev,
74 					      const union acpi_object *obj)
75 {
76 	return rtw89_acpi_traversal_object(rtwdev, obj, NULL);
77 }
78 
79 static struct rtw89_acpi_data *
80 rtw89_acpi_evaluate_method(struct rtw89_dev *rtwdev, const char *method)
81 {
82 	struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
83 	struct rtw89_acpi_data *data = NULL;
84 	acpi_handle root, handle;
85 	union acpi_object *obj;
86 	acpi_status status;
87 	u32 len;
88 
89 	root = ACPI_HANDLE(rtwdev->dev);
90 	if (!root) {
91 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
92 			    "acpi (%s): failed to get root\n", method);
93 		return NULL;
94 	}
95 
96 	status = acpi_get_handle(root, (acpi_string)method, &handle);
97 	if (ACPI_FAILURE(status)) {
98 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
99 			    "acpi (%s): failed to get handle\n", method);
100 		return NULL;
101 	}
102 
103 	status = acpi_evaluate_object(handle, NULL, NULL, &buf);
104 	if (ACPI_FAILURE(status)) {
105 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
106 			    "acpi (%s): failed to evaluate object\n", method);
107 		return NULL;
108 	}
109 
110 	obj = buf.pointer;
111 	len = rtw89_acpi_calculate_object_length(rtwdev, obj);
112 	if (unlikely(len == 0)) {
113 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
114 			    "acpi (%s): failed to traversal obj len\n", method);
115 		goto out;
116 	}
117 
118 	data = kzalloc(struct_size(data, buf, len), GFP_KERNEL);
119 	if (!data)
120 		goto out;
121 
122 	data->len = len;
123 	rtw89_acpi_traversal_object(rtwdev, obj, data->buf);
124 
125 out:
126 	ACPI_FREE(obj);
127 	return data;
128 }
129 
130 static
131 int rtw89_acpi_dsm_get_value(struct rtw89_dev *rtwdev, union acpi_object *obj,
132 			     u8 *value)
133 {
134 	if (obj->type != ACPI_TYPE_INTEGER) {
135 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
136 			    "acpi: expect integer but type: %d\n", obj->type);
137 		return -EINVAL;
138 	}
139 
140 	*value = (u8)obj->integer.value;
141 	return 0;
142 }
143 
144 static bool chk_acpi_policy_6ghz_sig(const struct rtw89_acpi_policy_6ghz *p)
145 {
146 	return p->signature[0] == 0x00 &&
147 	       p->signature[1] == 0xE0 &&
148 	       p->signature[2] == 0x4C;
149 }
150 
151 static
152 int rtw89_acpi_dsm_get_policy_6ghz(struct rtw89_dev *rtwdev,
153 				   union acpi_object *obj,
154 				   struct rtw89_acpi_policy_6ghz **policy_6ghz)
155 {
156 	const struct rtw89_acpi_policy_6ghz *ptr;
157 	u32 expect_len;
158 	u32 len;
159 
160 	if (obj->type != ACPI_TYPE_BUFFER) {
161 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
162 			    "acpi: expect buffer but type: %d\n", obj->type);
163 		return -EINVAL;
164 	}
165 
166 	len = obj->buffer.length;
167 	if (len < sizeof(*ptr)) {
168 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
169 			    __func__, len);
170 		return -EINVAL;
171 	}
172 
173 	ptr = (typeof(ptr))obj->buffer.pointer;
174 	if (!chk_acpi_policy_6ghz_sig(ptr)) {
175 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
176 		return -EINVAL;
177 	}
178 
179 	expect_len = struct_size(ptr, country_list, ptr->country_count);
180 	if (len < expect_len) {
181 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: expect %u but length: %u\n",
182 			    __func__, expect_len, len);
183 		return -EINVAL;
184 	}
185 
186 	*policy_6ghz = kmemdup(ptr, expect_len, GFP_KERNEL);
187 	if (!*policy_6ghz)
188 		return -ENOMEM;
189 
190 	rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz: ", *policy_6ghz,
191 		       expect_len);
192 	return 0;
193 }
194 
195 static bool chk_acpi_policy_6ghz_sp_sig(const struct rtw89_acpi_policy_6ghz_sp *p)
196 {
197 	return p->signature[0] == 0x52 &&
198 	       p->signature[1] == 0x54 &&
199 	       p->signature[2] == 0x4B &&
200 	       p->signature[3] == 0x07;
201 }
202 
203 static
204 int rtw89_acpi_dsm_get_policy_6ghz_sp(struct rtw89_dev *rtwdev,
205 				      union acpi_object *obj,
206 				      struct rtw89_acpi_policy_6ghz_sp **policy)
207 {
208 	const struct rtw89_acpi_policy_6ghz_sp *ptr;
209 	u32 buf_len;
210 
211 	if (obj->type != ACPI_TYPE_BUFFER) {
212 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
213 			    "acpi: expect buffer but type: %d\n", obj->type);
214 		return -EINVAL;
215 	}
216 
217 	buf_len = obj->buffer.length;
218 	if (buf_len < sizeof(*ptr)) {
219 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
220 			    __func__, buf_len);
221 		return -EINVAL;
222 	}
223 
224 	ptr = (typeof(ptr))obj->buffer.pointer;
225 	if (!chk_acpi_policy_6ghz_sp_sig(ptr)) {
226 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
227 		return -EINVAL;
228 	}
229 
230 	*policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
231 	if (!*policy)
232 		return -ENOMEM;
233 
234 	rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_sp: ", *policy,
235 		       sizeof(*ptr));
236 	return 0;
237 }
238 
239 static bool chk_acpi_policy_tas_sig(const struct rtw89_acpi_policy_tas *p)
240 {
241 	return p->signature[0] == 0x52 &&
242 	       p->signature[1] == 0x54 &&
243 	       p->signature[2] == 0x4B &&
244 	       p->signature[3] == 0x05;
245 }
246 
247 static int rtw89_acpi_dsm_get_policy_tas(struct rtw89_dev *rtwdev,
248 					 union acpi_object *obj,
249 					 struct rtw89_acpi_policy_tas **policy)
250 {
251 	const struct rtw89_acpi_policy_tas *ptr;
252 	u32 buf_len;
253 
254 	if (obj->type != ACPI_TYPE_BUFFER) {
255 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
256 			    "acpi: expect buffer but type: %d\n", obj->type);
257 		return -EINVAL;
258 	}
259 
260 	buf_len = obj->buffer.length;
261 	if (buf_len < sizeof(*ptr)) {
262 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
263 			    __func__, buf_len);
264 		return -EINVAL;
265 	}
266 
267 	ptr = (typeof(ptr))obj->buffer.pointer;
268 	if (!chk_acpi_policy_tas_sig(ptr)) {
269 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
270 		return -EINVAL;
271 	}
272 
273 	*policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL);
274 	if (!*policy)
275 		return -ENOMEM;
276 
277 	rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_tas: ", *policy,
278 		       sizeof(*ptr));
279 	return 0;
280 }
281 
282 int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
283 			    enum rtw89_acpi_dsm_func func,
284 			    struct rtw89_acpi_dsm_result *res)
285 {
286 	union acpi_object *obj;
287 	int ret;
288 
289 	obj = acpi_evaluate_dsm(ACPI_HANDLE(rtwdev->dev), &rtw89_guid,
290 				0, func, NULL);
291 	if (!obj) {
292 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
293 			    "acpi dsm fail to evaluate func: %d\n", func);
294 		return -ENOENT;
295 	}
296 
297 	if (func == RTW89_ACPI_DSM_FUNC_6G_BP)
298 		ret = rtw89_acpi_dsm_get_policy_6ghz(rtwdev, obj,
299 						     &res->u.policy_6ghz);
300 	else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP)
301 		ret = rtw89_acpi_dsm_get_policy_6ghz_sp(rtwdev, obj,
302 							&res->u.policy_6ghz_sp);
303 	else if (func == RTW89_ACPI_DSM_FUNC_TAS_EN)
304 		ret = rtw89_acpi_dsm_get_policy_tas(rtwdev, obj, &res->u.policy_tas);
305 	else
306 		ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value);
307 
308 	ACPI_FREE(obj);
309 	return ret;
310 }
311 
312 int rtw89_acpi_evaluate_rtag(struct rtw89_dev *rtwdev,
313 			     struct rtw89_acpi_rtag_result *res)
314 {
315 	const struct rtw89_acpi_data *data;
316 	u32 buf_len;
317 	int ret = 0;
318 
319 	data = rtw89_acpi_evaluate_method(rtwdev, "RTAG");
320 	if (!data)
321 		return -EIO;
322 
323 	buf_len = data->len;
324 	if (buf_len != sizeof(*res)) {
325 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
326 			    __func__, buf_len);
327 		ret = -EINVAL;
328 		goto out;
329 	}
330 
331 	*res = *(struct rtw89_acpi_rtag_result *)data->buf;
332 
333 	rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "antenna_gain: ", res, sizeof(*res));
334 
335 out:
336 	kfree(data);
337 	return ret;
338 }
339 
340 enum rtw89_acpi_sar_subband rtw89_acpi_sar_get_subband(struct rtw89_dev *rtwdev,
341 						       u32 center_freq)
342 {
343 	switch (center_freq) {
344 	default:
345 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
346 			    "center freq %u to ACPI SAR subband is unhandled\n",
347 			    center_freq);
348 		fallthrough;
349 	case 2412 ... 2484:
350 		return RTW89_ACPI_SAR_2GHZ_SUBBAND;
351 	case 5180 ... 5240:
352 		return RTW89_ACPI_SAR_5GHZ_SUBBAND_1;
353 	case 5250 ... 5320:
354 		return RTW89_ACPI_SAR_5GHZ_SUBBAND_2;
355 	case 5500 ... 5720:
356 		return RTW89_ACPI_SAR_5GHZ_SUBBAND_2E;
357 	case 5745 ... 5885:
358 		return RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4;
359 	case 5955 ... 6155:
360 		return RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L;
361 	case 6175 ... 6415:
362 		return RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H;
363 	case 6435 ... 6515:
364 		return RTW89_ACPI_SAR_6GHZ_SUBBAND_6;
365 	case 6535 ... 6695:
366 		return RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L;
367 	case 6715 ... 6855:
368 		return RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H;
369 
370 	/* freq 6875 (ch 185, 20MHz) spans RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H
371 	 * and RTW89_ACPI_SAR_6GHZ_SUBBAND_8, so directly describe it with
372 	 * struct rtw89_6ghz_span.
373 	 */
374 
375 	case 6895 ... 7115:
376 		return RTW89_ACPI_SAR_6GHZ_SUBBAND_8;
377 	}
378 }
379 
380 enum rtw89_band rtw89_acpi_sar_subband_to_band(struct rtw89_dev *rtwdev,
381 					       enum rtw89_acpi_sar_subband subband)
382 {
383 	switch (subband) {
384 	default:
385 		rtw89_debug(rtwdev, RTW89_DBG_ACPI,
386 			    "ACPI SAR subband %u to band is unhandled\n", subband);
387 		fallthrough;
388 	case RTW89_ACPI_SAR_2GHZ_SUBBAND:
389 		return RTW89_BAND_2G;
390 	case RTW89_ACPI_SAR_5GHZ_SUBBAND_1:
391 		return RTW89_BAND_5G;
392 	case RTW89_ACPI_SAR_5GHZ_SUBBAND_2:
393 		return RTW89_BAND_5G;
394 	case RTW89_ACPI_SAR_5GHZ_SUBBAND_2E:
395 		return RTW89_BAND_5G;
396 	case RTW89_ACPI_SAR_5GHZ_SUBBAND_3_4:
397 		return RTW89_BAND_5G;
398 	case RTW89_ACPI_SAR_6GHZ_SUBBAND_5_L:
399 		return RTW89_BAND_6G;
400 	case RTW89_ACPI_SAR_6GHZ_SUBBAND_5_H:
401 		return RTW89_BAND_6G;
402 	case RTW89_ACPI_SAR_6GHZ_SUBBAND_6:
403 		return RTW89_BAND_6G;
404 	case RTW89_ACPI_SAR_6GHZ_SUBBAND_7_L:
405 		return RTW89_BAND_6G;
406 	case RTW89_ACPI_SAR_6GHZ_SUBBAND_7_H:
407 		return RTW89_BAND_6G;
408 	case RTW89_ACPI_SAR_6GHZ_SUBBAND_8:
409 		return RTW89_BAND_6G;
410 	}
411 }
412 
413 static u8 rtw89_acpi_sar_rfpath_to_hp_antidx(enum rtw89_rf_path rfpath)
414 {
415 	switch (rfpath) {
416 	default:
417 	case RF_PATH_B:
418 		return 0;
419 	case RF_PATH_A:
420 		return 1;
421 	}
422 }
423 
424 static u8 rtw89_acpi_sar_rfpath_to_rt_antidx(enum rtw89_rf_path rfpath)
425 {
426 	switch (rfpath) {
427 	default:
428 	case RF_PATH_A:
429 		return 0;
430 	case RF_PATH_B:
431 		return 1;
432 	}
433 }
434 
435 static s16 rtw89_acpi_sar_normalize_hp_val(u8 v)
436 {
437 	static const u8 bias = 10;
438 	static const u8 fct = 1;
439 	u16 res;
440 
441 	BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR);
442 
443 	res = (bias << TXPWR_FACTOR_OF_RTW89_ACPI_SAR) +
444 	      (v << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct));
445 
446 	return min_t(s32, res, MAX_VAL_OF_RTW89_ACPI_SAR);
447 }
448 
449 static s16 rtw89_acpi_sar_normalize_rt_val(u8 v)
450 {
451 	static const u8 fct = 3;
452 	u16 res;
453 
454 	BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR);
455 
456 	res = v << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct);
457 
458 	return min_t(s32, res, MAX_VAL_OF_RTW89_ACPI_SAR);
459 }
460 
461 static
462 void rtw89_acpi_sar_load_std_legacy(struct rtw89_dev *rtwdev,
463 				    const struct rtw89_acpi_sar_recognition *rec,
464 				    const void *content,
465 				    struct rtw89_sar_entry_from_acpi *ent)
466 {
467 	const struct rtw89_acpi_sar_std_legacy *ptr = content;
468 	enum rtw89_acpi_sar_subband subband;
469 	enum rtw89_rf_path path;
470 
471 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
472 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
473 			u8 antidx = rec->rfpath_to_antidx(path);
474 
475 			if (subband < RTW89_ACPI_SAR_SUBBAND_NR_LEGACY)
476 				ent->v[subband][path] =
477 					rec->normalize(ptr->v[antidx][subband]);
478 			else
479 				ent->v[subband][path] = MAX_VAL_OF_RTW89_ACPI_SAR;
480 		}
481 	}
482 }
483 
484 static
485 void rtw89_acpi_sar_load_std_has_6ghz(struct rtw89_dev *rtwdev,
486 				      const struct rtw89_acpi_sar_recognition *rec,
487 				      const void *content,
488 				      struct rtw89_sar_entry_from_acpi *ent)
489 {
490 	const struct rtw89_acpi_sar_std_has_6ghz *ptr = content;
491 	enum rtw89_acpi_sar_subband subband;
492 	enum rtw89_rf_path path;
493 
494 	BUILD_BUG_ON(RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ != NUM_OF_RTW89_ACPI_SAR_SUBBAND);
495 
496 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
497 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
498 			u8 antidx = rec->rfpath_to_antidx(path);
499 
500 			ent->v[subband][path] = rec->normalize(ptr->v[antidx][subband]);
501 		}
502 	}
503 }
504 
505 static
506 void rtw89_acpi_sar_load_sml_legacy(struct rtw89_dev *rtwdev,
507 				    const struct rtw89_acpi_sar_recognition *rec,
508 				    const void *content,
509 				    struct rtw89_sar_entry_from_acpi *ent)
510 {
511 	const struct rtw89_acpi_sar_sml_legacy *ptr = content;
512 	enum rtw89_acpi_sar_subband subband;
513 	enum rtw89_rf_path path;
514 
515 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
516 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
517 			u8 antidx = rec->rfpath_to_antidx(path);
518 
519 			if (subband < RTW89_ACPI_SAR_SUBBAND_NR_LEGACY)
520 				ent->v[subband][path] =
521 					rec->normalize(ptr->v[antidx][subband]);
522 			else
523 				ent->v[subband][path] = MAX_VAL_OF_RTW89_ACPI_SAR;
524 		}
525 	}
526 }
527 
528 static
529 void rtw89_acpi_sar_load_sml_has_6ghz(struct rtw89_dev *rtwdev,
530 				      const struct rtw89_acpi_sar_recognition *rec,
531 				      const void *content,
532 				      struct rtw89_sar_entry_from_acpi *ent)
533 {
534 	const struct rtw89_acpi_sar_sml_has_6ghz *ptr = content;
535 	enum rtw89_acpi_sar_subband subband;
536 	enum rtw89_rf_path path;
537 
538 	BUILD_BUG_ON(RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ != NUM_OF_RTW89_ACPI_SAR_SUBBAND);
539 
540 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
541 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
542 			u8 antidx = rec->rfpath_to_antidx(path);
543 
544 			ent->v[subband][path] = rec->normalize(ptr->v[antidx][subband]);
545 		}
546 	}
547 }
548 
549 static s16 rtw89_acpi_geo_sar_normalize_delta(s8 delta)
550 {
551 	static const u8 fct = 1;
552 
553 	BUILD_BUG_ON(fct > TXPWR_FACTOR_OF_RTW89_ACPI_SAR);
554 
555 	return delta << (TXPWR_FACTOR_OF_RTW89_ACPI_SAR - fct);
556 }
557 
558 static enum rtw89_acpi_geo_sar_regd_hp
559 rtw89_acpi_geo_sar_regd_convert_hp_idx(enum rtw89_regulation_type regd)
560 {
561 	switch (regd) {
562 	case RTW89_FCC:
563 	case RTW89_IC:
564 	case RTW89_NCC:
565 	case RTW89_CHILE:
566 	case RTW89_MEXICO:
567 		return RTW89_ACPI_GEO_SAR_REGD_HP_FCC;
568 	case RTW89_ETSI:
569 	case RTW89_MKK:
570 	case RTW89_ACMA:
571 		return RTW89_ACPI_GEO_SAR_REGD_HP_ETSI;
572 	default:
573 	case RTW89_WW:
574 	case RTW89_NA:
575 	case RTW89_KCC:
576 		return RTW89_ACPI_GEO_SAR_REGD_HP_WW;
577 	}
578 }
579 
580 static enum rtw89_acpi_geo_sar_regd_rt
581 rtw89_acpi_geo_sar_regd_convert_rt_idx(enum rtw89_regulation_type regd)
582 {
583 	switch (regd) {
584 	case RTW89_FCC:
585 	case RTW89_NCC:
586 	case RTW89_CHILE:
587 	case RTW89_MEXICO:
588 		return RTW89_ACPI_GEO_SAR_REGD_RT_FCC;
589 	case RTW89_ETSI:
590 	case RTW89_ACMA:
591 		return RTW89_ACPI_GEO_SAR_REGD_RT_ETSI;
592 	case RTW89_MKK:
593 		return RTW89_ACPI_GEO_SAR_REGD_RT_MKK;
594 	case RTW89_IC:
595 		return RTW89_ACPI_GEO_SAR_REGD_RT_IC;
596 	case RTW89_KCC:
597 		return RTW89_ACPI_GEO_SAR_REGD_RT_KCC;
598 	default:
599 	case RTW89_WW:
600 	case RTW89_NA:
601 		return RTW89_ACPI_GEO_SAR_REGD_RT_WW;
602 	}
603 }
604 
605 static
606 void rtw89_acpi_geo_sar_load_by_hp(struct rtw89_dev *rtwdev,
607 				   const struct rtw89_acpi_geo_sar_hp_val *ptr,
608 				   enum rtw89_rf_path path, s16 *val)
609 {
610 	u8 antidx = rtw89_acpi_sar_rfpath_to_hp_antidx(path);
611 	s16 delta = rtw89_acpi_geo_sar_normalize_delta(ptr->delta[antidx]);
612 	s16 max = rtw89_acpi_sar_normalize_hp_val(ptr->max);
613 
614 	*val = clamp_t(s32, (*val) + delta, MIN_VAL_OF_RTW89_ACPI_SAR, max);
615 }
616 
617 static
618 void rtw89_acpi_geo_sar_load_by_rt(struct rtw89_dev *rtwdev,
619 				   const struct rtw89_acpi_geo_sar_rt_val *ptr,
620 				   s16 *val)
621 {
622 	s16 delta = rtw89_acpi_geo_sar_normalize_delta(ptr->delta);
623 	s16 max = rtw89_acpi_sar_normalize_rt_val(ptr->max);
624 
625 	*val = clamp_t(s32, (*val) + delta, MIN_VAL_OF_RTW89_ACPI_SAR, max);
626 }
627 
628 static
629 void rtw89_acpi_geo_sar_load_hp_legacy(struct rtw89_dev *rtwdev,
630 				       const void *content,
631 				       enum rtw89_regulation_type regd,
632 				       struct rtw89_sar_entry_from_acpi *ent)
633 {
634 	const struct rtw89_acpi_geo_sar_hp_legacy *ptr = content;
635 	const struct rtw89_acpi_geo_sar_hp_legacy_entry *ptr_ent;
636 	const struct rtw89_acpi_geo_sar_hp_val *ptr_ent_val;
637 	enum rtw89_acpi_geo_sar_regd_hp geo_idx =
638 		rtw89_acpi_geo_sar_regd_convert_hp_idx(regd);
639 	enum rtw89_acpi_sar_subband subband;
640 	enum rtw89_rf_path path;
641 	enum rtw89_band band;
642 
643 	ptr_ent = &ptr->entries[geo_idx];
644 
645 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
646 		band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
647 		switch (band) {
648 		case RTW89_BAND_2G:
649 			ptr_ent_val = &ptr_ent->val_2ghz;
650 			break;
651 		case RTW89_BAND_5G:
652 			ptr_ent_val = &ptr_ent->val_5ghz;
653 			break;
654 		default:
655 		case RTW89_BAND_6G:
656 			ptr_ent_val = NULL;
657 			break;
658 		}
659 
660 		if (!ptr_ent_val)
661 			continue;
662 
663 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
664 			rtw89_acpi_geo_sar_load_by_hp(rtwdev, ptr_ent_val, path,
665 						      &ent->v[subband][path]);
666 	}
667 }
668 
669 static
670 void rtw89_acpi_geo_sar_load_hp_has_6ghz(struct rtw89_dev *rtwdev,
671 					 const void *content,
672 					 enum rtw89_regulation_type regd,
673 					 struct rtw89_sar_entry_from_acpi *ent)
674 {
675 	const struct rtw89_acpi_geo_sar_hp_has_6ghz *ptr = content;
676 	const struct rtw89_acpi_geo_sar_hp_has_6ghz_entry *ptr_ent;
677 	const struct rtw89_acpi_geo_sar_hp_val *ptr_ent_val;
678 	enum rtw89_acpi_geo_sar_regd_hp geo_idx =
679 		rtw89_acpi_geo_sar_regd_convert_hp_idx(regd);
680 	enum rtw89_acpi_sar_subband subband;
681 	enum rtw89_rf_path path;
682 	enum rtw89_band band;
683 
684 	ptr_ent = &ptr->entries[geo_idx];
685 
686 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
687 		band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
688 		switch (band) {
689 		case RTW89_BAND_2G:
690 			ptr_ent_val = &ptr_ent->val_2ghz;
691 			break;
692 		case RTW89_BAND_5G:
693 			ptr_ent_val = &ptr_ent->val_5ghz;
694 			break;
695 		case RTW89_BAND_6G:
696 			ptr_ent_val = &ptr_ent->val_6ghz;
697 			break;
698 		default:
699 			ptr_ent_val = NULL;
700 			break;
701 		}
702 
703 		if (!ptr_ent_val)
704 			continue;
705 
706 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
707 			rtw89_acpi_geo_sar_load_by_hp(rtwdev, ptr_ent_val, path,
708 						      &ent->v[subband][path]);
709 	}
710 }
711 
712 static
713 void rtw89_acpi_geo_sar_load_rt_legacy(struct rtw89_dev *rtwdev,
714 				       const void *content,
715 				       enum rtw89_regulation_type regd,
716 				       struct rtw89_sar_entry_from_acpi *ent)
717 {
718 	const struct rtw89_acpi_geo_sar_rt_legacy *ptr = content;
719 	const struct rtw89_acpi_geo_sar_rt_legacy_entry *ptr_ent;
720 	const struct rtw89_acpi_geo_sar_rt_val *ptr_ent_val;
721 	enum rtw89_acpi_geo_sar_regd_rt geo_idx =
722 		rtw89_acpi_geo_sar_regd_convert_rt_idx(regd);
723 	enum rtw89_acpi_sar_subband subband;
724 	enum rtw89_rf_path path;
725 	enum rtw89_band band;
726 
727 	ptr_ent = &ptr->entries[geo_idx];
728 
729 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
730 		band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
731 		switch (band) {
732 		case RTW89_BAND_2G:
733 			ptr_ent_val = &ptr_ent->val_2ghz;
734 			break;
735 		case RTW89_BAND_5G:
736 			ptr_ent_val = &ptr_ent->val_5ghz;
737 			break;
738 		default:
739 		case RTW89_BAND_6G:
740 			ptr_ent_val = NULL;
741 			break;
742 		}
743 
744 		if (!ptr_ent_val)
745 			continue;
746 
747 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
748 			rtw89_acpi_geo_sar_load_by_rt(rtwdev, ptr_ent_val,
749 						      &ent->v[subband][path]);
750 	}
751 }
752 
753 static
754 void rtw89_acpi_geo_sar_load_rt_has_6ghz(struct rtw89_dev *rtwdev,
755 					 const void *content,
756 					 enum rtw89_regulation_type regd,
757 					 struct rtw89_sar_entry_from_acpi *ent)
758 {
759 	const struct rtw89_acpi_geo_sar_rt_has_6ghz *ptr = content;
760 	const struct rtw89_acpi_geo_sar_rt_has_6ghz_entry *ptr_ent;
761 	const struct rtw89_acpi_geo_sar_rt_val *ptr_ent_val;
762 	enum rtw89_acpi_geo_sar_regd_rt geo_idx =
763 		rtw89_acpi_geo_sar_regd_convert_rt_idx(regd);
764 	enum rtw89_acpi_sar_subband subband;
765 	enum rtw89_rf_path path;
766 	enum rtw89_band band;
767 
768 	ptr_ent = &ptr->entries[geo_idx];
769 
770 	for (subband = 0; subband < NUM_OF_RTW89_ACPI_SAR_SUBBAND; subband++) {
771 		band = rtw89_acpi_sar_subband_to_band(rtwdev, subband);
772 		switch (band) {
773 		case RTW89_BAND_2G:
774 			ptr_ent_val = &ptr_ent->val_2ghz;
775 			break;
776 		case RTW89_BAND_5G:
777 			ptr_ent_val = &ptr_ent->val_5ghz;
778 			break;
779 		case RTW89_BAND_6G:
780 			ptr_ent_val = &ptr_ent->val_6ghz;
781 			break;
782 		default:
783 			ptr_ent_val = NULL;
784 			break;
785 		}
786 
787 		if (!ptr_ent_val)
788 			continue;
789 
790 		for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++)
791 			rtw89_acpi_geo_sar_load_by_rt(rtwdev, ptr_ent_val,
792 						      &ent->v[subband][path]);
793 	}
794 }
795 
796 #define RTW89_ACPI_GEO_SAR_DECL_HANDLER(type) \
797 static const struct rtw89_acpi_geo_sar_handler \
798 rtw89_acpi_geo_sar_handler_ ## type = { \
799 	.data_size = RTW89_ACPI_GEO_SAR_SIZE_OF(type), \
800 	.load = rtw89_acpi_geo_sar_load_ ## type, \
801 }
802 
803 RTW89_ACPI_GEO_SAR_DECL_HANDLER(hp_legacy);
804 RTW89_ACPI_GEO_SAR_DECL_HANDLER(hp_has_6ghz);
805 RTW89_ACPI_GEO_SAR_DECL_HANDLER(rt_legacy);
806 RTW89_ACPI_GEO_SAR_DECL_HANDLER(rt_has_6ghz);
807 
808 static const struct rtw89_acpi_sar_recognition rtw89_acpi_sar_recs[] = {
809 	{
810 		.id = {
811 			.cid = RTW89_ACPI_SAR_CID_HP,
812 			.rev = RTW89_ACPI_SAR_REV_LEGACY,
813 			.size = RTW89_ACPI_SAR_SIZE_OF(std_legacy),
814 		},
815 		.geo = &rtw89_acpi_geo_sar_handler_hp_legacy,
816 
817 		.rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_hp_antidx,
818 		.normalize = rtw89_acpi_sar_normalize_hp_val,
819 		.load = rtw89_acpi_sar_load_std_legacy,
820 	},
821 	{
822 		.id = {
823 			.cid = RTW89_ACPI_SAR_CID_HP,
824 			.rev = RTW89_ACPI_SAR_REV_HAS_6GHZ,
825 			.size = RTW89_ACPI_SAR_SIZE_OF(std_has_6ghz),
826 		},
827 		.geo = &rtw89_acpi_geo_sar_handler_hp_has_6ghz,
828 
829 		.rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_hp_antidx,
830 		.normalize = rtw89_acpi_sar_normalize_hp_val,
831 		.load = rtw89_acpi_sar_load_std_has_6ghz,
832 	},
833 	{
834 		.id = {
835 			.cid = RTW89_ACPI_SAR_CID_RT,
836 			.rev = RTW89_ACPI_SAR_REV_LEGACY,
837 			.size = RTW89_ACPI_SAR_SIZE_OF(std_legacy),
838 		},
839 		.geo = &rtw89_acpi_geo_sar_handler_rt_legacy,
840 
841 		.rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
842 		.normalize = rtw89_acpi_sar_normalize_rt_val,
843 		.load = rtw89_acpi_sar_load_std_legacy,
844 	},
845 	{
846 		.id = {
847 			.cid = RTW89_ACPI_SAR_CID_RT,
848 			.rev = RTW89_ACPI_SAR_REV_HAS_6GHZ,
849 			.size = RTW89_ACPI_SAR_SIZE_OF(std_has_6ghz),
850 		},
851 		.geo = &rtw89_acpi_geo_sar_handler_rt_has_6ghz,
852 
853 		.rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
854 		.normalize = rtw89_acpi_sar_normalize_rt_val,
855 		.load = rtw89_acpi_sar_load_std_has_6ghz,
856 	},
857 	{
858 		.id = {
859 			.cid = RTW89_ACPI_SAR_CID_RT,
860 			.rev = RTW89_ACPI_SAR_REV_LEGACY,
861 			.size = RTW89_ACPI_SAR_SIZE_OF(sml_legacy),
862 		},
863 		.geo = &rtw89_acpi_geo_sar_handler_rt_legacy,
864 
865 		.rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
866 		.normalize = rtw89_acpi_sar_normalize_rt_val,
867 		.load = rtw89_acpi_sar_load_sml_legacy,
868 	},
869 	{
870 		.id = {
871 			.cid = RTW89_ACPI_SAR_CID_RT,
872 			.rev = RTW89_ACPI_SAR_REV_HAS_6GHZ,
873 			.size = RTW89_ACPI_SAR_SIZE_OF(sml_has_6ghz),
874 		},
875 		.geo = &rtw89_acpi_geo_sar_handler_rt_has_6ghz,
876 
877 		.rfpath_to_antidx = rtw89_acpi_sar_rfpath_to_rt_antidx,
878 		.normalize = rtw89_acpi_sar_normalize_rt_val,
879 		.load = rtw89_acpi_sar_load_sml_has_6ghz,
880 	},
881 };
882 
883 struct rtw89_acpi_sar_rec_parm {
884 	u32 pld_len;
885 	u8 tbl_cnt;
886 	u16 cid;
887 	u8 rev;
888 };
889 
890 static const struct rtw89_acpi_sar_recognition *
891 rtw89_acpi_sar_recognize(struct rtw89_dev *rtwdev,
892 			 const struct rtw89_acpi_sar_rec_parm *parm)
893 {
894 	const u32 tbl_len = parm->pld_len / parm->tbl_cnt;
895 	const struct rtw89_acpi_sar_recognition *rec;
896 	struct rtw89_acpi_sar_identifier id = {};
897 
898 	rtw89_debug(rtwdev, RTW89_DBG_ACPI,
899 		    "%s: cid %u, rev %u, tbl len %u, tbl cnt %u\n",
900 		    __func__, parm->cid, parm->rev, tbl_len, parm->tbl_cnt);
901 
902 	if (unlikely(parm->pld_len % parm->tbl_cnt)) {
903 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid pld len %u\n",
904 			    parm->pld_len);
905 		return NULL;
906 	}
907 
908 	if (unlikely(tbl_len > RTW89_ACPI_SAR_SIZE_MAX)) {
909 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid tbl len %u\n",
910 			    tbl_len);
911 		return NULL;
912 	}
913 
914 	if (unlikely(parm->tbl_cnt > MAX_NUM_OF_RTW89_ACPI_SAR_TBL)) {
915 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid tbl cnt %u\n",
916 			    parm->tbl_cnt);
917 		return NULL;
918 	}
919 
920 	switch (parm->cid) {
921 	case RTW89_ACPI_SAR_CID_HP:
922 	case RTW89_ACPI_SAR_CID_RT:
923 		id.cid = parm->cid;
924 		break;
925 	default:
926 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid cid 0x%x\n",
927 			    parm->cid);
928 		return NULL;
929 	}
930 
931 	switch (parm->rev) {
932 	case RTW89_ACPI_SAR_REV_LEGACY:
933 	case RTW89_ACPI_SAR_REV_HAS_6GHZ:
934 		id.rev = parm->rev;
935 		break;
936 	default:
937 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid rev %u\n",
938 			    parm->rev);
939 		return NULL;
940 	}
941 
942 	id.size = tbl_len;
943 	for (unsigned int i = 0; i < ARRAY_SIZE(rtw89_acpi_sar_recs); i++) {
944 		rec = &rtw89_acpi_sar_recs[i];
945 		if (memcmp(&rec->id, &id, sizeof(rec->id)) == 0)
946 			return rec;
947 	}
948 
949 	rtw89_debug(rtwdev, RTW89_DBG_ACPI, "failed to recognize\n");
950 	return NULL;
951 }
952 
953 static const struct rtw89_acpi_sar_recognition *
954 rtw89_acpi_evaluate_static_sar(struct rtw89_dev *rtwdev,
955 			       struct rtw89_sar_cfg_acpi *cfg)
956 {
957 	const struct rtw89_acpi_sar_recognition *rec = NULL;
958 	const struct rtw89_acpi_static_sar_hdr *hdr;
959 	struct rtw89_sar_entry_from_acpi tmp = {};
960 	struct rtw89_acpi_sar_rec_parm parm = {};
961 	struct rtw89_sar_table_from_acpi *tbl;
962 	const struct rtw89_acpi_data *data;
963 	u32 len;
964 
965 	data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_STATIC_SAR);
966 	if (!data)
967 		return NULL;
968 
969 	rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load static sar\n");
970 
971 	len = data->len;
972 	if (len <= sizeof(*hdr)) {
973 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
974 		goto out;
975 	}
976 
977 	hdr = (typeof(hdr))data->buf;
978 
979 	parm.cid = le16_to_cpu(hdr->cid);
980 	parm.rev = hdr->rev;
981 	parm.tbl_cnt = 1;
982 	parm.pld_len = len - sizeof(*hdr);
983 
984 	rec = rtw89_acpi_sar_recognize(rtwdev, &parm);
985 	if (!rec)
986 		goto out;
987 
988 	rec->load(rtwdev, rec, hdr->content, &tmp);
989 
990 	tbl = &cfg->tables[0];
991 	for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
992 		tbl->entries[regd] = tmp;
993 
994 	cfg->valid_num = 1;
995 
996 out:
997 	kfree(data);
998 	return rec;
999 }
1000 
1001 static const struct rtw89_acpi_sar_recognition *
1002 rtw89_acpi_evaluate_dynamic_sar(struct rtw89_dev *rtwdev,
1003 				struct rtw89_sar_cfg_acpi *cfg)
1004 {
1005 	const struct rtw89_acpi_sar_recognition *rec = NULL;
1006 	const struct rtw89_acpi_dynamic_sar_hdr *hdr;
1007 	struct rtw89_acpi_sar_rec_parm parm = {};
1008 	struct rtw89_sar_table_from_acpi *tbl;
1009 	const struct rtw89_acpi_data *data;
1010 	u32 len;
1011 
1012 	data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR);
1013 	if (!data)
1014 		return NULL;
1015 
1016 	rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar\n");
1017 
1018 	len = data->len;
1019 	if (len <= sizeof(*hdr)) {
1020 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
1021 		goto out;
1022 	}
1023 
1024 	hdr = (typeof(hdr))data->buf;
1025 
1026 	parm.cid = le16_to_cpu(hdr->cid);
1027 	parm.rev = hdr->rev;
1028 	parm.tbl_cnt = hdr->cnt;
1029 	parm.pld_len = len - sizeof(*hdr);
1030 
1031 	rec = rtw89_acpi_sar_recognize(rtwdev, &parm);
1032 	if (!rec)
1033 		goto out;
1034 
1035 	for (unsigned int i = 0; i < hdr->cnt; i++) {
1036 		const u8 *content = hdr->content + rec->id.size * i;
1037 		struct rtw89_sar_entry_from_acpi tmp = {};
1038 
1039 		rec->load(rtwdev, rec, content, &tmp);
1040 
1041 		tbl = &cfg->tables[i];
1042 		for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
1043 			tbl->entries[regd] = tmp;
1044 	}
1045 
1046 	cfg->valid_num = hdr->cnt;
1047 
1048 out:
1049 	kfree(data);
1050 	return rec;
1051 }
1052 
1053 int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev,
1054 					      struct rtw89_sar_cfg_acpi *cfg,
1055 					      bool *poll_changed)
1056 {
1057 	struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
1058 	struct rtw89_sar_indicator_from_acpi tmp = *ind;
1059 	const struct rtw89_acpi_data *data;
1060 	const u8 *tbl_base1_by_ant;
1061 	enum rtw89_rf_path path;
1062 	int ret = 0;
1063 	u32 len;
1064 
1065 	data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR);
1066 	if (!data)
1067 		return -EFAULT;
1068 
1069 	if (!poll_changed)
1070 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar indicator\n");
1071 
1072 	len = data->len;
1073 	if (len != ind->fields) {
1074 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
1075 		ret = -EINVAL;
1076 		goto out;
1077 	}
1078 
1079 	tbl_base1_by_ant = data->buf;
1080 
1081 	for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
1082 		u8 antidx = ind->rfpath_to_antidx(path);
1083 		u8 sel;
1084 
1085 		if (antidx >= ind->fields)
1086 			antidx = 0;
1087 
1088 		/* convert the table index from 1-based to 0-based */
1089 		sel = tbl_base1_by_ant[antidx] - 1;
1090 		if (sel >= cfg->valid_num)
1091 			sel = 0;
1092 
1093 		tmp.tblsel[path] = sel;
1094 	}
1095 
1096 	if (memcmp(ind, &tmp, sizeof(*ind)) == 0) {
1097 		if (poll_changed)
1098 			*poll_changed = false;
1099 	} else {
1100 		if (poll_changed)
1101 			*poll_changed = true;
1102 
1103 		*ind = tmp;
1104 	}
1105 
1106 out:
1107 	kfree(data);
1108 	return ret;
1109 }
1110 
1111 static
1112 void rtw89_acpi_evaluate_geo_sar(struct rtw89_dev *rtwdev,
1113 				 const struct rtw89_acpi_geo_sar_handler *hdl,
1114 				 struct rtw89_sar_cfg_acpi *cfg)
1115 {
1116 	const struct rtw89_acpi_data *data;
1117 	u32 len;
1118 
1119 	data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_GEO_SAR);
1120 	if (!data)
1121 		return;
1122 
1123 	rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load geo sar\n");
1124 
1125 	len = data->len;
1126 	if (len != hdl->data_size) {
1127 		rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u (expected %u)\n",
1128 			    len, hdl->data_size);
1129 		goto out;
1130 	}
1131 
1132 	for (unsigned int i = 0; i < cfg->valid_num; i++)
1133 		for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
1134 			hdl->load(rtwdev, data->buf, regd, &cfg->tables[i].entries[regd]);
1135 
1136 out:
1137 	kfree(data);
1138 }
1139 
1140 int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev,
1141 			    struct rtw89_sar_cfg_acpi *cfg)
1142 {
1143 	struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
1144 	const struct rtw89_acpi_sar_recognition *rec;
1145 	bool fetch_indicator = false;
1146 	int ret;
1147 
1148 	rec = rtw89_acpi_evaluate_static_sar(rtwdev, cfg);
1149 	if (rec)
1150 		goto recognized;
1151 
1152 	rec = rtw89_acpi_evaluate_dynamic_sar(rtwdev, cfg);
1153 	if (!rec)
1154 		return -ENOENT;
1155 
1156 	fetch_indicator = true;
1157 
1158 recognized:
1159 	rtw89_acpi_evaluate_geo_sar(rtwdev, rec->geo, cfg);
1160 
1161 	switch (rec->id.cid) {
1162 	case RTW89_ACPI_SAR_CID_HP:
1163 		cfg->downgrade_2tx = 3 << TXPWR_FACTOR_OF_RTW89_ACPI_SAR;
1164 		ind->fields = RTW89_ACPI_SAR_ANT_NR_STD;
1165 		break;
1166 	case RTW89_ACPI_SAR_CID_RT:
1167 		cfg->downgrade_2tx = 0;
1168 		ind->fields = 1;
1169 		break;
1170 	default:
1171 		return -EFAULT;
1172 	}
1173 
1174 	if (fetch_indicator) {
1175 		ind->rfpath_to_antidx = rec->rfpath_to_antidx;
1176 		ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, NULL);
1177 		if (ret)
1178 			fetch_indicator = false;
1179 	}
1180 
1181 	if (!fetch_indicator)
1182 		memset(ind->tblsel, 0, sizeof(ind->tblsel));
1183 
1184 	ind->enable_sync = fetch_indicator;
1185 	return 0;
1186 }
1187