Skip to content

Commit 8ae32da

Browse files
UPSTREAM: wifi: ath12k: support OBSS PD configuration for AP mode
Configure HE OBSS PD for spatial reuse in ath12k based on mac80211 HE SPR parameters in AP mode. This adds a pdev-level helper that programs SRG/non-SRG OBSS PD thresholds, per-AC enablement, SR prohibit control, and SRG/non-SRG BSS color and partial BSSID bitmaps via WMI. Replace the previous vdev-level OBSS SPR command usage with the new pdev-level configuration path, allowing firmware to apply HE spatial reuse behavior according to the HE SPR/OBSS PD settings provided by mac80211. Tested-on: WCN7850 hw2.0 PCI WLAN.IOE_HMT.1.1-00011-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Tested-on: QCN9274 hw2.0 WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Link: https://lore.kernel.org/linux-wireless/20260123064817.364047-3-wei.zhang@oss.qualcomm.com/ Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
1 parent cedcd02 commit 8ae32da

3 files changed

Lines changed: 171 additions & 3 deletions

File tree

drivers/net/wireless/ath/ath12k/mac.c

Lines changed: 167 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4505,6 +4505,166 @@ static void ath12k_wmi_vdev_params_up(struct ath12k *ar,
45054505
arvif->vdev_id, ret);
45064506
}
45074507

4508+
static int ath12k_mac_config_obss_pd(struct ath12k_link_vif *arvif,
4509+
const struct ieee80211_he_obss_pd *he_obss_pd)
4510+
{
4511+
struct ath12k_wmi_obss_pd_arg obss_pd_arg = {};
4512+
u32 srg_bitmap[2], non_srg_bitmap[2];
4513+
struct ath12k *ar = arvif->ar;
4514+
u32 param_id, pdev_id;
4515+
u32 param_val;
4516+
int ret;
4517+
4518+
if (ar->ab->hw_params->single_pdev_only)
4519+
pdev_id = ath12k_mac_get_target_pdev_id_from_vif(arvif);
4520+
else
4521+
pdev_id = ar->pdev->pdev_id;
4522+
4523+
/* Set and enable SRG/non-SRG OBSS PD threshold */
4524+
param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
4525+
if (ar->monitor_started || !he_obss_pd->enable) {
4526+
ret = ath12k_wmi_pdev_set_param(ar, param_id, 0, pdev_id);
4527+
if (ret)
4528+
ath12k_warn(ar->ab,
4529+
"failed to set OBSS PD threshold for pdev %u: %d\n",
4530+
pdev_id, ret);
4531+
return ret;
4532+
}
4533+
4534+
/*
4535+
* This service flag indicates firmware support for SRG/SRP-based
4536+
* spatial reuse. It also specifies whether OBSS PD threshold values
4537+
* should be interpreted as dB (offset) or dBm (absolute) units.
4538+
*/
4539+
obss_pd_arg.srp_support = test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT,
4540+
ar->ab->wmi_ab.svc_map);
4541+
4542+
if (!(he_obss_pd->sr_ctrl &
4543+
IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED)) {
4544+
if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
4545+
obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD +
4546+
he_obss_pd->non_srg_max_offset;
4547+
else
4548+
obss_pd_arg.non_srg_th = ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD;
4549+
4550+
if (!obss_pd_arg.srp_support)
4551+
obss_pd_arg.non_srg_th -= ATH12K_DEFAULT_NOISE_FLOOR;
4552+
4553+
obss_pd_arg.non_srg_enabled = true;
4554+
}
4555+
4556+
if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) {
4557+
obss_pd_arg.srg_th = ATH12K_OBSS_PD_MAX_THRESHOLD +
4558+
he_obss_pd->max_offset;
4559+
obss_pd_arg.srg_enabled = true;
4560+
}
4561+
4562+
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
4563+
"pdev %u OBSS PD sr_ctrl 0x%x srg_th %d dBm non_srg_th %d dBm\n",
4564+
pdev_id, he_obss_pd->sr_ctrl,
4565+
obss_pd_arg.srg_th, obss_pd_arg.non_srg_th);
4566+
4567+
param_val = ath12k_wmi_build_obss_pd(&obss_pd_arg);
4568+
ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
4569+
if (ret) {
4570+
ath12k_warn(ar->ab,
4571+
"failed to set OBSS PD threshold for pdev %u: %d\n",
4572+
pdev_id, ret);
4573+
return ret;
4574+
}
4575+
4576+
/* Enable OBSS PD for all access category */
4577+
param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC;
4578+
param_val = 0xf;
4579+
ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
4580+
if (ret) {
4581+
ath12k_warn(ar->ab,
4582+
"failed to set OBSS PD per ac for pdev %u: %d\n",
4583+
pdev_id, ret);
4584+
return ret;
4585+
}
4586+
4587+
/* Set SR prohibit */
4588+
param_id = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT;
4589+
param_val = !!(he_obss_pd->sr_ctrl &
4590+
IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED);
4591+
ret = ath12k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
4592+
if (ret) {
4593+
ath12k_warn(ar->ab, "failed to set SR prohibit for pdev %u: %d\n",
4594+
pdev_id, ret);
4595+
return ret;
4596+
}
4597+
4598+
if (!obss_pd_arg.srp_support)
4599+
return 0;
4600+
4601+
memcpy(srg_bitmap, he_obss_pd->bss_color_bitmap, sizeof(srg_bitmap));
4602+
/* Set SRG BSS color bitmap */
4603+
ret = ath12k_wmi_pdev_set_srg_bss_color_bitmap(ar, pdev_id, srg_bitmap);
4604+
if (ret) {
4605+
ath12k_warn(ar->ab,
4606+
"failed to set SRG bss color bitmap for pdev %u: %d\n",
4607+
pdev_id, ret);
4608+
return ret;
4609+
}
4610+
4611+
/* Enable BSS colors for SRG */
4612+
ret = ath12k_wmi_pdev_srg_obss_color_enable_bitmap(ar, pdev_id, srg_bitmap);
4613+
if (ret) {
4614+
ath12k_warn(ar->ab,
4615+
"failed to enable SRG bss color bitmap pdev %u: %d\n",
4616+
pdev_id, ret);
4617+
return ret;
4618+
}
4619+
4620+
memcpy(srg_bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(srg_bitmap));
4621+
/* Set SRG partial bssid bitmap */
4622+
ret = ath12k_wmi_pdev_set_srg_partial_bssid_bitmap(ar, pdev_id, srg_bitmap);
4623+
if (ret) {
4624+
ath12k_warn(ar->ab,
4625+
"failed to set SRG partial bssid bitmap for pdev %u: %d\n",
4626+
pdev_id, ret);
4627+
return ret;
4628+
}
4629+
4630+
/* Enable partial bssid mask for SRG */
4631+
ret = ath12k_wmi_pdev_srg_obss_bssid_enable_bitmap(ar, pdev_id, srg_bitmap);
4632+
if (ret) {
4633+
ath12k_warn(ar->ab,
4634+
"failed to enable SRG bssid bitmap pdev %u: %d\n",
4635+
pdev_id, ret);
4636+
return ret;
4637+
}
4638+
4639+
/*
4640+
* No explicit non-SRG bitmap from mac80211; enable all colors/bssids
4641+
* as non-SRG candidates. Actual SRG members are filtered by SRG bitmaps.
4642+
*/
4643+
memset(non_srg_bitmap, 0xff, sizeof(non_srg_bitmap));
4644+
4645+
/* Enable BSS colors for non-SRG */
4646+
ret = ath12k_wmi_pdev_non_srg_obss_color_enable_bitmap(ar, pdev_id,
4647+
non_srg_bitmap);
4648+
if (ret) {
4649+
ath12k_warn(ar->ab,
4650+
"failed to enable non SRG color bitmap pdev %u: %d\n",
4651+
pdev_id, ret);
4652+
return ret;
4653+
}
4654+
4655+
/* Enable partial bssid mask for non-SRG */
4656+
ret = ath12k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(ar, pdev_id,
4657+
non_srg_bitmap);
4658+
if (ret) {
4659+
ath12k_warn(ar->ab,
4660+
"failed to enable non SRG bssid bitmap pdev %u: %d\n",
4661+
pdev_id, ret);
4662+
return ret;
4663+
}
4664+
4665+
return 0;
4666+
}
4667+
45084668
static void ath12k_mac_bss_info_changed(struct ath12k *ar,
45094669
struct ath12k_link_vif *arvif,
45104670
struct ieee80211_bss_conf *info,
@@ -4796,9 +4956,13 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar,
47964956
ath12k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
47974957
}
47984958

4799-
if (changed & BSS_CHANGED_HE_OBSS_PD)
4800-
ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
4801-
&info->he_obss_pd);
4959+
if (changed & BSS_CHANGED_HE_OBSS_PD) {
4960+
if (vif->type == NL80211_IFTYPE_AP)
4961+
ath12k_mac_config_obss_pd(arvif, &info->he_obss_pd);
4962+
else
4963+
ath12k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
4964+
&info->he_obss_pd);
4965+
}
48024966

48034967
if (changed & BSS_CHANGED_HE_BSS_COLOR) {
48044968
if (vif->type == NL80211_IFTYPE_AP) {

drivers/net/wireless/ath/ath12k/mac.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ struct ath12k_reg_tpc_power_info {
138138
struct ath12k_chan_power_info chan_power_info[ATH12K_NUM_PWR_LEVELS];
139139
};
140140

141+
#define ATH12K_OBSS_PD_MAX_THRESHOLD -82
142+
#define ATH12K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62
143+
141144
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
142145

143146
#define ATH12K_SCAN_11D_INTERVAL 600000

drivers/net/wireless/ath/ath12k/wmi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,7 @@ enum wmi_tlv_service {
22592259
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
22602260
WMI_TLV_SERVICE_EXT2_MSG = 220,
22612261
WMI_TLV_SERVICE_BEACON_PROTECTION_SUPPORT = 244,
2262+
WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249,
22622263
WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253,
22632264

22642265
WMI_MAX_EXT_SERVICE = 256,

0 commit comments

Comments
 (0)