Commit 5a84cc87 authored by Zong-Zhe Yang's avatar Zong-Zhe Yang Committed by Ping-Ke Shih

wifi: rtw89: regd: handle policy of 6 GHz SP according to BIOS

According to BIOS configuration of Realtek ACPI DSM function 7,
RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, we handle the regd policy of 6 GHz SP.

If BIOS indicates to override driver settings, we only allow the countries,
which are enabled by BIOS, to use 6 GHz SP power. Other countries will be
applied to select default power when recalculating 6 GHz regulatory power
selection.
Signed-off-by: default avatarZong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/20240412115729.8316-9-pkshih@realtek.com
parent d03aeddf
......@@ -4760,6 +4760,7 @@ struct rtw89_regulatory_info {
enum rtw89_reg_6ghz_power reg_6ghz_power;
DECLARE_BITMAP(block_unii4, RTW89_REGD_MAX_COUNTRY_NUM);
DECLARE_BITMAP(block_6ghz, RTW89_REGD_MAX_COUNTRY_NUM);
DECLARE_BITMAP(block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
};
enum rtw89_ifs_clm_application {
......
......@@ -468,6 +468,51 @@ static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev)
kfree(ptr);
}
static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_acpi_policy_6ghz_sp *ptr;
struct rtw89_acpi_dsm_result res = {};
bool enable_by_us;
int ret;
int i;
ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP, &res);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"acpi: cannot eval policy 6ghz-sp: %d\n", ret);
return;
}
ptr = res.u.policy_6ghz_sp;
switch (ptr->override) {
default:
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"%s: unknown override case: %d\n", __func__,
ptr->override);
fallthrough;
case 0:
goto out;
case 1:
break;
}
bitmap_fill(regulatory->block_6ghz_sp, RTW89_REGD_MAX_COUNTRY_NUM);
enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
const struct rtw89_regd *tmp = &rtw89_regd_map[i];
if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0)
clear_bit(i, regulatory->block_6ghz_sp);
}
out:
kfree(ptr);
}
static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
......@@ -510,6 +555,7 @@ static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
if (regd_allow_6ghz) {
rtw89_regd_setup_policy_6ghz(rtwdev);
rtw89_regd_setup_policy_6ghz_sp(rtwdev);
return;
}
......@@ -671,10 +717,12 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *regd = regulatory->regd;
enum rtw89_reg_6ghz_power sel;
const struct rtw89_chan *chan;
struct rtw89_vif *rtwvif;
int count = 0;
u8 index;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
chan = rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
......@@ -691,6 +739,17 @@ static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
if (count != 1)
sel = RTW89_REG_6GHZ_POWER_DFLT;
if (sel == RTW89_REG_6GHZ_POWER_STD) {
index = rtw89_regd_get_index(regd);
if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
test_bit(index, regulatory->block_6ghz_sp)) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"%c%c 6 GHz SP is blocked by policy\n",
regd->alpha2[0], regd->alpha2[1]);
sel = RTW89_REG_6GHZ_POWER_DFLT;
}
}
if (regulatory->reg_6ghz_power == sel)
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment