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