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 74a5a63a68a7..5f9563596454 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 @@ -777,26 +777,33 @@ policy_mgr_get_third_conn_action_table( } } -QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, - uint32_t session_id, - uint8_t channel, - enum policy_mgr_conn_update_reason reason) +static QDF_STATUS +policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason, + enum policy_mgr_conc_next_action *next_action) { - enum policy_mgr_conc_next_action next_action = PM_NOP; uint32_t num_connections = 0; enum policy_mgr_one_connection_mode second_index = 0; enum policy_mgr_two_connection_mode third_index = 0; policy_mgr_next_action_two_connection_table_type *second_conn_table; policy_mgr_next_action_three_connection_table_type *third_conn_table; enum policy_mgr_band band; - QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_psoc_priv_obj *pm_ctx; enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE; - if (policy_mgr_is_hw_dbs_capable(psoc) == false) { - policy_mgr_err("driver isn't dbs capable, no further action needed"); - return QDF_STATUS_E_NOSUPPORT; + if (!next_action) { + policy_mgr_err("next_action is NULL"); + return QDF_STATUS_E_FAILURE; } + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + if (WLAN_REG_IS_24GHZ_CH(channel)) band = POLICY_MGR_BAND_24; else @@ -811,11 +818,11 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, case 0: if (band == POLICY_MGR_BAND_24) if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) - next_action = PM_DBS; + *next_action = PM_DBS; else - next_action = PM_NOP; + *next_action = PM_NOP; else - next_action = PM_NOP; + *next_action = PM_NOP; break; case 1: second_index = @@ -823,11 +830,11 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, if (PM_MAX_ONE_CONNECTION_MODE == second_index) { policy_mgr_err( "couldn't find index for 2nd connection next action table"); - goto done; + return QDF_STATUS_E_FAILURE; } second_conn_table = policy_mgr_get_second_conn_action_table( psoc, session_id, channel, reason); - next_action = (*second_conn_table)[second_index][band]; + *next_action = (*second_conn_table)[second_index][band]; break; case 2: third_index = @@ -835,11 +842,11 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, if (PM_MAX_TWO_CONNECTION_MODE == third_index) { policy_mgr_err( "couldn't find index for 3rd connection next action table"); - goto done; + return QDF_STATUS_E_FAILURE; } third_conn_table = policy_mgr_get_third_conn_action_table( psoc, session_id, channel, reason); - next_action = (*third_conn_table)[third_index][band]; + *next_action = (*third_conn_table)[third_index][band]; break; default: policy_mgr_err("unexpected num_connections value %d", @@ -847,12 +854,6 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, break; } - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid context"); - goto done; - } - /* * There is no adapter associated with NAN Discovery, hence skip the * HDD callback and fill separately. @@ -874,10 +875,36 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, */ if (policy_mgr_is_current_hwmode_dbs(psoc) && !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode)) - next_action = PM_SINGLE_MAC; + *next_action = PM_SINGLE_MAC; else if (!policy_mgr_is_current_hwmode_dbs(psoc) && !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode)) - next_action = PM_NOP; + *next_action = PM_NOP; + + policy_mgr_debug("idx2=%d idx3=%d next_action=%d, band=%d reason=%d session_id=%d", + second_index, third_index, *next_action, band, + reason, session_id); + + return QDF_STATUS_SUCCESS; +} + + +QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason) +{ + enum policy_mgr_conc_next_action next_action = PM_NOP; + QDF_STATUS status; + + if (!policy_mgr_is_hw_dbs_capable(psoc)) { + policy_mgr_err("driver isn't dbs capable, no further action needed"); + return QDF_STATUS_E_NOSUPPORT; + } + + status = policy_mgr_get_next_action(psoc, session_id, channel, reason, + &next_action); + if (QDF_IS_STATUS_ERROR(status)) + return status; if (PM_NOP != next_action) status = policy_mgr_next_actions(psoc, session_id, @@ -885,12 +912,9 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, else status = QDF_STATUS_E_NOSUPPORT; - policy_mgr_debug( - "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d", - second_index, third_index, next_action, band, status, - reason, session_id); + policy_mgr_debug("next_action %d reason=%d session_id=%d", + next_action, reason, session_id); -done: return status; } @@ -1919,6 +1943,16 @@ QDF_STATUS policy_mgr_set_hw_mode_before_channel_switch( QDF_STATUS status; struct policy_mgr_conc_connection_info info; uint8_t num_cxn_del = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum policy_mgr_conc_next_action next_action = PM_NOP; + enum policy_mgr_conn_update_reason reason = + POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } if (!policy_mgr_is_hw_dbs_capable(psoc)) { policy_mgr_err("DBS is disabled"); @@ -1944,6 +1978,7 @@ QDF_STATUS policy_mgr_set_hw_mode_before_channel_switch( return QDF_STATUS_E_ALREADY; } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* * Store the connection's parameter and temporarily delete it * from the concurrency table. This way the allow concurrency @@ -1952,19 +1987,39 @@ QDF_STATUS policy_mgr_set_hw_mode_before_channel_switch( */ policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, &info, &num_cxn_del); - - status = policy_mgr_update_and_wait_for_connection_update(psoc, - vdev_id, chan, - POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH); + status = policy_mgr_get_next_action(psoc, vdev_id, chan, reason, + &next_action); /* Restore the connection entry */ if (num_cxn_del) policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (QDF_IS_STATUS_ERROR(status)) + goto chk_opportunistic_timer; + + status = policy_mgr_reset_connection_update(psoc); + if (QDF_IS_STATUS_ERROR(status)) + policy_mgr_err("clearing event failed"); + + if (PM_NOP != next_action) + status = policy_mgr_next_actions(psoc, vdev_id, + next_action, reason); + else + status = QDF_STATUS_E_NOSUPPORT; + + if (QDF_IS_STATUS_SUCCESS(status)) { + status = policy_mgr_wait_for_connection_update(psoc); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("qdf wait for event failed"); + } + } + +chk_opportunistic_timer: /* * If hw mode change failed restart the opportunistic timer to * Switch to single mac if required. */ - if (QDF_IS_STATUS_ERROR(status)) { + if (status == QDF_STATUS_E_FAILURE) { policy_mgr_err("Failed to update HW modeStatus %d", status); policy_mgr_check_n_start_opportunistic_timer(psoc); } @@ -1978,6 +2033,16 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_sta_channel_switch( QDF_STATUS status; struct policy_mgr_conc_connection_info info; uint8_t num_cxn_del = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum policy_mgr_conc_next_action next_action = PM_NOP; + enum policy_mgr_conn_update_reason reason = + POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } if (!policy_mgr_is_hw_dbs_capable(psoc) || !policy_mgr_is_hw_dbs_2x2_capable(psoc)) { @@ -2001,6 +2066,8 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_sta_channel_switch( policy_mgr_err("DBS is not required for 5Ghz chan"); return QDF_STATUS_E_NOSUPPORT; } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* * Store the connection's parameter and temporarily delete it * from the concurrency table. This way the allow concurrency @@ -2010,13 +2077,23 @@ QDF_STATUS policy_mgr_check_and_set_hw_mode_sta_channel_switch( policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, &info, &num_cxn_del); - status = policy_mgr_current_connections_update(psoc, vdev_id, chan, - POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA); - + status = policy_mgr_get_next_action(psoc, vdev_id, chan, + reason, &next_action); /* Restore the connection entry */ if (num_cxn_del) policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (QDF_IS_STATUS_ERROR(status)) + goto chk_opportunistic_timer; + + if (PM_NOP != next_action) + status = policy_mgr_next_actions(psoc, vdev_id, + next_action, reason); + else + status = QDF_STATUS_E_NOSUPPORT; + +chk_opportunistic_timer: /* * If hw mode change failed restart the opportunistic timer to * Switch to single mac if required. 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 a4bceb4f25ad..8774696de01a 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 @@ -1329,7 +1329,7 @@ QDF_STATUS policy_mgr_pdev_get_pcl(struct wlan_objmgr_psoc *psoc, void policy_mgr_set_pcl_for_existing_combo( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) { - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_conc_connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; enum QDF_OPMODE pcl_mode; @@ -1348,7 +1348,6 @@ void policy_mgr_set_pcl_for_existing_combo( return; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* Check, store and temp delete the mode's parameter */ policy_mgr_store_and_del_conn_info(psoc, mode, false, info, &num_cxn_del); @@ -1357,14 +1356,14 @@ void policy_mgr_set_pcl_for_existing_combo( policy_mgr_debug("Set PCL to FW for mode:%d", mode); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - if (QDF_IS_STATUS_SUCCESS(status)) { - status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl); - if (QDF_IS_STATUS_ERROR(status)) - policy_mgr_err("Send set PCL to SME failed"); - } - } else { - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + /* Send PCL only if policy_mgr_pdev_get_pcl returned success */ + if (QDF_IS_STATUS_SUCCESS(status)) { + status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl); + if (QDF_IS_STATUS_ERROR(status)) + policy_mgr_err("Send set PCL to SME failed"); } } 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 093389fd6bd0..1270562955ef 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 @@ -2137,6 +2137,13 @@ bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, bool allow = false; struct policy_mgr_conc_connection_info info; uint8_t num_cxn_del = 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 allow; + } /* * Store the connection's parameter and temporarily delete it @@ -2144,6 +2151,7 @@ bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, * check can be used as though 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, vdev_id, &info, &num_cxn_del); allow = policy_mgr_allow_concurrency( @@ -2151,11 +2159,13 @@ bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, mode, channel, HW_MODE_20_MHZ); - if (!allow) - policy_mgr_err("CSA concurrency check failed"); /* 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); + + if (!allow) + policy_mgr_err("CSA concurrency check failed"); return allow; } 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 ef20048f2c7f..f53791e93724 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 @@ -86,12 +86,10 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, /* Check, store and temp delete the mode's parameter */ policy_mgr_store_and_del_conn_info(psoc, mode, all_matching_cxn_to_del, info, &num_cxn_del); - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* Get the PCL */ status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, pcl_weight, weight_len); policy_mgr_debug("Get PCL to FW for mode:%d", mode); - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } @@ -1778,7 +1776,6 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, */ policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, false, info, &num_cxn_del); - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* * There is a small window between releasing the above lock * and acquiring the same in policy_mgr_allow_concurrency, @@ -1792,7 +1789,6 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, WEIGHT_OF_NON_PCL_CHANNELS; } } - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); }