wlan: Retry sending Reassoc request 2 more times

Some times AP not sending Reassoc Rsp and STA not Acking Reassoc Rsp can
result in Reassoc timeout, to avoid this situation, STA should retry
sending Reassoc request 2 more times.

Change-Id: Idc644513fb6548c34814ff1ea00f8306b407b75f
CR-Fixed: 408031
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 4553d5c..517b92f 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -909,6 +909,11 @@
     tANI_U32    actionFrameSessionId;
 #endif
     tSirBackgroundScanMode gLimBackgroundScanMode;
+
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+    tpPESession  pSessionEntry;
+    tANI_U8 reAssocRetryAttempt;
+#endif
 } tAniSirLim, *tpAniSirLim;
 
 #ifdef WLAN_FEATURE_P2P
diff --git a/CORE/MAC/inc/wniCfgAp.h b/CORE/MAC/inc/wniCfgAp.h
index e6573d2..a7b11f5 100644
--- a/CORE/MAC/inc/wniCfgAp.h
+++ b/CORE/MAC/inc/wniCfgAp.h
@@ -571,7 +571,7 @@
 
 #define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN    0
 #define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX    65535
-#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF    2000
+#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF    1000
 
 #define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_APMIN    0
 #define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_APMAX    65535
diff --git a/CORE/MAC/inc/wniCfgSta.h b/CORE/MAC/inc/wniCfgSta.h
index 682bd93..5a5aed2 100644
--- a/CORE/MAC/inc/wniCfgSta.h
+++ b/CORE/MAC/inc/wniCfgSta.h
@@ -484,7 +484,7 @@
 
 #define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN    0
 #define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX    65535
-#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF    2000
+#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF    1000
 
 #define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMIN    0
 #define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMAX    65535
diff --git a/CORE/MAC/src/cfg/cfgUtil/cfg.txt b/CORE/MAC/src/cfg/cfgUtil/cfg.txt
index 5b1d4bd..fa337c7 100644
--- a/CORE/MAC/src/cfg/cfgUtil/cfg.txt
+++ b/CORE/MAC/src/cfg/cfgUtil/cfg.txt
@@ -475,7 +475,7 @@
 WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT    I    4    7
 V    RW    NP
 NONE
-0    65535    2000
+0    65535    1000
 V    RW    NP
 NONE
 0    65535    3000
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index ca39bd8..186e8b9 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -94,6 +94,9 @@
     tpSirSmeJoinReq         pLimJoinReq;            // handle to sme join req
     tpSirSmeReassocReq      pLimReAssocReq;         //handle to sme reassoc req
     tpLimMlmJoinReq         pLimMlmJoinReq;         //handle to MLM join Req
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+    void                    *pLimMlmReassocRetryReq; //keep reasoc req for retry
+#endif
     void                    *pLimMlmReassocReq;      //handle to MLM reassoc Req
     tANI_U16                channelChangeReasonCode;
     tANI_U8                 dot11mode;
diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c
index 9a0fd9d..3026558 100644
--- a/CORE/MAC/src/pe/lim/limApi.c
+++ b/CORE/MAC/src/pe/lim/limApi.c
@@ -389,6 +389,11 @@
     palZeroMemory(pMac->hHdd, pMac->lim.protStaOverlapCache, sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE);
     palZeroMemory(pMac->hHdd, pMac->lim.protStaCache, sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE);
 
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+    pMac->lim.pSessionEntry = NULL;
+    pMac->lim.reAssocRetryAttempt = 0;
+#endif
+
 }
 
 
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.h b/CORE/MAC/src/pe/lim/limAssocUtils.h
index af6dfa9..276d17e 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.h
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.h
@@ -166,6 +166,9 @@
 
 /* API to fill in RX Highest Supported data Rate */
 void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet);
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+void limSendRetryReassocReqFrame(tpAniSirGlobal pMac, tLimMlmReassocReq *pMlmReassocReq, tpPESession psessionEntry);
+#endif
 
 
 #endif /* __LIM_ASSOC_UTILS_H */
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
index 62e1f34..b4c865d 100644
--- a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
@@ -547,7 +547,17 @@
     if (subType == LIM_ASSOC)        // Stop Association failure timer
         limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER);
     else        // Stop Reassociation failure timer
+    {
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+        pMac->lim.reAssocRetryAttempt = 0;
+        if (NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)
+        {
+            palFreeMemory( pMac->hHdd, pMac->lim.pSessionEntry->pLimMlmReassocRetryReq);
+            pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL;
+        }
+#endif
         limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
+    }
 
     if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS)
     {
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index 1279f8c..5622c58 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -2028,6 +2028,9 @@
     secChanOffset = psessionEntry->htSecondaryChannelOffset;
     //store the channel switch sessionEntry in the lim global var
     psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN;
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+    psessionEntry->pLimMlmReassocRetryReq = NULL;
+#endif
 
     limSetChannel(pMac, chanNum, secChanOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); 
 
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 47c2bed..37369e1 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -2817,7 +2817,19 @@
         mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
         goto end;
     }
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+    pMac->lim.pSessionEntry = psessionEntry;
+    if(NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)
+    {
+        /* Take a copy of reassoc request for retrying */
+        if ( !HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, sizeof(tLimMlmReassocReq))) ) goto end;
+        palZeroMemory(pMac->hHdd, pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, sizeof(tLimMlmReassocReq));
+        palCopyMemory( pMac->hHdd,pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, psessionEntry->pLimMlmReassocReq, sizeof(tLimMlmReassocReq));
+    }
+    pMac->lim.reAssocRetryAttempt = 0;
+#endif
     limSendReassocReqWithFTIEsMgmtFrame(pMac, psessionEntry->pLimMlmReassocReq, psessionEntry);
+
     psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
     psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE;
     PELOGE(limLog(pMac, LOGE,  FL("Set the mlm state to %d session=%d\n"),
diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index fc673db..fb00d00 100644
--- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -3043,6 +3043,62 @@
     psessionEntry->pLimMlmReassocReq = NULL;
 
 }
+
+void limSendRetryReassocReqFrame(tpAniSirGlobal     pMac,
+                                 tLimMlmReassocReq *pMlmReassocReq,
+                                 tpPESession psessionEntry)
+{
+    tLimMlmReassocCnf       mlmReassocCnf; // keep sme
+    tLimMlmReassocReq       *pTmpMlmReassocReq = NULL;
+    if(NULL == pTmpMlmReassocReq)
+    {
+        if ( !HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pTmpMlmReassocReq, sizeof(tLimMlmReassocReq))) ) goto end;
+        palZeroMemory(pMac->hHdd, pTmpMlmReassocReq, sizeof(tLimMlmReassocReq));
+        palCopyMemory( pMac->hHdd, pTmpMlmReassocReq, pMlmReassocReq, sizeof(tLimMlmReassocReq));
+    }
+
+    // Prepare and send Reassociation request frame
+    // start reassoc timer.
+    pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId;
+    // Start reassociation failure timer
+    MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_REASSOC_FAIL_TIMER));
+    if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+                                               != TX_SUCCESS)
+    {
+        // Could not start reassoc failure timer.
+        // Log error
+        limLog(pMac, LOGP,
+           FL("could not start Reassociation failure timer\n"));
+        // Return Reassoc confirm with
+        // Resources Unavailable
+        mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+        mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+        goto end;
+    }
+
+    limSendReassocReqWithFTIEsMgmtFrame(pMac, pTmpMlmReassocReq, psessionEntry);
+    return;
+
+end:
+    // Free up buffer allocated for reassocReq
+    if (pMlmReassocReq != NULL)
+    {
+        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmReassocReq);
+        pMlmReassocReq = NULL;
+    }
+    if (pTmpMlmReassocReq != NULL)
+    {
+        palFreeMemory( pMac->hHdd, (tANI_U8 *) pTmpMlmReassocReq);
+        pTmpMlmReassocReq = NULL;
+    }
+    mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+    mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+    /* Update PE sessio Id*/
+    mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+    limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+}
+
 #endif /* WLAN_FEATURE_VOWIFI_11R */
 
 
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
index fc73263..c00be90 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.c
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -859,6 +859,29 @@
     tSirMsgQ    msg;
     tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
 
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+    if((LIM_REASSOC == param) &&
+       (NULL != pMac->lim.pSessionEntry))
+    {
+        limLog(pMac, LOGE, FL("Reassoc timeout happened\n"));
+        if(pMac->lim.reAssocRetryAttempt < LIM_MAX_REASSOC_RETRY_LIMIT)
+        {
+            limSendRetryReassocReqFrame(pMac, pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, pMac->lim.pSessionEntry);
+            pMac->lim.reAssocRetryAttempt++;
+            limLog(pMac, LOGW, FL("Reassoc request retry is sent %d times\n"), pMac->lim.reAssocRetryAttempt);
+            return;
+        }
+        else
+        {
+            limLog(pMac, LOGW, FL("Reassoc request retry MAX(%d) reached\n"), LIM_MAX_REASSOC_RETRY_LIMIT);
+            if(NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)
+            {
+                palFreeMemory( pMac->hHdd, pMac->lim.pSessionEntry->pLimMlmReassocRetryReq);
+                pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL;
+            }
+        }
+    }
+#endif
     // Prepare and post message to LIM Message Queue
 
     msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT;
diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h
index c42e1eb..cbecaf8 100644
--- a/CORE/MAC/src/pe/lim/limUtils.h
+++ b/CORE/MAC/src/pe/lim/limUtils.h
@@ -49,6 +49,9 @@
 #define LIM_STA_ID_MASK                        0x00FF
 #define LIM_AID_MASK                              0xC000
 #define LIM_SPECTRUM_MANAGEMENT_BIT_MASK          0x0100
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
+#define LIM_MAX_REASSOC_RETRY_LIMIT            2
+#endif
 
 // classifier ID is coded as 0-3: tsid, 4-5:direction
 #define LIM_MAKE_CLSID(tsid, dir) (((tsid) & 0x0F) | (((dir) & 0x03) << 4))
diff --git a/firmware_bin/WCNSS_cfg.dat b/firmware_bin/WCNSS_cfg.dat
index bf6478c..1169eab 100644
--- a/firmware_bin/WCNSS_cfg.dat
+++ b/firmware_bin/WCNSS_cfg.dat
Binary files differ