From 6efce6c5dd11ca4d0b34cd8472589a07f77d555c Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 3 Aug 2017 16:58:38 -0700 Subject: [PATCH] qcacmn: Add logic to force SCC in SAP+STA concurrency - Part 2 If STA is up on a a DFS or passive or LTE unsafe channel & SAP is comings up that causes MCC, move SAP to the other band if DBS is supported. This logic is enabled only if gWlanMccToSccSwitchMode is set to QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION. Change-Id: I5d393a21301f3fa838f7cf38620fb1d57ae1d57a CRs-Fixed: 2063060 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 36 +++++++++ .../policy_mgr/src/wlan_policy_mgr_action.c | 73 +++++++++++++++++++ .../src/wlan_policy_mgr_get_set_utils.c | 16 ++++ .../policy_mgr/src/wlan_policy_mgr_i.h | 16 ++++ .../policy_mgr/src/wlan_policy_mgr_pcl.c | 50 ++++++++++++- 5 files changed, 188 insertions(+), 3 deletions(-) diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index b5fbfb5ecd64..a5a0ef670efd 100644 --- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1947,4 +1947,40 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( */ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, uint8_t channel); + +/** + * policy_mgr_is_force_scc() - checks if SCC needs to be + * mandated + * @psoc: PSOC object information + * + * This function checks if SCC needs to be mandated or not + * + * Return: True if SCC to be mandated, false otherwise + */ +bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_valid_sap_conc_channel_check() - checks & updates + * the channel SAP to come up on in case of STA+SAP concurrency + * @psoc: PSOC object information + * @con_ch: pointer to the channel on which sap will come up + * @sap_ch: initial channel for SAP + * + * This function checks & updates the channel SAP to come up on in + * case of STA+SAP concurrency + * Return: Success if SAP can come up on a channel + */ +QDF_STATUS policy_mgr_valid_sap_conc_channel_check( + struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch); + +/** + * policy_mgr_get_alternate_channel_for_sap() - Get an alternate + * channel to move the SAP to + * @psoc: PSOC object information + * + * This function returns an alternate channel for SAP to move to + * Return: The new channel for SAP + */ +uint8_t policy_mgr_get_alternate_channel_for_sap( + struct wlan_objmgr_psoc *psoc); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index b0d3a368609a..6ed459865219 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -728,6 +728,79 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, return true; } +QDF_STATUS policy_mgr_valid_sap_conc_channel_check( + struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch) +{ + uint8_t channel = *con_ch; + uint8_t temp_channel = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + /* + * if force SCC is set, Check if conc channel is DFS + * or passive or part of LTE avoided channel list. + * In that case move SAP to other band if DBS is supported, + * return otherwise + */ + if (!policy_mgr_is_force_scc(psoc)) + return QDF_STATUS_SUCCESS; + + /* + * if interference is 0, check if it is DBS case. If DBS case + * return from here. If SCC, check further if SAP can move to + * STA's channel. + */ + if (!channel && + (sap_ch != policy_mgr_mode_specific_get_channel( + psoc, PM_STA_MODE))) + return QDF_STATUS_SUCCESS; + else if (!channel) + channel = sap_ch; + + if (policy_mgr_valid_sta_channel_check(psoc, channel)) { + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) || + wlan_reg_is_passive_or_disable_ch( + pm_ctx->pdev, channel) || + !policy_mgr_is_safe_channel(psoc, channel)) { + if (policy_mgr_is_hw_dbs_capable(psoc)) { + temp_channel = + policy_mgr_get_alternate_channel_for_sap(psoc); + policy_mgr_debug("temp_channel is %d", + temp_channel); + if (temp_channel) { + channel = temp_channel; + } else { + if (WLAN_REG_IS_5GHZ_CH(channel)) + channel = PM_24_GHZ_CHANNEL_6; + else + channel = PM_5_GHZ_CHANNEL_36; + } + if (!policy_mgr_is_safe_channel( + psoc, channel)) { + policy_mgr_warn( + "Can't have concurrency on %d as it is not safe", + channel); + return QDF_STATUS_E_FAILURE; + } + } else { + policy_mgr_warn("Can't have concurrency on %d", + channel); + return QDF_STATUS_E_FAILURE; + } + } + } + + if (channel != sap_ch) + *con_ch = channel; + + return QDF_STATUS_SUCCESS; +} + /** * policy_mgr_check_concurrent_intf_and_restart_sap() - Check * concurrent change intf diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 0909847e1afc..ba337ab71ae1 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -2627,3 +2627,19 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( return QDF_STATUS_SUCCESS; } + +bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return 0; + } + + return ((pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) || + (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)); +} diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index d27b3e71add1..f285bfce9ed0 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -43,6 +43,9 @@ #define CONNECTION_UPDATE_TIMEOUT 1000 #endif +#define PM_24_GHZ_CHANNEL_6 (6) +#define PM_5_GHZ_CHANNEL_36 (36) + /** * Policy Mgr hardware mode list bit-mask definitions. * Bits 4:0, 31:29 are unused. @@ -426,4 +429,17 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, struct regulatory_channel *chan_list, struct avoid_freq_ind_data *avoid_freq_ind, void *arg); + +/** + * policy_mgr_mode_specific_get_channel() - Get channel for a + * connection type + * @psoc: PSOC object information + * @chan_list: Connection type + * + * Get channel for a connection type + * + * Return: channel number + */ +uint8_t policy_mgr_mode_specific_get_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); #endif diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index 09b4009d70f4..84b0197084e0 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -41,7 +41,6 @@ #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" -#define PM_24_GHZ_CHANNEL_6 (6) /** * first_connection_pcl_table - table which provides PCL for the * very first connection in the system @@ -1653,8 +1652,9 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, */ for (i = 0; i < weight->saved_num_chan; i++) { if (policy_mgr_allow_concurrency(psoc, PM_STA_MODE, - weight->saved_chan_list[i], - HW_MODE_20_MHZ)) { + weight->saved_chan_list[i], + HW_MODE_20_MHZ) && + !policy_mgr_is_force_scc(psoc)) { weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; } @@ -1677,3 +1677,47 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } + +uint8_t policy_mgr_mode_specific_get_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) +{ + uint32_t conn_index; + uint8_t channel = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return channel; + } + /* provides the channel for the first matching mode type */ + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + pm_conc_connection_list[conn_index].in_use) { + channel = pm_conc_connection_list[conn_index].chan; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return channel; +} + +uint8_t policy_mgr_get_alternate_channel_for_sap( + struct wlan_objmgr_psoc *psoc) +{ + uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; + uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; + uint8_t channel = 0; + uint32_t pcl_len; + + if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE, + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) { + channel = pcl_channels[0]; + } + + return channel; +}