wlan: LFR MBB preauth changes

As part of LFR make before break, add changes to handle preauth
request and response in lim and csr.

Change-Id: I4a4872f8619efd95643ee8eeb62c9a8574b413dd
CRs-Fixed: 1098427
diff --git a/CORE/MAC/src/pe/include/limFT.h b/CORE/MAC/src/pe/include/limFT.h
index d750849..bf4dd64 100644
--- a/CORE/MAC/src/pe/include/limFT.h
+++ b/CORE/MAC/src/pe/include/limFT.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -52,6 +52,7 @@
 extern int  limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
 extern void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, 
                 tpPESession psessionEntry);
+void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry);
 void        limPerformPostFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, 
                 tpPESession psessionEntry);
 void        limFTResumeLinkCb(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data);
diff --git a/CORE/MAC/src/pe/include/limFTDefs.h b/CORE/MAC/src/pe/include/limFTDefs.h
index 97625a3..ffda9af 100644
--- a/CORE/MAC/src/pe/include/limFTDefs.h
+++ b/CORE/MAC/src/pe/include/limFTDefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
diff --git a/CORE/MAC/src/pe/include/lim_mbb.h b/CORE/MAC/src/pe/include/lim_mbb.h
new file mode 100644
index 0000000..b050233
--- /dev/null
+++ b/CORE/MAC/src/pe/include/lim_mbb.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac);
+void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg);
+void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac,
+     tSirRetStatus status, tpPESession session_entry);
+
diff --git a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
index 09bb745..83dd917 100644
--- a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -51,6 +51,9 @@
 #include "limFT.h"
 #endif
 #include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
 
 
 /**
@@ -1873,15 +1876,33 @@
     limLog(pMac, LOG1, FL("Pre-Auth response received from neighbor"));
     limLog(pMac, LOG1, FL("Pre-Auth done state"));
 #endif
+
+    limLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+                          pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
     // Stopping timer now, that we have our unicast from the AP
     // of our choice.
-    limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+    if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+        limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+        limDeactivateAndChangeTimer(pMac, eLIM_PREAUTH_MBB_RSP_TIMER);
+#endif
 
 
     // Save off the auth resp.
     if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS))
     {
         limLog(pMac, LOGE, FL("failed to convert Auth frame to struct"));
+
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            lim_handle_pre_auth_mbb_rsp(pMac, eSIR_FAILURE, psessionEntry);
+            return eSIR_FAILURE;
+        }
+#endif
+
         limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
         return eSIR_FAILURE;
     }
@@ -1921,6 +1942,13 @@
             break;
     }
 
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            lim_handle_pre_auth_mbb_rsp(pMac, ret_status, psessionEntry);
+            return ret_status;
+        }
+#endif
+
     // Send the Auth response to SME
     limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry);
 
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index abc8bad..afca513 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1681,6 +1681,9 @@
         case eWNI_SME_FT_PRE_AUTH_REQ:
         case eWNI_SME_FT_AGGR_QOS_REQ:
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+        case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
+#endif
         case eWNI_SME_ADD_STA_SELF_REQ:
         case eWNI_SME_DEL_STA_SELF_REQ:
         case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
@@ -1986,6 +1989,9 @@
         case SIR_LIM_DEAUTH_ACK_TIMEOUT:
         case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
         case SIR_LIM_AUTH_RETRY_TIMEOUT:
+#ifdef WLAN_FEATURE_LFR_MBB
+        case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+#endif
             // These timeout messages are handled by MLM sub module
 
             limProcessMlmReqMessages(pMac,
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index d0eab9b..8323ebd 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -59,6 +59,9 @@
 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
 #include "vos_diag_core_log.h"
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
 
 
 // MLM REQ processing function templates
@@ -155,6 +158,11 @@
 #ifdef WLAN_FEATURE_VOWIFI_11R
         case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:limProcessFTPreauthRspTimeout(pMac); break;
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+        case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+             lim_process_preauth_mbb_rsp_timeout(pMac);
+             break;
+#endif
         case SIR_LIM_REMAIN_CHN_TIMEOUT:    limProcessRemainOnChnTimeout(pMac); break;
         case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:   
                                             limProcessInsertSingleShotNOATimeout(pMac); break;
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index d91635a..4a694f7 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -76,6 +76,10 @@
 #include <limFT.h>
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
 
 #define JOIN_FAILURE_TIMEOUT   1000   // in msecs
 /* This overhead is time for sending NOA start to host in case of GO/sending NULL data & receiving ACK 
@@ -5907,6 +5911,13 @@
             break;
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+        case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
+             lim_process_pre_auth_reassoc_req(pMac, pMsg);
+             bufConsumed = FALSE;
+             break;
+#endif
+
 #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
        case eWNI_SME_ESE_ADJACENT_AP_REPORT:
             limProcessAdjacentAPRepMsg ( pMac, pMsgBuf );
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
index 0237271..71c7dde 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.c
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -64,6 +64,10 @@
    convert  ACTIVE DFS channel to DFS channels */
 #define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT     1000
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#define PREAUTH_REASSOC_TIMEOUT     500
+#endif
+
 /**
  * limCreateTimers()
  *
@@ -624,6 +628,21 @@
     }
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    cfgValue = PREAUTH_REASSOC_TIMEOUT;
+    cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+    if (tx_timer_create(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer,
+                        "PREAUTH MBB RSP TIMEOUT",
+                        limTimerHandler, SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT,
+                        cfgValue, 0,
+                        TX_NO_ACTIVATE) != TX_SUCCESS)
+    {
+        limLog(pMac, LOGP, FL("could not create PREAUTH_MBB_RSP timer"));
+        goto err_timer;
+    }
+#endif
+
 #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
     cfgValue = 5000;
     cfgValue = SYS_MS_TO_TICKS(cfgValue);
@@ -712,6 +731,9 @@
         tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer);
 #endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */
         tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
+#ifdef WLAN_FEATURE_LFR_MBB
+        tx_timer_delete(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer);
+#endif
         tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
         while(((tANI_S32)--i) >= 0)
         {
@@ -1730,6 +1752,18 @@
             }
             break;
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+        case eLIM_PREAUTH_MBB_RSP_TIMER:
+            if (tx_timer_deactivate(&pMac->lim.limTimers.
+                          glim_pre_auth_mbb_rsp_timer) != TX_SUCCESS) {
+                limLog(pMac, LOGP,
+                       FL("Unable to deactivate preauth response mbb timer"));
+                return;
+            }
+            break;
+#endif
+
 #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
          case eLIM_TSM_TIMER:
              if (tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer)
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.h b/CORE/MAC/src/pe/lim/limTimerUtils.h
index 1906182..67e06fc 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.h
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -77,7 +77,10 @@
     eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
     eLIM_INSERT_SINGLESHOT_NOA_TIMER,
     eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE,
-    eLIM_AUTH_RETRY_TIMER
+    eLIM_AUTH_RETRY_TIMER,
+#ifdef WLAN_FEATURE_LFR_MBB
+    eLIM_PREAUTH_MBB_RSP_TIMER
+#endif
 };
 
 #define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT         500
diff --git a/CORE/MAC/src/pe/lim/limTrace.c b/CORE/MAC/src/pe/lim/limTrace.c
index 662670b..02f3087 100644
--- a/CORE/MAC/src/pe/lim/limTrace.c
+++ b/CORE/MAC/src/pe/lim/limTrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -92,6 +92,9 @@
         CASE_RETURN_STRING(eLIM_INSERT_SINGLESHOT_NOA_TIMER);
         CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
         CASE_RETURN_STRING(eLIM_AUTH_RETRY_TIMER);
+#ifdef WLAN_FEATURE_LFR_MBB
+        CASE_RETURN_STRING(eLIM_PREAUTH_MBB_RSP_TIMER);
+#endif
         default:
             return( "UNKNOWN" );
             break;
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
index 42fe6cd..4936ed9 100644
--- a/CORE/MAC/src/pe/lim/limUtils.c
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -648,6 +648,11 @@
             return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT";
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+        case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+            return "SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT";
+#endif
+
         case SIR_HAL_APP_SETUP_NTF:
             return "SIR_HAL_APP_SETUP_NTF";
         case SIR_HAL_INITIAL_CAL_FAILED_NTF:
diff --git a/CORE/MAC/src/pe/lim/lim_mbb.c b/CORE/MAC/src/pe/lim/lim_mbb.c
new file mode 100644
index 0000000..42e27ef
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/lim_mbb.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aniGlobal.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limFT.h"
+#include "limSendMessages.h"
+
+/**
+ * lim_post_pre_auth_reassoc_rsp() -Posts preauth_reassoc response to SME
+ * @mac: MAC context
+ * @status: status
+ * @session_entry: session entry
+ *
+ * This function process preauth request received from CSR
+ */
+void lim_post_pre_auth_reassoc_rsp(tpAniSirGlobal mac,
+     tSirRetStatus status, tpPESession session_entry)
+{
+    tpSirFTPreAuthRsp pre_auth_rsp;
+    tSirMsgQ mmh_msg;
+    tANI_U16 rsp_len = sizeof(tSirFTPreAuthRsp);
+
+    pre_auth_rsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rsp_len);
+    if (NULL == pre_auth_rsp) {
+        limLog(mac, LOGE, FL("Failed to allocate memory"));
+        return;
+    }
+
+    vos_mem_zero(pre_auth_rsp, rsp_len);
+    pre_auth_rsp->messageType = eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP;
+    pre_auth_rsp->length = (tANI_U16)rsp_len;
+    pre_auth_rsp->status = status;
+
+    if (session_entry)
+        pre_auth_rsp->smeSessionId = session_entry->smeSessionId;
+
+    /* The bssid of the AP we are sending Auth1 to. */
+    if (mac->ft.ftPEContext.pFTPreAuthReq)
+        sirCopyMacAddr(pre_auth_rsp->preAuthbssId,
+                       mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId);
+
+    if (status != eSIR_SUCCESS) {
+        limLog(mac, LOG1, "Pre-Auth Failed, Cleanup!");
+        limFTCleanup(mac);
+    }
+
+    mmh_msg.type = pre_auth_rsp->messageType;
+    mmh_msg.bodyptr = pre_auth_rsp;
+    mmh_msg.bodyval = 0;
+
+    limLog(mac, LOG1,
+           FL("Posted Auth Rsp to SME with status of 0x%x"), status);
+
+    limSysProcessMmhMsgApi(mac, &mmh_msg, ePROT);
+}
+
+/*
+ * lim_process_preauth_mbb_result() -process pre auth result
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function invokes resume callback
+ */
+static inline void lim_process_preauth_mbb_result(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data)
+{
+    tpPESession session_entry;
+
+    if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+        limLog(mac, LOG1, "Pre-Auth request is NULL!");
+        return;
+    }
+
+    session_entry = (tpPESession)data;
+
+    /* Post the FT Pre Auth Response to SME in case of failure*/
+    if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_FAILURE) {
+        lim_post_pre_auth_reassoc_rsp(mac,
+                  mac->ft.ftPEContext.ftPreAuthStatus, session_entry);
+        return;
+    }
+
+    /* Flow for preauth success */
+    limFTSetupAuthSession(mac, session_entry);
+}
+
+/*
+ * lim_perform_post_preauth_mbb_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback after successful reception of
+ * pre auth
+ */
+static inline
+void lim_perform_post_preauth_mbb_channel_change(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+    peSetResumeChannel(mac, 0, 0);
+    limResumeLink(mac, lim_process_preauth_mbb_result,
+                                (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_pre_auth_mbb_rsp() -handles preauth response
+ * @mac: MAC context
+ * @status: status of message
+ * @session_entry: session entry
+ *
+ * This function process preauth response
+ */
+void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac,
+     tSirRetStatus status, tpPESession session_entry)
+{
+    tpPESession ft_session_entry;
+    tANI_U8 session_id;
+    tpSirBssDescription  bss_description;
+
+    mac->ft.ftPEContext.ftPreAuthStatus = status;
+
+    mac->ft.ftPEContext.saved_auth_rsp_length = 0;
+
+    limLog(mac, LOG1, FL("preauth status %d"),
+                         mac->ft.ftPEContext.ftPreAuthStatus);
+
+    /* Create FT session for the re-association at this point */
+    if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+        bss_description = mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription;
+        if((ft_session_entry = peCreateSession(mac, bss_description->bssId,
+                                  &session_id, mac->lim.maxStation)) == NULL) {
+            limLog(mac, LOGE,
+                   FL("session can not be created for pre-auth AP"));
+            mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+            goto out;
+        }
+        ft_session_entry->peSessionId = session_id;
+        sirCopyMacAddr(ft_session_entry->selfMacAddr,
+                                 session_entry->selfMacAddr);
+        sirCopyMacAddr(ft_session_entry->limReAssocbssId,
+                                     bss_description->bssId);
+        ft_session_entry->bssType = session_entry->bssType;
+
+        if (ft_session_entry->bssType == eSIR_INFRASTRUCTURE_MODE)
+            ft_session_entry->limSystemRole = eLIM_STA_ROLE;
+
+        ft_session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+        mac->ft.ftPEContext.pftSessionEntry = ft_session_entry;
+        limLog(mac, LOG1,"%s:created session (%p) with id = %d",
+               __func__, ft_session_entry, ft_session_entry->peSessionId);
+
+        /* Update the ReAssoc BSSID of the current session */
+        sirCopyMacAddr(session_entry->limReAssocbssId, bss_description->bssId);
+        limPrintMacAddr(mac, session_entry->limReAssocbssId, LOG1);
+    }
+out:
+    if (session_entry->currentOperChannel !=
+        mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+        limChangeChannelWithCallback(mac, session_entry->currentOperChannel,
+              lim_perform_post_preauth_mbb_channel_change, NULL, session_entry);
+     } else {
+        /* Link needs to be resumed as link was suspended for same channel */
+        peSetResumeChannel(mac, 0, 0);
+        limResumeLink(mac, lim_process_preauth_mbb_result,
+                                           (tANI_U32 *)session_entry);
+     }
+}
+
+/**
+ * lim_process_preauth_mbb_rsp_timeout() -Process preauth response timeout
+ * @mac: MAC context
+ *
+ * This function is called if preauth response is not received from the AP
+ * within timeout
+ */
+void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac)
+{
+    tpPESession session_entry;
+
+    /*
+     * Pre auth is failed. Need to resume link and get back on
+     * to home channel.
+     */
+    limLog(mac, LOG1, FL("Pre-Auth MBB Time Out!!!!"));
+
+    if((session_entry = peFindSessionBySessionId(mac,
+        mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId))== NULL) {
+        limLog(mac, LOGE, FL("session does not exist for given session id"));
+        return;
+    }
+
+    /*
+     * To handle the race condition where we recieve preauth rsp after
+     * timer has expired.
+     */
+    if (mac->ft.ftPEContext.pFTPreAuthReq == NULL) {
+        limLog(mac, LOGE, FL("Auth Rsp might already be posted to SME"
+               "and cleanup done! sessionId:%d"),
+                mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId);
+        return;
+    }
+
+    if (eANI_BOOLEAN_TRUE ==
+         mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+         limLog(mac, LOGE,
+                FL("Auth rsp already posted to SME session %p"), session_entry);
+         return;
+    } else {
+    /*
+     * Here we are sending preauth rsp with failure state
+     * and which is forwarded to SME. Now, if we receive an preauth
+     * resp from AP with success it would create a FT pesession, but
+     * will be dropped in SME leaving behind the pesession.
+     * Mark Preauth rsp processed so that any rsp from AP is dropped in
+     * limProcessAuthFrameNoSession.
+     */
+     limLog(mac,LOG1,
+            FL("Auth rsp not yet posted to SME session %p)"), session_entry);
+            mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
+           eANI_BOOLEAN_TRUE;
+     }
+     /*
+      * Ok, so attempted a Pre-Auth and failed. If we are off channel. We need
+      * to get back.
+      */
+     lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry);
+ }
+
+/**
+ * lim_perform_pre_auth_reassoc() -Sends preauth request
+ * @mac: MAC context
+ * @status: status of message
+ * @data: gives information of session
+ * @session_entry: session entry
+ *
+ * This function process preauth request received from CSR
+ */
+static inline
+void lim_perform_pre_auth_reassoc(tpAniSirGlobal mac, eHalStatus status,
+     tANI_U32 *data, tpPESession session_entry)
+{
+    tSirMacAuthFrameBody authFrame;
+
+    if (status != eHAL_STATUS_SUCCESS) {
+        limLog(mac, LOGE,
+               FL("Change channel not successful for pre-auth"));
+        goto preauth_fail;
+    }
+
+    limLog(mac, LOGE,
+           FL("session id %d"), session_entry->peSessionId);
+
+    mac->ft.ftPEContext.psavedsessionEntry = session_entry;
+
+    authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
+    authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+    authFrame.authStatusCode = 0;
+
+    /* Start timer here to come back to operating channel. */
+    mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId =
+                                                session_entry->peSessionId;
+
+    limSendAuthMgmtFrame(mac, &authFrame,
+         mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+         LIM_NO_WEP_IN_FC, session_entry, eSIR_FALSE);
+
+    if(TX_SUCCESS !=
+          tx_timer_activate(&mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer)) {
+       limLog(mac, LOGE, FL("Pre Auth MBB Rsp Timer Start Failed"));
+
+       mac->ft.ftPEContext.psavedsessionEntry = NULL;
+       goto preauth_fail;
+    }
+
+    return;
+
+preauth_fail:
+     lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry);
+     return;
+}
+
+/**
+ * pre_auth_mbb_suspend_link_handler() -Handler for suspend link
+ * @mac: MAC context
+ * @status: status of message
+ * @data: gives information of session
+ *
+ * This function process preauth request received from CSR
+ */
+static inline
+void pre_auth_mbb_suspend_link_handler(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data)
+{
+    tpPESession session_entry;
+
+    if (status != eHAL_STATUS_SUCCESS) {
+        limLog(mac, LOGE, FL("Link suspend failed"));
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, (tpPESession)data);
+        return;
+    }
+
+    session_entry = (tpPESession)data;
+
+    if (session_entry->currentOperChannel !=
+                mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+        limChangeChannelWithCallback(mac,
+                mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+                lim_perform_pre_auth_reassoc, NULL, session_entry);
+        return;
+    } else {
+        lim_perform_pre_auth_reassoc(mac, eHAL_STATUS_SUCCESS,
+                                  NULL, session_entry);
+        return;
+    }
+}
+
+/**
+ * lim_process_pre_auth_reassoc_req() -Process preauth request
+ * @hal: HAL context
+ * @msg: message
+ *
+ * This function process preauth request received from CSR
+ */
+void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg)
+{
+    tpPESession session_entry;
+    tANI_U8 session_id;
+
+    limFTInit(mac);
+
+    /* Can set it only after sending auth */
+    mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+
+    /* We need information from the Pre-Auth Req. Lets save that */
+    mac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)msg->bodyptr;
+    if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+        limLog(mac, LOGE,
+               FL("pFTPreAuthReq is NULL"));
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL);
+        return;
+    }
+
+    /* Get the current session entry */
+    session_entry = peFindSessionByBssid(mac,
+                    mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id);
+    if (session_entry == NULL) {
+        limLog(mac, LOGE,
+               FL("Unable to find session for the following bssid"));
+        limPrintMacAddr(mac,
+                        mac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE);
+
+        /* Post the pre auth response to SME */
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL);
+    }
+
+    limLog(mac, LOG1,
+           FL("set link with eSIR_LINK_PRE_AUTH_REASSOC_STATE"));
+
+    if (limSetLinkState(mac, eSIR_LINK_PRE_AUTH_REASSOC_STATE,
+                        session_entry->bssId, session_entry->selfMacAddr,
+                        NULL, NULL) != eSIR_SUCCESS) {
+        limLog(mac, LOGE,
+               FL("set link failed for eSIR_LINK_PRE_AUTH_REASSOC_STATE"));
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL);
+        return;
+    }
+
+    /*
+     * Suspend link for same channel or different channel so that STA
+     * can be in power save for connected AP.
+     */
+    limLog(mac, LOG1,
+           FL("pre-auth on channel %d (session %p) currentOperChannel %d"),
+           mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+           session_entry, session_entry->currentOperChannel);
+    limSuspendLink(mac, eSIR_CHECK_ROAMING_SCAN,
+                   pre_auth_mbb_suspend_link_handler,
+                  (tANI_U32 *)session_entry);
+}