From f19af0eed9bb5c8f2749a4d673f3505ff1b0980e Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 1 Sep 2021 17:03:57 +0800 Subject: [PATCH] qcacld-3.0: Abort MLME connect timers upon NB disconnect request When the connect request is pending on MLME and NB disconnect comes, driver will wait for previous connect finish to process the disconnect request. This delay the disconnect and may cause framework ANR. Add code to fire the timeout event of active timers in various MLME state. This will abort the connect request and get disconnect done fast. Change-Id: I19cc03108c966c8f1efc0a554dfc59123dfe37f1 CRs-Fixed: 3026311 --- core/mac/inc/wni_api.h | 3 +- .../src/pe/lim/lim_process_message_queue.c | 3 + .../src/pe/lim/lim_process_mlm_req_messages.c | 9 +-- core/mac/src/pe/lim/lim_types.h | 9 +++ core/mac/src/pe/lim/lim_utils.c | 62 +++++++++++++++++++ core/mac/src/pe/lim/lim_utils.h | 13 ++++ core/sme/src/csr/csr_api_roam.c | 23 +++++++ 7 files changed, 113 insertions(+), 9 deletions(-) diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 2bbf321922e4..776b30b5fbbf 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -251,7 +251,8 @@ enum eWniMsgTypes { eWNI_SME_TWT_RESUME_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 168, eWNI_SME_TWT_NUDGE_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 169, eWNI_SME_TWT_NOTIFY_EVENT = SIR_SME_MSG_TYPES_BEGIN + 170, - eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 171 + eWNI_SME_ABORT_CONN_TIMER = SIR_SME_MSG_TYPES_BEGIN + 171, + eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 172 }; typedef struct sAniCfgTxRateCtrs { diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 35318f22ba37..03a692c566bb 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -2104,6 +2104,9 @@ static void lim_process_messages(struct mac_context *mac_ctx, break; case SIR_LIM_PROCESS_DEFERRED_QUEUE: break; + case eWNI_SME_ABORT_CONN_TIMER: + lim_deactivate_timers_for_vdev(mac_ctx, msg->bodyval); + break; default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index 8d8c281f850d..a3c32714b92f 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -90,14 +90,7 @@ static void lim_fill_status_code(uint8_t frame_type, } } -/** - * lim_process_sae_auth_timeout() - This function is called to process sae - * auth timeout - * @mac_ctx: Pointer to Global MAC structure - * - * @Return: None - */ -static void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) +void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) { struct pe_session *session; enum wlan_status_code proto_status_code; diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index c7265930407e..e2f766402737 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -1299,6 +1299,15 @@ void lim_process_auth_failure_timeout(struct mac_context *mac_ctx); void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, uint32_t msg_type); +/** + * lim_process_sae_auth_timeout() - This function is called to process sae + * auth timeout + * @mac_ctx: Pointer to Global MAC structure + * + * @Return: None + */ +void lim_process_sae_auth_timeout(struct mac_context *mac_ctx); + /** * lim_send_frame() - API to send frame * @mac_ctx Pointer to Global MAC structure diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 8093da95310d..c2cc18456761 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -493,6 +493,68 @@ void lim_deactivate_timers(struct mac_context *mac_ctx) tx_timer_deactivate(&lim_timer->sae_auth_timer); } +void lim_deactivate_timers_for_vdev(struct mac_context *mac_ctx, + uint8_t vdev_id) +{ + tLimTimers *lim_timer = &mac_ctx->lim.lim_timers; + struct pe_session *pe_session; + + pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id); + if (!pe_session) { + pe_err("pe session invalid for vdev %d", vdev_id); + return; + } + pe_debug("pe limMlmState %s vdev %d", + lim_mlm_state_str(pe_session->limMlmState), + vdev_id); + switch (pe_session->limMlmState) { + case eLIM_MLM_WT_JOIN_BEACON_STATE: + if (tx_timer_running( + &lim_timer->gLimJoinFailureTimer)) { + pe_debug("Trigger Join failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->gLimJoinFailureTimer); + lim_process_join_failure_timeout(mac_ctx); + } + break; + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + case eLIM_MLM_WT_AUTH_FRAME4_STATE: + if (tx_timer_running( + &lim_timer->gLimAuthFailureTimer)) { + pe_debug("Trigger Auth failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->gLimAuthFailureTimer); + lim_process_auth_failure_timeout(mac_ctx); + + } + break; + case eLIM_MLM_WT_ASSOC_RSP_STATE: + if (tx_timer_running( + &lim_timer->gLimAssocFailureTimer)) { + pe_debug("Trigger Assoc failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->gLimAssocFailureTimer); + lim_process_assoc_failure_timeout(mac_ctx, + LIM_ASSOC); + } + break; + case eLIM_MLM_WT_SAE_AUTH_STATE: + if (tx_timer_running(&lim_timer->sae_auth_timer)) { + pe_debug("Trigger SAE Auth failure timeout for vdev %d", + vdev_id); + tx_timer_deactivate( + &lim_timer->sae_auth_timer); + lim_process_sae_auth_timeout(mac_ctx); + } + break; + default: + return; + } +} + /** * lim_cleanup_mlm() - This function is called to cleanup diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 7ebf92fbaae6..aa9280a0a620 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -247,6 +247,19 @@ void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type */ void lim_deactivate_timers(struct mac_context *mac_ctx); +/* + * lim_deactivate_timers_for_vdev() - Deactivate lim connection timers + * @mac_ctx: Pointer to global mac structure + * @vdev_id: vdev id + * + * This function is used to trigger timeout of lim connection timers to abort + * connect request. + * + * Return: None + */ +void lim_deactivate_timers_for_vdev(struct mac_context *mac_ctx, + uint8_t vdev_id); + /* * The below 'product' check tobe removed if 'Association' is * allowed in IBSS. diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 12bd90877dd6..913b92180f7a 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -8316,6 +8316,27 @@ QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac, return status; } +static void csr_abort_connect_request_timers( + struct mac_context *mac, uint32_t vdev_id) +{ + struct scheduler_msg msg; + QDF_STATUS status; + enum QDF_OPMODE op_mode; + + op_mode = wlan_get_opmode_from_vdev_id(mac->pdev, vdev_id); + if (op_mode != QDF_STA_MODE && + op_mode != QDF_P2P_CLIENT_MODE) + return; + qdf_mem_zero(&msg, sizeof(msg)); + msg.bodyval = vdev_id; + msg.type = eWNI_SME_ABORT_CONN_TIMER; + status = scheduler_post_message(QDF_MODULE_ID_MLME, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) + sme_debug("msg eWNI_SME_ABORT_CONN_TIMER post fail"); +} + QDF_STATUS csr_roam_issue_disassociate_cmd(struct mac_context *mac, uint32_t sessionId, eCsrRoamDisconnectReason reason, @@ -8337,6 +8358,8 @@ QDF_STATUS csr_roam_issue_disassociate_cmd(struct mac_context *mac, csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, sessionId); } + csr_abort_connect_request_timers(mac, sessionId); + pCommand->command = eSmeCommandRoam; pCommand->vdev_id = (uint8_t) sessionId; sme_debug("Disassociate reason: %d, vdev_id: %d mac_reason %d",