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 77a1de789755..b713c6c91265 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 @@ -64,6 +64,31 @@ typedef const enum policy_mgr_conc_next_action ((channel_select_logic_conc & PM_FW_MODE_STA_P2P_BIT_MASK) >> \ PM_FW_MODE_STA_P2P_BIT_POS) +/** + * enum sap_csa_reason_code - SAP channel switch reason code + * @CSA_REASON_UNKNOWN: Unknown reason + * @CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS: STA connection from DFS to NON DFS. + * @CSA_REASON_USER_INITIATED: User initiated form north bound. + * @CSA_REASON_PEER_ACTION_FRAME: Action frame received on sta iface. + * @CSA_REASON_PRE_CAC_SUCCESS: Pre CAC success. + * @CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL: concurrent sta changed channel. + * @CSA_REASON_UNSAFE_CHANNEL: Unsafe channel. + * @CSA_REASON_LTE_COEX: LTE coex. + * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency. + * + */ +enum sap_csa_reason_code { + CSA_REASON_UNKNOWN, + CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS, + CSA_REASON_USER_INITIATED, + CSA_REASON_PEER_ACTION_FRAME, + CSA_REASON_PRE_CAC_SUCCESS, + CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL, + CSA_REASON_UNSAFE_CHANNEL, + CSA_REASON_LTE_COEX, + CSA_REASON_CONCURRENT_NAN_EVENT +}; + /** * enum PM_AP_DFS_MASTER_MODE - AP dfs master mode * @PM_STA_SAP_ON_DFS_DEFAULT - Disallow STA+SAP SCC on DFS channel @@ -693,6 +718,8 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, * @mode: connection mode * @channel: target channel to switch * @vdev_id: vdev id of channel switch interface + * @forced: forced to chan switch. + * @reason: request reason of CSA * * There is already existing SAP+GO combination but due to upper layer * notifying LTE-COEX event or sending command to move one of the connections @@ -706,10 +733,12 @@ policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, * * Return: True/False */ -bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t channel, - uint32_t vdev_id); +bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + uint32_t vdev_id, + bool forced, + enum sap_csa_reason_code reason); /** * policy_mgr_get_first_connection_pcl_table_index() - provides the diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 52d2e0ce0d80..643d74c85a7d 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -765,6 +765,56 @@ void policy_mgr_store_and_del_conn_info_by_vdev_id( qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } +void policy_mgr_store_and_del_conn_info_by_chan_and_mode( + struct wlan_objmgr_psoc *psoc, + uint32_t chan, + enum policy_mgr_con_mode mode, + struct policy_mgr_conc_connection_info *info, + uint8_t *num_cxn_del) +{ + uint32_t conn_index = 0; + uint8_t found_index = 0; + + struct policy_mgr_psoc_priv_obj *pm_ctx; + + if (!info || !num_cxn_del) { + policy_mgr_err("Invalid parameters"); + return; + } + *num_cxn_del = 0; + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (chan != pm_conc_connection_list[conn_index].chan || + mode != pm_conc_connection_list[conn_index].mode) { + conn_index++; + continue; + } + info[found_index] = pm_conc_connection_list[conn_index]; + policy_mgr_debug("Stored %d (%d), deleted STA entry with vdev id %d, index %d ch %d", + info[found_index].vdev_id, + info[found_index].mode, + info[found_index].vdev_id, conn_index, + chan); + found_index++; + conn_index++; + } + conn_index = 0; + while (conn_index < found_index) { + policy_mgr_decr_connection_count( + psoc, info[conn_index].vdev_id); + + pm_ctx->no_of_active_sessions[info[conn_index].mode]--; + conn_index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + *num_cxn_del = found_index; +} + /** * policy_mgr_restore_deleted_conn_info() - Restore connection info * @info: An array saving connection info that is to be restored 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 85d06cbecb21..c2a5635a0a51 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 @@ -2345,28 +2345,60 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t channel, - uint32_t vdev_id) + uint32_t vdev_id, + bool forced, + enum sap_csa_reason_code reason) { bool allow = false; - struct policy_mgr_conc_connection_info info; + struct policy_mgr_conc_connection_info + info[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t num_cxn_del = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t old_chan; + QDF_STATUS status; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); return allow; } + policy_mgr_debug("check concurrency_csa vdev:%d ch %d, forced %d, reason %d", + vdev_id, channel, forced, reason); + + status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &old_chan); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to get channel for vdev:%d", + vdev_id); + return allow; + } + qdf_mem_zero(info, sizeof(info)); /* * Store the connection's parameter and temporarily delete it * from the concurrency table. This way the allow concurrency * check can be used as though a new connection is coming up, * after check, restore the connection to concurrency table. + * + * In SAP+SAP SCC case, when LTE unsafe event processing, + * we should remove the all SAP conn entry on the same ch before + * do the concurrency check. Otherwise the left SAP on old channel + * will cause the concurrency check failure because of dual beacon + * MCC not supported. for the CSA request reason code, + * PM_CSA_REASON_UNSAFE_CHANNEL, we remove all the SAP + * entry on old channel before do concurrency check. + * + * The assumption is both SAP should move to the new channel later for + * the reason code. */ qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, - &info, &num_cxn_del); + + if (forced && reason == CSA_REASON_UNSAFE_CHANNEL) + policy_mgr_store_and_del_conn_info_by_chan_and_mode( + psoc, old_chan, mode, info, &num_cxn_del); + else + policy_mgr_store_and_del_conn_info_by_vdev_id( + psoc, vdev_id, info, &num_cxn_del); + allow = policy_mgr_allow_concurrency( psoc, mode, @@ -2374,7 +2406,7 @@ bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, HW_MODE_20_MHZ); /* Restore the connection entry */ if (num_cxn_del > 0) - policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (!allow) diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index 5a1ee0ad7809..6e977fe47ad7 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -449,7 +449,7 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, * connection info by vdev id * @psoc: PSOC object information * @vdev_id: vdev id whose entry has to be deleted - * @info: struture array pointer where the connection info will be saved + * @info: structure array pointer where the connection info will be saved * @num_cxn_del: number of connection which are going to be deleted * * Saves the connection info corresponding to the provided mode @@ -464,6 +464,27 @@ void policy_mgr_store_and_del_conn_info_by_vdev_id( struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del); +/** + * policy_mgr_store_and_del_conn_info_by_chan_and_mode() - Store and del a + * connection info by chan number and conn mode + * @psoc: PSOC object information + * @chan: channel number + * @mode: conn mode + * @info: structure array pointer where the connection info will be saved + * @num_cxn_del: number of connection which are going to be deleted + * + * Saves and deletes the entries if the active connection entry chan and mode + * matches the provided chan & mode from the function parameters. + * + * Return: None + */ +void policy_mgr_store_and_del_conn_info_by_chan_and_mode( + struct wlan_objmgr_psoc *psoc, + uint32_t chan, + enum policy_mgr_con_mode mode, + struct policy_mgr_conc_connection_info *info, + uint8_t *num_cxn_del); + void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, struct policy_mgr_conc_connection_info *info, uint8_t num_cxn_del); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 1f440c2d253d..4a3a164370ba 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -2872,6 +2872,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, struct hdd_context *hdd_ctx = NULL; struct hdd_adapter *sta_adapter; struct hdd_station_ctx *sta_ctx; + struct sap_context *sap_ctx; uint8_t conc_rule1 = 0; uint8_t scc_on_lte_coex = 0; bool is_p2p_go_session = false; @@ -2881,6 +2882,12 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, if (ret) return ret; + if (adapter->device_mode != QDF_SAP_MODE && + adapter->device_mode != QDF_P2P_GO_MODE) + return -EINVAL; + sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); + if (!sap_ctx) + return -EINVAL; /* * If sta connection is in progress do not allow SAP channel change from * user space as it may change the HW mode requirement, for which sta is @@ -2945,7 +2952,9 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, policy_mgr_convert_device_mode_to_qdf_type( adapter->device_mode), target_channel, - adapter->vdev_id)) { + adapter->vdev_id, + forced, + sap_ctx->csa_reason)) { hdd_err("Channel switch failed due to concurrency check failure"); qdf_atomic_set(&adapter->ch_switch_in_progress, 0); return -EINVAL; @@ -3149,7 +3158,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( * Need to take care of 3 port cases with 2 STA iface in future. */ intf_ch = wlansap_check_cc_intf(hdd_ap_ctx->sap_context); - hdd_info("intf_ch: %d", intf_ch); + hdd_info("sap_vdev %d intf_ch: %d", vdev_id, 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); diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 89b22c3426d2..4165aca8ecd8 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -468,31 +468,6 @@ enum sap_acs_dfs_mode { ACS_DFS_MODE_DEPRIORITIZE }; -/** - * enum sap_csa_reason_code - SAP channel switch reason code - * @CSA_REASON_UNKNOWN: Unknown reason - * @CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS: STA connection from DFS to NON DFS. - * @CSA_REASON_USER_INITIATED: User initiated form north bound. - * @CSA_REASON_PEER_ACTION_FRAME: Action frame received on sta iface. - * @CSA_REASON_PRE_CAC_SUCCESS: Pre CAC success. - * @CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL: concurrent sta changed channel. - * @CSA_REASON_UNSAFE_CHANNEL: Unsafe channel. - * @CSA_REASON_LTE_COEX: LTE coex. - * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency. - * - */ -enum sap_csa_reason_code { - CSA_REASON_UNKNOWN, - CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS, - CSA_REASON_USER_INITIATED, - CSA_REASON_PEER_ACTION_FRAME, - CSA_REASON_PRE_CAC_SUCCESS, - CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL, - CSA_REASON_UNSAFE_CHANNEL, - CSA_REASON_LTE_COEX, - CSA_REASON_CONCURRENT_NAN_EVENT -}; - struct sap_config { tSap_SSIDInfo_t SSIDinfo; eCsrPhyMode SapHw_mode; /* Wireless Mode */ diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 9d8c9a64f591..652152fd6cc7 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1408,12 +1408,12 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, return QDF_STATUS_E_FAULT; } QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: sap chan:%d target:%d conn on 5GHz:%d, csa_reason:%s(%d)", + "%s: sap chan:%d target:%d conn on 5GHz:%d, csa_reason:%s(%d) strict %d vdev %d", __func__, sap_ctx->channel, targetChannel, policy_mgr_is_any_mode_active_on_band_along_with_session( mac->psoc, sap_ctx->sessionId, POLICY_MGR_BAND_5), sap_get_csa_reason_str(sap_ctx->csa_reason), - sap_ctx->csa_reason); + sap_ctx->csa_reason, strict, sap_ctx->sessionId); sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);