From b8db936cfe6b0fc0174ac154df2ad9cfb0cc24b5 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Fri, 3 May 2019 16:50:22 +0530 Subject: [PATCH] qcacld-3.0: Select a different channel than self for SAP restart Scenario of the issue is :- 1. Keep sta+sap_scc_dfs_ch as 0 to disable the dfs concurrency 2. Start a SAP on any 5ghz channel(NON-DFS). 3. Start a STA on a DFS channel. Expectation: The SAP should not do MCC, SCC as the above mentioned ini is 0, also MCC is not prefereed in a HW solution where DFS is preferred, hence the SAP should go to 2.4ghz and DBS should be the expectation. Observation: The SAP does not do a DBS operation, and falls to MCC here. Reason: When the SAP gets a PCL in the path of SAP restart, the PCL feels that a new SAP is going to come up, and hence gives the best channel (first element of PCL ) as its own, which leads to restart being rejected, as the SAP cannot start on a channel which is the same as existing. The final channel then selected is the STA channel, leading to DFS SCC which is also not allowed. Hence the SAP is now stuck in MCC(STA+SAP , one on DFS, and the other on NON-DFS channel). Fix: The fix is to get an alternate channel for SAP restart, other than the channel on which the SAP is already up, to lead to DBS, if the STA channel is not suitable for SCC operaion. Change-Id: Iab3ad22b2f970ca26ce3e6bc7a9b5ee34bc7e7ba CRs-Fixed: 2443718 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 9 ++++- .../policy_mgr/src/wlan_policy_mgr_action.c | 7 +++- .../policy_mgr/src/wlan_policy_mgr_pcl.c | 37 +++++++++++++++++-- core/hdd/src/wlan_hdd_hostapd.c | 9 ++--- core/sap/src/sap_fsm.c | 3 +- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index fb5c339d5ced..a9c619c06f9c 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -2555,24 +2555,29 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc); * @psoc: PSOC object information * @con_ch: pointer to the channel on which sap will come up * @sap_ch: initial channel for SAP + * @sap_vdev_id: sap vdev id. * * 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); + struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch, + uint8_t sap_vdev_id); /** * policy_mgr_get_alternate_channel_for_sap() - Get an alternate * channel to move the SAP to * @psoc: PSOC object information + * @sap_vdev_id: sap vdev id. + * @sap_channel: sap channel. * * 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); + struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id, + uint8_t sap_channel); /** * policy_mgr_disallow_mcc() - Check for mcc diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index ec7384e72211..1d58a84b3432 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -1742,7 +1742,8 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, } QDF_STATUS policy_mgr_valid_sap_conc_channel_check( - struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch) + struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch, + uint8_t sap_vdev_id) { uint8_t channel = *con_ch; uint8_t temp_channel = 0; @@ -1795,7 +1796,9 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( if (policy_mgr_is_hw_dbs_capable(psoc)) { temp_channel = - policy_mgr_get_alternate_channel_for_sap(psoc); + policy_mgr_get_alternate_channel_for_sap(psoc, + sap_vdev_id, + sap_ch); policy_mgr_debug("temp_channel is %d", temp_channel); if (temp_channel) { 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 759ab8e00068..dbfce21b2386 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 @@ -1997,18 +1997,49 @@ uint8_t policy_mgr_mode_specific_get_channel( } uint8_t policy_mgr_get_alternate_channel_for_sap( - struct wlan_objmgr_psoc *psoc) + struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id, + uint8_t sap_channel) { uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; uint8_t channel = 0; uint32_t pcl_len = 0; + struct policy_mgr_conc_connection_info info; + uint8_t num_cxn_del = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t i; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return 0; + } + + /* + * Store the connection's parameter and temporarily delete it + * from the concurrency table. This way the get pcl can be used as a + * new connection is coming up, after check, restore the connection to + * concurrency table. + */ + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id, + &info, &num_cxn_del); if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE, - &pcl_channels[0], &pcl_len, + pcl_channels, &pcl_len, pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) { - channel = pcl_channels[0]; + for (i = 0; i < pcl_len; i++) { + if (pcl_channels[i] == sap_channel) + continue; + channel = pcl_channels[i]; + break; + } } + /* Restore the connection entry */ + if (num_cxn_del > 0) + policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return channel; } + diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 45bbc36e7b30..5ccb73c3c5ac 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -3045,7 +3045,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( { mac_handle_t mac_handle; struct hdd_ap_ctx *hdd_ap_ctx; - uint8_t intf_ch = 0; + uint8_t intf_ch = 0, sap_ch = 0; struct hdd_context *hdd_ctx; struct hdd_station_ctx *hdd_sta_ctx; struct hdd_adapter *sta_adapter; @@ -3053,6 +3053,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( struct ch_params ch_params; struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev( psoc, vdev_id); + if (!ap_adapter) { hdd_err("ap_adapter is NULL"); return QDF_STATUS_E_FAILURE; @@ -3115,12 +3116,10 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( hdd_info("intf_ch: %d", intf_ch); if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION != mcc_to_scc_switch) { + policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch); if (QDF_IS_STATUS_ERROR( policy_mgr_valid_sap_conc_channel_check( - hdd_ctx->psoc, - &intf_ch, - policy_mgr_mode_specific_get_channel( - hdd_ctx->psoc, PM_SAP_MODE)))) { + hdd_ctx->psoc, &intf_ch, sap_ch, vdev_id))) { hdd_debug("can't move sap to %d", hdd_sta_ctx->conn_info.channel); return QDF_STATUS_E_FAILURE; diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 6defd9963558..cabba709ab33 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -854,7 +854,8 @@ sap_validate_chan(struct sap_context *sap_context, if (QDF_IS_STATUS_ERROR( policy_mgr_valid_sap_conc_channel_check( mac_ctx->psoc, &con_ch, - sap_context->channel))) { + sap_context->channel, + sap_context->sessionId))) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, FL("SAP can't start (no MCC)"));