qcacld-2.0: Fix active cmd timeout issue
prima to qcacld-2.0 propagation
There can be a possible race in updation of roam substate
between csrRoamWaitForKeyTimeOutHandler and upper layer
disconnect in csrRoamIssueDeauth. Race can be as follows.
Driver roam substate is eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY by
the time csrRoamWaitForKeyTimeOutHandler is invoked. This
can allow check CSR_IS_WAIT_FOR_KEY to pass. If MC thread
gets preempted and if driver processes upper layer disconnect,
then driver changes roam substate to eCSR_ROAM_SUBSTATE_DEAUTH_REQ
in csrRoamIssueDeauth. When MC thread resumes processing of
csrRoamWaitForKeyTimeOutHandler, then driver changes roam
substate to eCSR_ROAM_SUBSTATE_NONE. This can result in
unhandling of eWNI_SME_DEAUTH_RSP as roam substate is not in
eCSR_ROAM_SUBSTATE_DEAUTH_REQ and can result in active command
timeout. Hence, update roam substate atomically in same context
if CSR_IS_WAIT_FOR_KEY passes in csrRoamWaitForKeyTimeOutHandler.
Change-Id: I05cfc8de54fe4196df941c2fd48db8bedc7df779
CRs-Fixed: 2155141
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 8a24f8f..8ac1883 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1123,6 +1123,7 @@
#endif
vos_timer_t packetdump_timer;
tANI_BOOLEAN pending_roam_disable;
+ vos_spin_lock_t roam_state_lock;
}tCsrRoamStruct;
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 8527c7c..d31c16d 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -275,6 +275,21 @@
void csrReinitPreauthCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csrInitOperatingClasses(tHalHandle hHal);
+void csrRoamSubstateChange(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate,
+ tANI_U32 sessionId)
+{
+ smsLog(pMac, LOG1, FL("CSR RoamSubstate: [ %s <== %s ]"),
+ macTraceGetcsrRoamSubState(NewSubstate),
+ macTraceGetcsrRoamSubState(pMac->roam.curSubState[sessionId]));
+ if(pMac->roam.curSubState[sessionId] == NewSubstate)
+ {
+ return;
+ }
+ vos_spin_lock_acquire(&pMac->roam.roam_state_lock);
+ pMac->roam.curSubState[sessionId] = NewSubstate;
+ vos_spin_lock_release(&pMac->roam.roam_state_lock);
+}
+
//Initialize global variables
static void csrRoamInitGlobals(tpAniSirGlobal pMac)
{
@@ -755,7 +770,7 @@
for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
csrRoamStateChange(pMac, eCSR_ROAMING_STATE_STOP, sessionId);
- pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE;
+ csrRoamSubstateChange(pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId);
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
@@ -902,6 +917,7 @@
smsLog(pMac, LOGE, FL("cannot allocate memory for summary Statistics timer"));
return eHAL_STATUS_FAILURE;
}
+ vos_spin_lock_init(&pMac->roam.roam_state_lock);
}while (0);
return (status);
}
@@ -919,6 +935,7 @@
vos_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
vos_timer_stop(&pMac->roam.packetdump_timer);
vos_timer_destroy(&pMac->roam.packetdump_timer);
+ vos_spin_lock_destroy(&pMac->roam.roam_state_lock);
return (eHAL_STATUS_SUCCESS);
}
@@ -1183,18 +1200,6 @@
}
}
-void csrRoamSubstateChange( tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate, tANI_U32 sessionId)
-{
- smsLog(pMac, LOG1, FL("CSR RoamSubstate: [ %s <== %s ]"),
- macTraceGetcsrRoamSubState(NewSubstate),
- macTraceGetcsrRoamSubState(pMac->roam.curSubState[sessionId]));
- if(pMac->roam.curSubState[sessionId] == NewSubstate)
- {
- return;
- }
- pMac->roam.curSubState[sessionId] = NewSubstate;
-}
-
eCsrRoamState csrRoamStateChange( tpAniSirGlobal pMac, eCsrRoamState NewRoamState, tANI_U8 sessionId)
{
eCsrRoamState PreviousState;
@@ -11887,8 +11892,14 @@
macTraceGetcsrRoamSubState(
pMac->roam.curSubState[pInfo->sessionId]));
+ vos_spin_lock_acquire(&pMac->roam.roam_state_lock);
if( CSR_IS_WAIT_FOR_KEY( pMac, pInfo->sessionId ) )
{
+ //Change the substate so command queue is unblocked.
+ if (CSR_ROAM_SESSION_MAX > pInfo->sessionId)
+ pMac->roam.curSubState[pInfo->sessionId] =
+ eCSR_ROAM_SUBSTATE_NONE;
+ vos_spin_lock_release(&pMac->roam.roam_state_lock);
#ifdef FEATURE_WLAN_LFR
if (csrNeighborRoamIsHandoffInProgress(pMac, pInfo->sessionId))
{
@@ -11906,13 +11917,6 @@
#endif
smsLog(pMac, LOGE, " SME pre-auth state timeout. ");
- //Change the substate so command queue is unblocked.
- if (CSR_ROAM_SESSION_MAX > pInfo->sessionId)
- {
- csrRoamSubstateChange(pMac, eCSR_ROAM_SUBSTATE_NONE,
- pInfo->sessionId);
- }
-
if( csrIsConnStateConnectedInfra(pMac, pInfo->sessionId) )
{
csrRoamLinkUp(pMac, pSession->connectedProfile.bssid);
@@ -11931,6 +11935,8 @@
__func__, pInfo->sessionId);
}
}
+ else
+ vos_spin_lock_release(&pMac->roam.roam_state_lock);
}
eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval)