@@ -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+
45084668static 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 ) {
0 commit comments