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 1aa8938b4f3b..9f68499914c5 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 @@ -42,6 +42,34 @@ /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 +/** + * policy_mgr_debug_alert() - fatal error alert + * + * This function will flush host drv log and + * disable all level logs. + * It can be called in fatal error detected in policy + * manager. + * This is to avoid host log overwritten in stress + * test to help issue debug. + * + * Return: none + */ +static void +policy_mgr_debug_alert(void) +{ + int module_id; + int qdf_print_idx; + + policy_mgr_err("fatal error detected to flush and pause host log"); + qdf_logging_flush_logs(); + qdf_print_idx = qdf_get_pidx(); + for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++) + qdf_print_set_category_verbose( + qdf_print_idx, + module_id, QDF_TRACE_LEVEL_NONE, + 0); +} + QDF_STATUS policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc, uint8_t *allow_mcc_go_diff_bi) @@ -1827,6 +1855,64 @@ void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, pm_ctx->no_of_open_sessions[mode]); } +/** + * policy_mgr_validate_conn_info() - validate conn info list + * @psoc: PSOC object data + * + * This function will check connection list to see duplicated + * vdev entry existing or not. + * + * Return: true if conn list is in abnormal state. + */ +static bool +policy_mgr_validate_conn_info(struct wlan_objmgr_psoc *psoc) +{ + uint32_t i, j, conn_num = 0; + bool panic = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return true; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if (pm_conc_connection_list[i].in_use) { + for (j = i + 1; j < MAX_NUMBER_OF_CONC_CONNECTIONS; + j++) { + if (pm_conc_connection_list[j].in_use && + pm_conc_connection_list[i].vdev_id == + pm_conc_connection_list[j].vdev_id) { + policy_mgr_debug( + "dup entry %d", + pm_conc_connection_list[i].vdev_id); + panic = true; + } + } + conn_num++; + } + } + if (panic) + policy_mgr_err("dup entry"); + + for (i = 0, j = 0; i < QDF_MAX_NO_OF_MODE; i++) + j += pm_ctx->no_of_active_sessions[i]; + + if (j != conn_num) { + policy_mgr_err("active session/conn count mismatch %d %d", + j, conn_num); + panic = true; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + if (panic) + policy_mgr_debug_alert(); + + return panic; +} + void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, uint8_t session_id) @@ -2148,6 +2234,7 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, uint32_t conn_index = 0, next_conn_index = 0; bool found = false; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool panic = false; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2197,8 +2284,21 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, /* clean up the entry */ qdf_mem_zero(&pm_conc_connection_list[next_conn_index - 1], sizeof(*pm_conc_connection_list)); - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + conn_index = 0; + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { + panic = true; + break; + } + conn_index++; + } + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (panic) { + policy_mgr_err("dup entry occur"); + policy_mgr_debug_alert(); + } if (pm_ctx->conc_cbacks.connection_info_update) pm_ctx->conc_cbacks.connection_info_update(); @@ -2547,6 +2647,7 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (policy_mgr_max_concurrent_connections_reached(psoc)) { policy_mgr_rl_debug("Reached max concurrent connections: %d", pm_ctx->cfg.max_conc_cxns); + policy_mgr_validate_conn_info(psoc); goto done; } @@ -3541,6 +3642,8 @@ void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc) pm_conc_connection_list[i].ch_flagext); } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + policy_mgr_validate_conn_info(psoc); } bool policy_mgr_is_any_mode_active_on_band_along_with_session( diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 6d7e84c7e7c1..365e04d6d7dc 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1174,7 +1174,9 @@ static void wma_update_phymode_on_roam(tp_wma_handle wma, uint8_t *bssid, /* update new phymode to peer */ wma_objmgr_set_peer_mlme_phymode(wma, bssid, bss_phymode); - wma_debug("LFR3: new phymode %d", bss_phymode); + wma_debug("LFR3: new phymode %d freq %d (bw %d, %d %d)", + bss_phymode, des_chan->ch_freq, des_chan->ch_width, + des_chan->ch_cfreq1, des_chan->ch_cfreq2); } static void wma_post_roam_sync_failure(tp_wma_handle wma, uint8_t vdev_id)