diff options
author | Zong-Zhe Yang <kevin_yang@realtek.com> | 2024-04-12 19:57:28 +0800 |
---|---|---|
committer | Ping-Ke Shih <pkshih@realtek.com> | 2024-04-18 09:11:10 +0800 |
commit | d03aeddf34ca0e2fbb6b9b81d1d11728e1b364f5 (patch) | |
tree | 8e80bc57a3fe6be4e99bfc9c3aa7a7eadb23fabb | |
parent | d3c846367e3157704a2da29e5962dc6ef5300503 (diff) |
wifi: rtw89: acpi: process 6 GHz SP policy from ACPI DSM
Realtek ACPI DSM func 7, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, accepts a format
via ACPI buffer as below.
| index | description |
--------------------------------------------
| [0-3] | signature |
| [4] | revision |
| [5] | override driver settings, or not |
| [6] | configuration if override |
| [7] | reserved |
where field of [6] is a bitmap by country,
and for now, only define BIT(0) is for US.
Through this function with overriding, BIOS can indicate to allow/block
6 GHz SP power by country.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/20240412115729.8316-8-pkshih@realtek.com
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/acpi.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/acpi.h | 14 |
2 files changed, 61 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/acpi.c b/drivers/net/wireless/realtek/rtw89/acpi.c index 2e7326a8e3e4..908e980a4b72 100644 --- a/drivers/net/wireless/realtek/rtw89/acpi.c +++ b/drivers/net/wireless/realtek/rtw89/acpi.c @@ -77,6 +77,50 @@ int rtw89_acpi_dsm_get_policy_6ghz(struct rtw89_dev *rtwdev, return 0; } +static bool chk_acpi_policy_6ghz_sp_sig(const struct rtw89_acpi_policy_6ghz_sp *p) +{ + return p->signature[0] == 0x52 && + p->signature[1] == 0x54 && + p->signature[2] == 0x4B && + p->signature[3] == 0x07; +} + +static +int rtw89_acpi_dsm_get_policy_6ghz_sp(struct rtw89_dev *rtwdev, + union acpi_object *obj, + struct rtw89_acpi_policy_6ghz_sp **policy) +{ + const struct rtw89_acpi_policy_6ghz_sp *ptr; + u32 buf_len; + + if (obj->type != ACPI_TYPE_BUFFER) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, + "acpi: expect buffer but type: %d\n", obj->type); + return -EINVAL; + } + + buf_len = obj->buffer.length; + if (buf_len < sizeof(*ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: invalid buffer length: %u\n", + __func__, buf_len); + return -EINVAL; + } + + ptr = (typeof(ptr))obj->buffer.pointer; + if (!chk_acpi_policy_6ghz_sp_sig(ptr)) { + rtw89_debug(rtwdev, RTW89_DBG_ACPI, "%s: bad signature\n", __func__); + return -EINVAL; + } + + *policy = kmemdup(ptr, sizeof(*ptr), GFP_KERNEL); + if (!*policy) + return -ENOMEM; + + rtw89_hex_dump(rtwdev, RTW89_DBG_ACPI, "policy_6ghz_sp: ", *policy, + sizeof(*ptr)); + return 0; +} + int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, enum rtw89_acpi_dsm_func func, struct rtw89_acpi_dsm_result *res) @@ -95,6 +139,9 @@ int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, if (func == RTW89_ACPI_DSM_FUNC_6G_BP) ret = rtw89_acpi_dsm_get_policy_6ghz(rtwdev, obj, &res->u.policy_6ghz); + else if (func == RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP) + ret = rtw89_acpi_dsm_get_policy_6ghz_sp(rtwdev, obj, + &res->u.policy_6ghz_sp); else ret = rtw89_acpi_dsm_get_value(rtwdev, obj, &res->u.value); diff --git a/drivers/net/wireless/realtek/rtw89/acpi.h b/drivers/net/wireless/realtek/rtw89/acpi.h index 5182797e68b6..d274be1775bf 100644 --- a/drivers/net/wireless/realtek/rtw89/acpi.h +++ b/drivers/net/wireless/realtek/rtw89/acpi.h @@ -13,6 +13,7 @@ enum rtw89_acpi_dsm_func { RTW89_ACPI_DSM_FUNC_6G_BP = 4, RTW89_ACPI_DSM_FUNC_TAS_EN = 5, RTW89_ACPI_DSM_FUNC_UNII4_SUP = 6, + RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP = 7, }; enum rtw89_acpi_conf_unii4 { @@ -41,11 +42,24 @@ struct rtw89_acpi_policy_6ghz { struct rtw89_acpi_country_code country_list[] __counted_by(country_count); } __packed; +enum rtw89_acpi_conf_6ghz_sp { + RTW89_ACPI_CONF_6GHZ_SP_US = BIT(0), +}; + +struct rtw89_acpi_policy_6ghz_sp { + u8 signature[4]; + u8 revision; + u8 override; + u8 conf; + u8 rsvd; +} __packed; + struct rtw89_acpi_dsm_result { union { u8 value; /* caller needs to free it after using */ struct rtw89_acpi_policy_6ghz *policy_6ghz; + struct rtw89_acpi_policy_6ghz_sp *policy_6ghz_sp; } u; }; |