Skip to content

Commit 665ecff

Browse files
Zong-Zhe YangKalle Valo
authored andcommitted
wifi: rtw89: acpi: process 6 GHz band policy from DSM
Realtek ACPI DSM func 4, RTW89_ACPI_DSM_FUNC_6G_BP, accepts a configuration via ACPI buffer as below. | index | description | ------------------------- | [0-2] | signature | | [3] | reserved | | [4] | policy mode | | [5] | country count | | [6-] | country list | Through this function, BIOS can indicate to allow/block 6 GHz on some specific countries. Still, driver should follow regd first before taking this configuration into account. Besides, add a bit in debug mask for ACPI. Signed-off-by: Zong-Zhe Yang <[email protected]> Signed-off-by: Ping-Ke Shih <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2c4e9ac commit 665ecff

File tree

5 files changed

+109
-19
lines changed

5 files changed

+109
-19
lines changed

drivers/net/wireless/realtek/rtw89/acpi.c

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,91 @@ static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00,
1212
0x82, 0xBD, 0xFE, 0x86,
1313
0x07, 0x80, 0x3A, 0xA7);
1414

15-
static int rtw89_acpi_dsm_get(struct rtw89_dev *rtwdev, union acpi_object *obj,
16-
u8 *value)
15+
static
16+
int rtw89_acpi_dsm_get_value(struct rtw89_dev *rtwdev, union acpi_object *obj,
17+
u8 *value)
1718
{
18-
switch (obj->type) {
19-
case ACPI_TYPE_INTEGER:
20-
*value = (u8)obj->integer.value;
21-
break;
22-
case ACPI_TYPE_BUFFER:
23-
*value = obj->buffer.pointer[0];
24-
break;
25-
default:
26-
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
27-
"acpi dsm return unhandled type: %d\n", obj->type);
19+
if (obj->type != ACPI_TYPE_INTEGER) {
20+
rtw89_debug(rtwdev, RTW89_DBG_ACPI,
21+
"acpi: expect integer but type: %d\n", obj->type);
2822
return -EINVAL;
2923
}
3024

25+
*value = (u8)obj->integer.value;
26+
return 0;
27+
}
28+
29+
static bool chk_acpi_policy_6ghz_sig(const struct rtw89_acpi_policy_6ghz *p)
30+
{
31+
return p->signature[0] == 0x00 &&
32+
p->signature[1] == 0xE0 &&
33+
p->signature[2] == 0x4C;
34+
}
35+
36+
static
37+
int rtw89_acpi_dsm_get_policy_6ghz(struct rtw89_dev *rtwdev,
38+
union acpi_object *obj,
39+
struct rtw89_acpi_policy_6ghz **policy_6ghz)
40+
{
41+
const struct rtw89_acpi_policy_6ghz *ptr;
42+
u32 expect_len;
43+
u32 len;
44+
45+
if (obj->type != ACPI_TYPE_BUFFER) {
46+
rtw89_debug(rtwdev, RTW89_DBG_ACPI,
47+
"acpi: expect buffer but type: %d\n", obj->type);
48+
return -EINVAL;
49+
}
50+
51+
len = obj->buffer.length;
52+
if (len < sizeof(*ptr)) {
53+
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n",
54+
__func__, len);
55+
return -EINVAL;
56+
}
57+
58+
ptr = (typeof(ptr))obj->buffer.pointer;
59+
if (!chk_acpi_policy_6ghz_sig(ptr)) {
60+
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__);
61+
return -EINVAL;
62+
}
63+
64+
expect_len = struct_size(ptr, country_list, ptr->country_count);
65+
if (len < expect_len) {
66+
rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: expect %u but length: %u\n",
67+
__func__, expect_len, len);
68+
return -EINVAL;
69+
}
70+
71+
*policy_6ghz = kmemdup(ptr, expect_len, GFP_KERNEL);
72+
if (!*policy_6ghz)
73+
return -ENOMEM;
74+
75+
rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz: ", *policy_6ghz,
76+
expect_len);
3177
return 0;
3278
}
3379

3480
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
35-
enum rtw89_acpi_dsm_func func, u8 *value)
81+
enum rtw89_acpi_dsm_func func,
82+
struct rtw89_acpi_dsm_result *res)
3683
{
3784
union acpi_object *obj;
3885
int ret;
3986

4087
obj = acpi_evaluate_dsm(ACPI_HANDLE(rtwdev->dev), &rtw89_guid,
4188
0, func, NULL);
4289
if (!obj) {
43-
rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
90+
rtw89_debug(rtwdev, RTW89_DBG_ACPI,
4491
"acpi dsm fail to evaluate func: %d\n", func);
4592
return -ENOENT;
4693
}
4794

48-
ret = rtw89_acpi_dsm_get(rtwdev, obj, value);
95+
if (func == RTW89_ACPI_DSM_FUNC_6G_BP)
96+
ret = rtw89_acpi_dsm_get_policy_6ghz(rtwdev, obj,
97+
&res->u.policy_6ghz);
98+
else
99+
ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value);
49100

50101
ACPI_FREE(obj);
51102
return ret;

drivers/net/wireless/realtek/rtw89/acpi.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,37 @@ enum rtw89_acpi_dsm_func {
1515
RTW89_ACPI_DSM_FUNC_59G_EN = 6,
1616
};
1717

18+
enum rtw89_acpi_policy_mode {
19+
RTW89_ACPI_POLICY_BLOCK = 0,
20+
RTW89_ACPI_POLICY_ALLOW = 1,
21+
};
22+
23+
struct rtw89_acpi_country_code {
24+
/* below are allowed:
25+
* * ISO alpha2 country code
26+
* * EU for countries in Europe
27+
*/
28+
char alpha2[2];
29+
} __packed;
30+
31+
struct rtw89_acpi_policy_6ghz {
32+
u8 signature[3];
33+
u8 rsvd;
34+
u8 policy_mode;
35+
u8 country_count;
36+
struct rtw89_acpi_country_code country_list[] __counted_by(country_count);
37+
} __packed;
38+
39+
struct rtw89_acpi_dsm_result {
40+
union {
41+
u8 value;
42+
/* caller needs to free it after using */
43+
struct rtw89_acpi_policy_6ghz *policy_6ghz;
44+
} u;
45+
};
46+
1847
int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
19-
enum rtw89_acpi_dsm_func func, u8 *value);
48+
enum rtw89_acpi_dsm_func func,
49+
struct rtw89_acpi_dsm_result *res);
2050

2151
#endif

drivers/net/wireless/realtek/rtw89/debug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum rtw89_debug_mask {
2929
RTW89_DBG_WOW = BIT(18),
3030
RTW89_DBG_UL_TB = BIT(19),
3131
RTW89_DBG_CHAN = BIT(20),
32+
RTW89_DBG_ACPI = BIT(21),
3233

3334
RTW89_DBG_UNEXP = BIT(31),
3435
};

drivers/net/wireless/realtek/rtw89/regd.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,19 +291,22 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
291291
const struct rtw89_chip_info *chip = rtwdev->chip;
292292
bool regd_allow_unii_4 = chip->support_unii4;
293293
struct ieee80211_supported_band *sband;
294+
struct rtw89_acpi_dsm_result res = {};
294295
int ret;
295296
u8 val;
296297

297298
if (!chip->support_unii4)
298299
goto bottom;
299300

300-
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_59G_EN, &val);
301+
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_59G_EN, &res);
301302
if (ret) {
302303
rtw89_debug(rtwdev, RTW89_DBG_REGD,
303304
"acpi: cannot eval unii 4: %d\n", ret);
304305
goto bottom;
305306
}
306307

308+
val = res.u.value;
309+
307310
rtw89_debug(rtwdev, RTW89_DBG_REGD,
308311
"acpi: eval if allow unii 4: %d\n", val);
309312

@@ -338,19 +341,22 @@ static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
338341
bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ);
339342
bool regd_allow_6ghz = chip_support_6ghz;
340343
struct ieee80211_supported_band *sband;
344+
struct rtw89_acpi_dsm_result res = {};
341345
int ret;
342346
u8 val;
343347

344348
if (!chip_support_6ghz)
345349
goto bottom;
346350

347-
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &val);
351+
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6G_DIS, &res);
348352
if (ret) {
349353
rtw89_debug(rtwdev, RTW89_DBG_REGD,
350354
"acpi: cannot eval 6ghz: %d\n", ret);
351355
goto bottom;
352356
}
353357

358+
val = res.u.value;
359+
354360
rtw89_debug(rtwdev, RTW89_DBG_REGD,
355361
"acpi: eval if disallow 6ghz: %d\n", val);
356362

drivers/net/wireless/realtek/rtw89/sar.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,16 +404,18 @@ static void rtw89_tas_state_update(struct rtw89_dev *rtwdev)
404404
void rtw89_tas_init(struct rtw89_dev *rtwdev)
405405
{
406406
struct rtw89_tas_info *tas = &rtwdev->tas;
407+
struct rtw89_acpi_dsm_result res = {};
407408
int ret;
408409
u8 val;
409410

410-
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &val);
411+
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &res);
411412
if (ret) {
412413
rtw89_debug(rtwdev, RTW89_DBG_SAR,
413414
"acpi: cannot get TAS: %d\n", ret);
414415
return;
415416
}
416417

418+
val = res.u.value;
417419
switch (val) {
418420
case 0:
419421
tas->enable = false;

0 commit comments

Comments
 (0)