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)"));