From 7da2ef6f88e50f30e0bab0b5b5718c0c07f7fefc Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Sat, 28 May 2022 00:44:34 +0530 Subject: [PATCH] qcacld-3.0: Do not allow SAP SCC on non-PSC/non-VLP channels SAP is allowed to come up on SCC with a STA operating in 6GHz only if the STA is on a PSC channel in VLP mode. Therefore, filter out all 6GHz channels from the PCL if the STA operates on any non-VLP mode. Also, in case of VLP mode, filter out non-PSC channels. Change-Id: I37d9a510db3647fc07858af99eb614ebe824cc78 CRs-Fixed: 3206471 --- .../src/wlan_policy_mgr_get_set_utils.c | 8 ++ .../policy_mgr/src/wlan_policy_mgr_pcl.c | 102 ++++++++++++++++++ .../mlme/dispatcher/inc/wlan_mlme_api.h | 9 ++ .../mlme/dispatcher/src/wlan_mlme_api.c | 15 +++ 4 files changed, 134 insertions(+) diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 221c6632e1..637e8865b3 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -7647,11 +7647,14 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc, if (connection[i].freq != freq && policy_mgr_are_2_freq_on_same_mac(psoc, freq, connection[i].freq)) { + policy_mgr_debug("SAP:%d and STA:%d on same mac. Restart SAP ", + freq, connection[i].freq); restart_required = true; break; } if (connection[i].freq == freq && !sta_sap_scc_on_dfs_chan && sap_on_dfs) { + policy_mgr_debug("Move SAP out of DFS ch:%d", freq); restart_required = true; break; } @@ -7659,6 +7662,7 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc, if (connection[i].freq == freq && !sta_sap_scc_allowed_on_indoor_ch && wlan_reg_is_freq_indoor(pm_ctx->pdev, connection[i].freq)) { + policy_mgr_debug("Move SAP out of indoor ch:%d", freq); restart_required = true; break; } @@ -7681,6 +7685,9 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc, !wlan_reg_is_dfs_for_freq(pm_ctx->pdev, connection[i].freq) && WLAN_REG_IS_5GHZ_CH_FREQ(pm_ctx->user_config_sap_ch_freq)) { + policy_mgr_debug("Move SAP from:%d to STA ch:%d (sap start freq:%d)", + freq, connection[i].freq, + pm_ctx->user_config_sap_ch_freq); restart_required = true; if (wlan_reg_is_freq_indoor(pm_ctx->pdev, @@ -7708,6 +7715,7 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc, restart_required = true; } } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return restart_required; diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index 9f40372e17..7e2dc8f4a6 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -915,6 +915,96 @@ policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +/** + * policy_mgr_modify_sap_pcl_for_6G_channels() - filter out the + * 6GHz channels where SCC is not supported. + * @psoc: pointer to soc + * @pcl_list_org: channel list to filter out + * @weight_list_org: weight of channel list + * @pcl_len_org: length of channel list + * + * Return: QDF_STATUS + */ +static QDF_STATUS +policy_mgr_modify_sap_pcl_for_6G_channels(struct wlan_objmgr_psoc *psoc, + uint32_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t pcl_list[NUM_CHANNELS]; + uint8_t weight_list[NUM_CHANNELS]; + uint32_t vdev_id = 0, pcl_len = 0, i; + struct wlan_objmgr_vdev *vdev; + qdf_freq_t sta_gc_freq = 0; + uint32_t ap_pwr_type_6g = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (*pcl_len_org > NUM_CHANNELS) { + policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org); + return QDF_STATUS_E_FAILURE; + } + + if (policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, NULL)) { + sta_gc_freq = + policy_mgr_mode_specific_get_channel(psoc, PM_STA_MODE); + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); + } else if (policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_CLIENT_MODE, + NULL)) { + sta_gc_freq = policy_mgr_mode_specific_get_channel( + psoc, PM_P2P_CLIENT_MODE); + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, + PM_P2P_CLIENT_MODE); + } + + if (!sta_gc_freq || !WLAN_REG_IS_6GHZ_CHAN_FREQ(sta_gc_freq)) + return QDF_STATUS_SUCCESS; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_POLICY_MGR_ID); + if (!vdev) { + policy_mgr_err("vdev %d is not present", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + /* If STA is present in 6GHz, STA+SAP SCC is allowed + * only on PSC channels in VLP mode. Therefore, remove + * all other 6GHz channels from the PCL list. + * + * VLP STA in PSC + SAP - Allowed + * VLP STA in non-PSC + SAP - Not allowed + * non-VLP STA + SAP - Not allowed + */ + ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev); + policy_mgr_debug("STA power type : %d", ap_pwr_type_6g); + for (i = 0; i < *pcl_len_org; i++) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_list_org[i])) { + if (ap_pwr_type_6g != REG_VERY_LOW_POWER_AP) + continue; + else if (!WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(pcl_list_org[i])) + continue; + } + pcl_list[pcl_len] = pcl_list_org[i]; + weight_list[pcl_len++] = weight_list_org[i]; + } + + qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org)); + qdf_mem_zero(weight_list_org, *pcl_len_org * sizeof(*weight_list_org)); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org)); + qdf_mem_copy(weight_list_org, weight_list, pcl_len); + *pcl_len_org = pcl_len; + + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS policy_mgr_pcl_modification_for_sap( struct wlan_objmgr_psoc *psoc, uint32_t *pcl_channels, uint8_t *pcl_weight, @@ -975,6 +1065,14 @@ static QDF_STATUS policy_mgr_pcl_modification_for_sap( } indoor_modified_pcl = true; + status = policy_mgr_modify_sap_pcl_for_6G_channels(psoc, + pcl_channels, + pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to modify pcl for 6G channels"); + return status; + } + modified_final_pcl = true; policy_mgr_debug(" %d %d %d %d %d", mandatory_modified_pcl, @@ -1210,6 +1308,8 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, return status; } + policy_mgr_debug("PCL before modification"); + policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); policy_mgr_mode_specific_modification_on_pcl( psoc, pcl_channels, pcl_weight, len, mode); @@ -1220,6 +1320,8 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, policy_mgr_err("failed to get modified pcl based on DNBS"); return status; } + + policy_mgr_debug("PCL after modification"); policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight); return QDF_STATUS_SUCCESS; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index e34e741882..3cc649129d 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -3637,4 +3637,13 @@ void wlan_mlme_set_safe_mode_enable(struct wlan_objmgr_psoc *psoc, void wlan_mlme_get_safe_mode_enable(struct wlan_objmgr_psoc *psoc, bool *safe_mode_enable); +/** + * wlan_mlme_get_6g_ap_power_type() - get the power type of the + * vdev operating on 6GHz. + * + * @vdev: vdev context + * + * Return: 6g_power_type + */ +uint32_t wlan_mlme_get_6g_ap_power_type(struct wlan_objmgr_vdev *vdev); #endif /* _WLAN_MLME_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 4e3b90d5c0..05c78e1381 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -5788,3 +5788,18 @@ void wlan_mlme_set_safe_mode_enable(struct wlan_objmgr_psoc *psoc, mlme_obj->cfg.gen.safe_mode_enable = safe_mode_enable; } + +uint32_t wlan_mlme_get_6g_ap_power_type(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_mlme_obj *mlme_obj; + + mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); + + if (!mlme_obj) { + mlme_legacy_err("vdev component object is NULL"); + return REG_MAX_AP_TYPE; + } + + return mlme_obj->reg_tpc_obj.power_type_6g; +} +