Commit e3d373ec authored by Wen Gong's avatar Wen Gong Committed by Kalle Valo

wifi: ath11k: add support to select 6 GHz regulatory type

There are 3 types of regulatory rules for AP mode and 6 type for
station mode. Add wmi_vdev_type and ieee80211_ap_reg_power to
select the exact reg rules.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
Signed-off-by: default avatarWen Gong <quic_wgong@quicinc.com>
Signed-off-by: default avatarBaochen Qiang <quic_bqiang@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20231218085844.2658-2-quic_bqiang@quicinc.com
parent fba97a77
...@@ -618,25 +618,68 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, ...@@ -618,25 +618,68 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
*rule_idx = i; *rule_idx = i;
} }
enum wmi_reg_6ghz_ap_type
ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type)
{
switch (power_type) {
case IEEE80211_REG_LPI_AP:
return WMI_REG_INDOOR_AP;
case IEEE80211_REG_SP_AP:
return WMI_REG_STANDARD_POWER_AP;
case IEEE80211_REG_VLP_AP:
return WMI_REG_VERY_LOW_POWER_AP;
default:
return WMI_REG_MAX_AP_TYPE;
}
}
struct ieee80211_regdomain * struct ieee80211_regdomain *
ath11k_reg_build_regd(struct ath11k_base *ab, ath11k_reg_build_regd(struct ath11k_base *ab,
struct cur_regulatory_info *reg_info, bool intersect) struct cur_regulatory_info *reg_info, bool intersect,
enum wmi_vdev_type vdev_type,
enum ieee80211_ap_reg_power power_type)
{ {
struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
struct cur_reg_rule *reg_rule; struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
u8 i = 0, j = 0, k = 0; u8 i = 0, j = 0, k = 0;
u8 num_rules; u8 num_rules;
u16 max_bw; u16 max_bw;
u32 flags; u32 flags, reg_6ghz_number, max_bw_6ghz;
char alpha2[3]; char alpha2[3];
num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules; num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules;
/* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list. if (reg_info->is_ext_reg_event) {
* This can be updated after complete 6 GHz regulatory support is added. if (vdev_type == WMI_VDEV_TYPE_STA) {
*/ enum wmi_reg_6ghz_ap_type ap_type;
if (reg_info->is_ext_reg_event)
num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; ap_type = ath11k_reg_ap_pwr_convert(power_type);
if (ap_type == WMI_REG_MAX_AP_TYPE)
ap_type = WMI_REG_INDOOR_AP;
reg_6ghz_number = reg_info->num_6ghz_rules_client
[ap_type][WMI_REG_DEFAULT_CLIENT];
if (reg_6ghz_number == 0) {
ap_type = WMI_REG_INDOOR_AP;
reg_6ghz_number = reg_info->num_6ghz_rules_client
[ap_type][WMI_REG_DEFAULT_CLIENT];
}
reg_rule_6ghz = reg_info->reg_rules_6ghz_client_ptr
[ap_type][WMI_REG_DEFAULT_CLIENT];
max_bw_6ghz = reg_info->max_bw_6ghz_client
[ap_type][WMI_REG_DEFAULT_CLIENT];
} else {
reg_6ghz_number = reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
reg_rule_6ghz =
reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP];
max_bw_6ghz = reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP];
}
num_rules += reg_6ghz_number;
}
if (!num_rules) if (!num_rules)
goto ret; goto ret;
...@@ -683,13 +726,10 @@ ath11k_reg_build_regd(struct ath11k_base *ab, ...@@ -683,13 +726,10 @@ ath11k_reg_build_regd(struct ath11k_base *ab,
* per other BW rule flags we pass from here * per other BW rule flags we pass from here
*/ */
flags = NL80211_RRF_AUTO_BW; flags = NL80211_RRF_AUTO_BW;
} else if (reg_info->is_ext_reg_event && } else if (reg_info->is_ext_reg_event && reg_6ghz_number &&
reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] && k < reg_6ghz_number) {
(k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) { reg_rule = reg_rule_6ghz + k++;
reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] + max_bw = min_t(u16, reg_rule->max_bw, max_bw_6ghz);
k++;
max_bw = min_t(u16, reg_rule->max_bw,
reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]);
flags = NL80211_RRF_AUTO_BW; flags = NL80211_RRF_AUTO_BW;
} else { } else {
break; break;
......
...@@ -34,7 +34,11 @@ void ath11k_reg_free(struct ath11k_base *ab); ...@@ -34,7 +34,11 @@ void ath11k_reg_free(struct ath11k_base *ab);
void ath11k_regd_update_work(struct work_struct *work); void ath11k_regd_update_work(struct work_struct *work);
struct ieee80211_regdomain * struct ieee80211_regdomain *
ath11k_reg_build_regd(struct ath11k_base *ab, ath11k_reg_build_regd(struct ath11k_base *ab,
struct cur_regulatory_info *reg_info, bool intersect); struct cur_regulatory_info *reg_info, bool intersect,
enum wmi_vdev_type vdev_type,
enum ieee80211_ap_reg_power power_type);
int ath11k_regd_update(struct ath11k *ar); int ath11k_regd_update(struct ath11k *ar);
int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait);
enum wmi_reg_6ghz_ap_type
ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
#endif #endif
...@@ -7151,7 +7151,8 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, ...@@ -7151,7 +7151,8 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
!ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
intersect = true; intersect = true;
regd = ath11k_reg_build_regd(ab, reg_info, intersect); regd = ath11k_reg_build_regd(ab, reg_info, intersect,
WMI_VDEV_TYPE_AP, IEEE80211_REG_LPI_AP);
if (!regd) { if (!regd) {
ath11k_warn(ab, "failed to build regd from reg_info\n"); ath11k_warn(ab, "failed to build regd from reg_info\n");
goto fallback; goto fallback;
......
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