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 6ed4598652..c828a3ae14 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 @@ -598,14 +598,15 @@ static bool policy_mgr_is_restart_sap_allowed( uint32_t mcc_to_scc_switch) { if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) || - !(policy_mgr_concurrent_open_sessions_running(psoc) && - ((policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_SAP_MASK)) || - (policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_P2P_GO_MASK))))) { + !policy_mgr_concurrent_open_sessions_running(psoc) || + !((policy_mgr_get_concurrency_mode(psoc) == + (QDF_STA_MASK | QDF_SAP_MASK)) || + (policy_mgr_get_concurrency_mode(psoc) == + (QDF_STA_MASK | QDF_P2P_GO_MASK)))) { policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO"); return false; } + return true; } @@ -649,18 +650,30 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, */ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { - struct wlan_objmgr_psoc *psoc = - (struct wlan_objmgr_psoc *) data; - struct policy_mgr_psoc_priv_obj *pm_ctx; + struct wlan_objmgr_psoc *psoc; + struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; + struct sta_ap_intf_check_work_ctx *work_info = NULL; uint32_t mcc_to_scc_switch; QDF_STATUS status; uint8_t channel, sec_ch; uint8_t operating_channel, vdev_id; + work_info = (struct sta_ap_intf_check_work_ctx *) data; + if (!work_info) { + policy_mgr_err("Invalid work_info"); + goto end; + } + + psoc = work_info->psoc; + if (!psoc) { + policy_mgr_err("Invalid psoc"); + goto end; + } + pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); - return; + goto end; } mcc_to_scc_switch = policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); @@ -669,7 +682,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_concurrent_open_sessions_running(psoc)); if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) - return; + goto end; if (policy_mgr_get_mode_specific_conn_info(psoc, &operating_channel, @@ -685,12 +698,12 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) operating_channel); } else { policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid"); - return; + goto end; } if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { policy_mgr_err("SAP restart get channel callback in NULL"); - return; + goto end; } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); status = pm_ctx->hdd_cbacks. @@ -699,11 +712,17 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to switch SAP channel"); - return; + goto end; } policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d", operating_channel, channel); +end: + if (work_info) { + qdf_mem_free(work_info); + if (pm_ctx) + pm_ctx->sta_ap_intf_check_work_info = NULL; + } } static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, @@ -846,15 +865,30 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); policy_mgr_info("MCC to SCC switch: %d chan: %d", mcc_to_scc_switch, operating_channel); + + if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) { + policy_mgr_debug( + "No action taken at check_concurrent_intf_and_restart_sap"); + return; + } + if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && policy_mgr_valid_sta_channel_check(psoc, operating_channel) - ) { - qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, + && !pm_ctx->sta_ap_intf_check_work_info) { + struct sta_ap_intf_check_work_ctx *work_info; + work_info = qdf_mem_malloc( + sizeof(struct sta_ap_intf_check_work_ctx)); + pm_ctx->sta_ap_intf_check_work_info = work_info; + if (work_info) { + work_info->psoc = psoc; + qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, policy_mgr_check_sta_ap_concurrent_ch_intf, - psoc); - qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); - policy_mgr_info("Checking for Concurrent Change interference"); + work_info); + qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); + policy_mgr_info( + "Checking for Concurrent Change interference"); + } } } #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ 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 2dcc30497b..df104a7f7a 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 @@ -184,6 +184,15 @@ extern enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) (struct wlan_objmgr_psoc *psoc); +/** + * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work + * related info + * @psoc: pointer to PSOC object information + */ +struct sta_ap_intf_check_work_ctx { + struct wlan_objmgr_psoc *psoc; +}; + /** * struct policy_mgr_psoc_priv_obj - Policy manager private data * @psoc: pointer to PSOC object information @@ -229,34 +238,36 @@ extern enum policy_mgr_conc_next_action * value from INI * @unsafe_channel_list: LTE coex channel avoidance list * @unsafe_channel_count: LTE coex channel avoidance list count + * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work */ struct policy_mgr_psoc_priv_obj { - struct wlan_objmgr_psoc *psoc; - struct wlan_objmgr_pdev *pdev; - qdf_event_t connection_update_done_evt; - qdf_mutex_t qdf_conc_list_lock; - qdf_mc_timer_t dbs_opportunistic_timer; - struct policy_mgr_hdd_cbacks hdd_cbacks; - struct policy_mgr_sme_cbacks sme_cbacks; - struct policy_mgr_wma_cbacks wma_cbacks; - struct policy_mgr_tdls_cbacks tdls_cbacks; - struct policy_mgr_cdp_cbacks cdp_cbacks; - uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; - uint32_t sap_mandatory_channels_len; - bool do_hw_mode_change; - uint32_t concurrency_mode; - uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; - uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; - qdf_work_t sta_ap_intf_check_work; - uint32_t num_dbs_hw_modes; - struct dbs_hw_mode_info hw_mode; - uint32_t old_hw_mode_index; - uint32_t new_hw_mode_index; - struct dual_mac_config dual_mac_cfg; - uint32_t hw_mode_change_in_progress; - struct policy_mgr_user_cfg user_cfg; - uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; - uint16_t unsafe_channel_count; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + qdf_event_t connection_update_done_evt; + qdf_mutex_t qdf_conc_list_lock; + qdf_mc_timer_t dbs_opportunistic_timer; + struct policy_mgr_hdd_cbacks hdd_cbacks; + struct policy_mgr_sme_cbacks sme_cbacks; + struct policy_mgr_wma_cbacks wma_cbacks; + struct policy_mgr_tdls_cbacks tdls_cbacks; + struct policy_mgr_cdp_cbacks cdp_cbacks; + uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; + uint32_t sap_mandatory_channels_len; + bool do_hw_mode_change; + uint32_t concurrency_mode; + uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; + uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; + qdf_work_t sta_ap_intf_check_work; + uint32_t num_dbs_hw_modes; + struct dbs_hw_mode_info hw_mode; + uint32_t old_hw_mode_index; + uint32_t new_hw_mode_index; + struct dual_mac_config dual_mac_cfg; + uint32_t hw_mode_change_in_progress; + struct policy_mgr_user_cfg user_cfg; + uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; + uint16_t unsafe_channel_count; + struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info; }; /** diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c index fd91357a3e..c20c548a72 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c @@ -364,6 +364,12 @@ QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) policy_mgr_info("HW list is freed"); } + if (pm_ctx->sta_ap_intf_check_work_info) { + qdf_cancel_work(0, &pm_ctx->sta_ap_intf_check_work); + qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info); + pm_ctx->sta_ap_intf_check_work_info = NULL; + } + return QDF_STATUS_SUCCESS; }