mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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: Wen Gong <quic_wgong@quicinc.com> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://msgid.link/20231218085844.2658-2-quic_bqiang@quicinc.com
This commit is contained in:
parent
fba97a777d
commit
e3d373ec4f
3 changed files with 62 additions and 17 deletions
|
@ -618,25 +618,68 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab,
|
|||
*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 *
|
||||
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 cur_reg_rule *reg_rule;
|
||||
struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
|
||||
u8 i = 0, j = 0, k = 0;
|
||||
u8 num_rules;
|
||||
u16 max_bw;
|
||||
u32 flags;
|
||||
u32 flags, reg_6ghz_number, max_bw_6ghz;
|
||||
char alpha2[3];
|
||||
|
||||
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.
|
||||
* This can be updated after complete 6 GHz regulatory support is added.
|
||||
*/
|
||||
if (reg_info->is_ext_reg_event)
|
||||
num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
|
||||
if (reg_info->is_ext_reg_event) {
|
||||
if (vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
enum wmi_reg_6ghz_ap_type ap_type;
|
||||
|
||||
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)
|
||||
goto ret;
|
||||
|
@ -683,13 +726,10 @@ ath11k_reg_build_regd(struct ath11k_base *ab,
|
|||
* per other BW rule flags we pass from here
|
||||
*/
|
||||
flags = NL80211_RRF_AUTO_BW;
|
||||
} else if (reg_info->is_ext_reg_event &&
|
||||
reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] &&
|
||||
(k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) {
|
||||
reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] +
|
||||
k++;
|
||||
max_bw = min_t(u16, reg_rule->max_bw,
|
||||
reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]);
|
||||
} else if (reg_info->is_ext_reg_event && reg_6ghz_number &&
|
||||
k < reg_6ghz_number) {
|
||||
reg_rule = reg_rule_6ghz + k++;
|
||||
max_bw = min_t(u16, reg_rule->max_bw, max_bw_6ghz);
|
||||
flags = NL80211_RRF_AUTO_BW;
|
||||
} else {
|
||||
break;
|
||||
|
|
|
@ -34,7 +34,11 @@ void ath11k_reg_free(struct ath11k_base *ab);
|
|||
void ath11k_regd_update_work(struct work_struct *work);
|
||||
struct ieee80211_regdomain *
|
||||
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_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
|
||||
|
|
|
@ -7151,7 +7151,8 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
|
|||
!ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
|
||||
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) {
|
||||
ath11k_warn(ab, "failed to build regd from reg_info\n");
|
||||
goto fallback;
|
||||
|
|
Loading…
Add table
Reference in a new issue