From 21bde25bdaff6df485878f703a2cb916e0aeb565 Mon Sep 17 00:00:00 2001 From: "Masti, Narayanraddi" Date: Fri, 9 Oct 2015 19:39:47 +0530 Subject: [PATCH] qcacld-3.0: Fix race condition between disassoc/deauth from peer qcacld-2.0 to qcacld-3.0 propagation When disassoc request is received from peer and at the same time if deauth request is received from supplicant, LIM cleanup may not happen properly as there is a chance of session deletion in limSendSmeDeauthNtf while cleanup in progress from limProcessSmeDisassocCnf. This can result in not sending delbss to FW. Hence, FW can crash when config bss is sent for new connection. Following changes are added to handle this. 1. Add state eLIM_SME_WT_DISASSOC_STATE in __limProcessSmeDeauthReq and allow host to post LIM_MLM_DEAUTH_REQ instead of invoking limSendSmeDeauthNtf, where session is deleted. 2. Send eWNI_SME_DEAUTH_RSP if cleanup is already in progress to avoid cleanup again. If mlm state is not eLIM_MLM_LINK_ESTABLISHED_STATE, then it means cleanup is already in progress. 3. Return from __limProcessSmeDisassocCnf if cleanup is already in progress. 4. Add check in limProcessMlmDeauthCnf to send deauth confirmation even if state is eLIM_SME_WT_DISASSOC_STATE. 5. Add similar checks in limProcessMlmDisassocReqNtf to handle disassoc from peer and supplicant simultaneously. Change-Id: Ie19a7b79d835a5e5a77ef48f9379c1cf90dc38d7 CRs-Fixed: 878334 --- .../src/pe/lim/lim_process_mlm_req_messages.c | 79 +++++++++++++++++-- .../src/pe/lim/lim_process_mlm_rsp_messages.c | 4 +- .../src/pe/lim/lim_process_sme_req_messages.c | 12 +++ core/mac/src/pe/lim/lim_types.h | 2 + 4 files changed, 88 insertions(+), 9 deletions(-) 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 fcee43b85190..7cd873d4fbfa 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 @@ -1569,6 +1569,7 @@ lim_process_mlm_disassoc_req_ntf(tpAniSirGlobal mac_ctx, tpPESession session; extern bool send_disassoc_frame; tLimMlmStates mlm_state; + tSirSmeDisassocRsp *sme_disassoc_rsp; if (CDF_STATUS_SUCCESS != suspend_status) lim_log(mac_ctx, LOGE, FL("Suspend Status is not success %X"), @@ -1605,10 +1606,39 @@ lim_process_mlm_disassoc_req_ntf(tpAniSirGlobal mac_ctx, lim_print_mac_addr(mac_ctx, mlm_disassocreq->peerMacAddr, LOGW); - /* Prepare and Send LIM_MLM_DISASSOC_CNF */ - mlm_disassoccnf.resultCode = - eSIR_SME_INVALID_PARAMETERS; - goto end; + /* + * Disassociation response due to host triggered + * disassociation + */ + sme_disassoc_rsp = + cdf_mem_malloc(sizeof(tSirSmeDisassocRsp)); + if (NULL == sme_disassoc_rsp) { + lim_log(mac_ctx, LOGP, + FL("memory allocation failed for disassoc rsp")); + return; + } + + lim_log(mac_ctx, LOG1, + FL("send disassoc rsp with ret code %d for" MAC_ADDRESS_STR), + eSIR_SME_DEAUTH_STATUS, + MAC_ADDR_ARRAY(mlm_disassocreq->peerMacAddr)); + + sme_disassoc_rsp->messageType = eWNI_SME_DISASSOC_RSP; + sme_disassoc_rsp->length = sizeof(tSirSmeDisassocRsp); + sme_disassoc_rsp->sessionId = + mlm_disassocreq->sessionId; + sme_disassoc_rsp->transactionId = 0; + sme_disassoc_rsp->statusCode = eSIR_SME_DEAUTH_STATUS; + + cdf_mem_copy(sme_disassoc_rsp->peerMacAddr, + mlm_disassocreq->peerMacAddr, + sizeof(tSirMacAddr)); + msg = (uint32_t *)sme_disassoc_rsp; + + lim_send_sme_disassoc_deauth_ntf(mac_ctx, + CDF_STATUS_SUCCESS, msg); + return; + } break; case eLIM_STA_IN_IBSS_ROLE: @@ -1909,6 +1939,7 @@ lim_process_mlm_deauth_req_ntf(tpAniSirGlobal mac_ctx, tLimMlmDeauthReq *mlm_deauth_req; tLimMlmDeauthCnf mlm_deauth_cnf; tpPESession session; + tSirSmeDeauthRsp *sme_deauth_rsp; if (CDF_STATUS_SUCCESS != suspend_status) lim_log(mac_ctx, LOGE, FL("Suspend Status is not success %X"), @@ -1955,10 +1986,42 @@ lim_process_mlm_deauth_req_ntf(tpAniSirGlobal mac_ctx, MAC_ADDR_ARRAY( mlm_deauth_req->peerMacAddr), MAC_ADDR_ARRAY(curr_bssId)); - /* Prepare and Send LIM_MLM_DEAUTH_CNF */ - mlm_deauth_cnf.resultCode = - eSIR_SME_INVALID_PARAMETERS; - goto end; + /* + * Deauthentication response to host triggered + * deauthentication + */ + sme_deauth_rsp = + cdf_mem_malloc(sizeof(tSirSmeDeauthRsp)); + if (NULL == sme_deauth_rsp) { + lim_log(mac_ctx, LOGP, + FL("memory allocation failed for deauth rsp")); + return; + } + + lim_log(mac_ctx, LOG1, + FL("send deauth rsp with ret code %d for" MAC_ADDRESS_STR), + eSIR_SME_DEAUTH_STATUS, + MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr)); + + sme_deauth_rsp->messageType = + eWNI_SME_DEAUTH_RSP; + sme_deauth_rsp->length = + sizeof(tSirSmeDeauthRsp); + sme_deauth_rsp->statusCode = + eSIR_SME_DEAUTH_STATUS; + sme_deauth_rsp->sessionId = + mlm_deauth_req->sessionId; + sme_deauth_rsp->transactionId = 0; + + cdf_mem_copy(sme_deauth_rsp->peerMacAddr, + mlm_deauth_req->peerMacAddr, + sizeof(tSirMacAddr)); + + msg_buf = (uint32_t *)sme_deauth_rsp; + + lim_send_sme_disassoc_deauth_ntf(mac_ctx, + CDF_STATUS_SUCCESS, msg_buf); + return; } if ((session->limMlmState == diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index 5a756e77cd61..c7c4f5aa1f75 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -1299,7 +1299,9 @@ void lim_process_mlm_deauth_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf) if (LIM_IS_STA_ROLE(psessionEntry) || LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) { /* Deauth Confirm from MLM */ - if (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) { + if ((psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) + && psessionEntry->limSmeState != + eLIM_SME_WT_DEAUTH_STATE) { /** * Should not have received Deauth confirm * from MLM in other states. diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 541e42e863e5..6241c06af150 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -2741,6 +2741,18 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr)); return; } + + if ((pStaDs->mlmStaContext.mlmState == + eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == + eLIM_MLM_WT_DEL_STA_RSP_STATE)) { + lim_log(pMac, LOGE, + FL("No need of cleanup for addr:" MAC_ADDRESS_STR "as MLM state is %d"), + MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr), + pStaDs->mlmStaContext.mlmState); + return; + } + #if defined WLAN_FEATURE_VOWIFI_11R /* Delete FT session if there exists one */ lim_ft_cleanup_pre_auth_info(pMac, psessionEntry); diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index a61a9cadba00..8bffe8b8e244 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -854,6 +854,8 @@ void lim_process_rx_scan_event(tpAniSirGlobal mac, void *buf); int lim_process_remain_on_chnl_req(tpAniSirGlobal pMac, uint32_t *pMsg); void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, CDF_STATUS status, uint32_t *data); +void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal mac_ctx, + CDF_STATUS status, uint32_t *ctx); /* / Bit value data structure */ typedef enum sHalBitVal /* For Bit operations */