prima: Fix race condition between disassoc/deauth from peer, supplicant
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
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index 3f8ba9f..257fade 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -2861,6 +2861,9 @@
tLimMlmDisassocCnf mlmDisassocCnf;
tpPESession psessionEntry;
extern tANI_BOOLEAN sendDisassocFrame;
+ tSirSmeDisassocRsp *pSirSmeDisassocRsp;
+ tANI_U32 *pMsg;
+ tANI_U8 *pBuf;
if(eHAL_STATUS_SUCCESS != suspendStatus)
{
@@ -2959,11 +2962,37 @@
limLog(pMac, LOGE, FL("Sta MlmState : %d"),
pStaDs->mlmStaContext.mlmState);
- /// Prepare and Send LIM_MLM_DISASSOC_CNF
+ /*
+ * Disassociation response due to
+ * host triggered disassociation
+ */
- mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ pSirSmeDisassocRsp = vos_mem_malloc(sizeof(tSirSmeDisassocRsp));
+ if ( NULL == pSirSmeDisassocRsp )
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to AllocateMemory failed for eWNI_SME_DISASSOC_RSP"));
+ return;
+ }
+ limLog(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with "
+ "retCode: %d for "MAC_ADDRESS_STR),eSIR_SME_DEAUTH_STATUS,
+ MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr));
+ pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP;
+ pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp);
+ pSirSmeDisassocRsp->sessionId = pMlmDisassocReq->sessionId;
+ pSirSmeDisassocRsp->transactionId = 0;
+ pSirSmeDisassocRsp->statusCode = eSIR_SME_DEAUTH_STATUS;
- goto end;
+ pBuf = (tANI_U8 *) pSirSmeDisassocRsp->peerMacAddr;
+ vos_mem_copy( pBuf, pMlmDisassocReq->peerMacAddr, sizeof(tSirMacAddr));
+
+ pMsg = (tANI_U32*) pSirSmeDisassocRsp;
+
+ limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pMsg );
+ return;
+
}
//pStaDs->mlmStaContext.rxPurgeReq = 1;
@@ -3174,6 +3203,9 @@
tLimMlmDeauthReq *pMlmDeauthReq;
tLimMlmDeauthCnf mlmDeauthCnf;
tpPESession psessionEntry;
+ tSirSmeDeauthRsp *pSirSmeDeauthRsp;
+ tANI_U8 *pBuf;
+ tANI_U32 *pMsg;
if(eHAL_STATUS_SUCCESS != suspendStatus)
@@ -3355,11 +3387,38 @@
FL("received MLM_DEAUTH_REQ for STA that either has no context or in some transit state, Addr="
MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));)
- /// Prepare and Send LIM_MLM_DEAUTH_CNF
+ /*
+ * Deauthentication response to host triggered
+ * deauthentication.
+ */
+ pSirSmeDeauthRsp = vos_mem_malloc(sizeof(tSirSmeDeauthRsp));
+ if ( NULL == pSirSmeDeauthRsp )
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP"));
- mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ return;
+ }
+ limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with "
+ "retCode: %d for"MAC_ADDRESS_STR),eSIR_SME_DEAUTH_STATUS,
+ MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));
+ pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP;
+ pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp);
+ pSirSmeDeauthRsp->statusCode = eSIR_SME_DEAUTH_STATUS;
+ pSirSmeDeauthRsp->sessionId = pMlmDeauthReq->sessionId;
+ pSirSmeDeauthRsp->transactionId = 0;
- goto end;
+ pBuf = (tANI_U8 *) pSirSmeDeauthRsp->peerMacAddr;
+ vos_mem_copy( pBuf, pMlmDeauthReq->peerMacAddr, sizeof(tSirMacAddr));
+
+ pMsg = (tANI_U32*)pSirSmeDeauthRsp;
+
+ limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pMsg );
+
+ return;
+
}
//pStaDs->mlmStaContext.rxPurgeReq = 1;