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
This commit is contained in:
Tushnim Bhattacharyya 2017-08-03 16:58:38 -07:00 • committed by snandini
commit 6efce6c5dd
5 changed files with 188 additions and 3 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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));
}

View file

@ -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

View file

@ -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;
}