Merge "wlan: At very low RSSI increase throttle down of TX traffic" into wlan-driver.lnx.1.0-dev.1.0
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 04ebf82..5a52a2c 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -3043,6 +3043,15 @@
 #define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX        (100)
 #define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT    (10)
 
+/*
+ * gEnableLFRMBB is used to disable/enable LFR Make before Break
+ * 1: Enable LFR Make before Break
+ * 0: Disable LFR Make before Break
+ */
+#define CFG_ENABLE_LFR_MBB         "gEnableLFRMBB"
+#define CFG_ENABLE_LFR_MBB_MIN     (0)
+#define CFG_ENABLE_LFR_MBB_MAX     (1)
+#define CFG_ENABLE_LFR_MBB_DEFAULT (0)
 
 /*--------------------------------------------------------------------------- 
   Type declarations
@@ -3274,6 +3283,11 @@
    v_U32_t                      PERtimerThreshold;
    v_U32_t                      PERroamRxPktsThreshold;
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+   tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
    hdd_wmm_classification_t     PktClassificationBasis; // DSCP or 802.1Q
    v_BOOL_t                     bImplicitQosEnabled;
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 956f5fb..c485114 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2877,6 +2877,15 @@
                  CFG_PER_ROAM_BAD_RSSI_MAX),
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+   REG_VARIABLE(CFG_ENABLE_LFR_MBB, WLAN_PARAM_Integer,
+                hdd_config_t, enable_lfr_mbb,
+                VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+                CFG_ENABLE_LFR_MBB_DEFAULT,
+                CFG_ENABLE_LFR_MBB_MIN,
+                CFG_ENABLE_LFR_MBB_MAX ),
+#endif
+
    REG_VARIABLE( CFG_ENABLE_ADAPT_RX_DRAIN_NAME, WLAN_PARAM_Integer,
                  hdd_config_t, fEnableAdaptRxDrain,
                  VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK ,
@@ -4530,6 +4539,13 @@
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
         "Name = [gEnableSapInternalRestart] Value = [%u] ",
          pHddCtx->cfg_ini->sap_internal_restart);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+          "Name = [gEnableLFRMBB] Value = [%u] ",
+           pHddCtx->cfg_ini->enable_lfr_mbb);
+#endif
+
 }
 
 
@@ -6412,6 +6428,11 @@
        smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0;
    }
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+   smeConfig->csrConfig.enable_lfr_mbb = pConfig->enable_lfr_mbb;
+#endif
+
 #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
    smeConfig->csrConfig.neighborRoamConfig.nNeighborReassocRssiThreshold = pConfig->nNeighborReassocRssiThreshold;
    smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold = pConfig->nNeighborLookupRssiThreshold;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 71365ea..d58daae 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -20059,6 +20059,12 @@
             buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
             buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
 
+            if (buf_len > sizeof(*hb_params)) {
+                hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
+                       buf_len);
+                return -ERANGE;
+            }
+
             hb_params_temp =(tSirLPHBReq *)buf;
             if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
                 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 0d93f1c..d63d73e 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -4450,6 +4450,14 @@
         return 0;
     }
 
+    if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN)
+    {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                  "%s: WPARSN Ie input length is more than max[%d]", __func__,
+                  wrqu->data.length);
+        return -EINVAL;
+   }
+
     switch (genie[0])
     {
         case DOT11F_EID_WPA:
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 8197357..ddfbc23 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -230,6 +230,11 @@
     TX_TIMER           gLimFTPreAuthRspTimer;
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    TX_TIMER           glim_pre_auth_mbb_rsp_timer;
+    TX_TIMER           glim_reassoc_mbb_rsp_timer;
+#endif
+
 #ifdef FEATURE_WLAN_ESE
     TX_TIMER           gLimEseTsmTimer;
 #endif
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 42b4ffc..3f8edad 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -6338,4 +6338,30 @@
     void * tsf_rsp_cb_ctx;
 }tSirCapTsfParams,*tpSirCapTsfParams;
 
+#ifdef WLAN_FEATURE_LFR_MBB
+
+/**
+ * enum csr_roam_op_code - Operation to be done by the callback.
+ * @SIR_ROAMING_DEREGISTER_STA: Deregister the old STA after roaming.
+ * @SIR_STOP_ROAM_OFFLOAD_SCAN : sends RSO stop
+ * @SIR_PREPARE_REASSOC_REQ: prepares reassoc request
+ */
+enum csr_roam_op_code {
+    SIR_ROAMING_DEREGISTER_STA,
+    SIR_STOP_ROAM_OFFLOAD_SCAN,
+    SIR_PREPARE_REASSOC_REQ,
+};
+
+/**
+ * enum sir_roam_cleanup_type - Type of cleanup needs to be performed.
+ * @SIR_MBB_DISCONNECTED: Entire CSR cleanup for connected AP
+ * needs to be performed
+ * @SIR_MBB_CONNECTED: No need to perform CSR cleanup for connected AP.
+ */
+enum sir_roam_cleanup_type {
+    SIR_MBB_DISCONNECTED,
+    SIR_MBB_CONNECTED,
+};
+#endif
+
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 718af27..6ed2bb0 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -389,6 +389,12 @@
     eWNI_SME_REGISTER_MGMT_FRAME_CB,
     eWNI_SME_CAP_TSF_REQ,
     eWNI_SME_GET_TSF_REQ,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ,
+    eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP,
+#endif
+
     eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 9752eb7..17be814 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -151,6 +151,9 @@
     */
    SAP_OFFLOADS = 65,
    SAP_BUFF_ALLOC = 66,
+#ifdef WLAN_FEATURE_LFR_MBB
+   MAKE_BEFORE_BREAK = 67,
+#endif
    NUD_DEBUG = 68,
    //MAX_FEATURE_SUPPORTED = 128
 } placeHolderInCapBitmap;
@@ -175,6 +178,11 @@
     eSIR_LINK_FINISH_CAL_STATE  = 13,
     eSIR_LINK_LISTEN_STATE      = 14,
     eSIR_LINK_SEND_ACTION_STATE = 15,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
+
 } tSirLinkState;
 
 
@@ -895,6 +903,11 @@
 #define SIR_LIM_DEAUTH_ACK_TIMEOUT       (SIR_LIM_TIMEOUT_MSG_START + 0x27)
 #define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x28)
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#define SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT   (SIR_LIM_TIMEOUT_MSG_START + 0x29)
+#define SIR_LIM_REASSOC_MBB_RSP_TIMEOUT   (SIR_LIM_TIMEOUT_MSG_START + 0x2A)
+#endif
+
 #define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
 #define SIR_LIM_AUTH_RETRY_TIMEOUT            (SIR_LIM_TIMEOUT_MSG_START + 0x2D)
 
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..02b9d5f 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.
  *
@@ -81,6 +81,10 @@
    tANI_U8          ft_ies[MAX_FTIE_SIZE];
    tANI_U16         ric_ies_length;
    tANI_U8          ric_ies[MAX_FTIE_SIZE];
+#ifdef WLAN_FEATURE_LFR_MBB
+   enum sir_roam_cleanup_type reason;
+   tCsrRoamInfo *roam_info;
+#endif
 } tSirFTPreAuthRsp, *tpSirFTPreAuthRsp;
 
 /*--------------------------------------------------------------------------
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index e517bfb..f00449c 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -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.
  *
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..770263e
--- /dev/null
+++ b/CORE/MAC/src/pe/include/lim_mbb.h
@@ -0,0 +1,48 @@
+/*
+ * 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);
+void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac);
+void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac,
+     tpPESession session_entry);
+void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac,
+     tpPESession session_entry, tpSirAssocRsp  assoc_rsp, tpDphHashNode sta_ds);
+void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac,
+     tpSirMsgQ lim_msg, tpPESession session_entry);
+void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac,
+     tpSirMsgQ lim_msg, tpPESession session_entry);
+void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac,
+     tpSirMsgQ limMsgQ,tpPESession session_entry);
+void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac,
+     tpSirMsgQ limMsgQ,tpPESession session_entry);
+eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac,
+     tpPESession session_entry);
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.h b/CORE/MAC/src/pe/lim/limAssocUtils.h
index d44afc5..8b4705a 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.h
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -188,6 +188,7 @@
                             tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval);
 #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
 
+tANI_U16 __limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf);
 
 #endif /* __LIM_ASSOC_UTILS_H */
 
diff --git a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
index 36b7a68..d60902a 100644
--- a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
+++ b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.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.
  *
@@ -55,6 +55,9 @@
 #endif //FEATURE_WLAN_DIAG_SUPPORT
 #include "limSession.h"
 #include "limSerDesUtils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
 
 
 /**
@@ -111,6 +114,15 @@
         return;
     }
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+    {
+        limLog(pMac, LOGE,
+             FL("Ignore delete sta as LFR MBB in progress"));
+        return;
+    }
+#endif
+
     switch(pMsg->reasonCode)
     {
         case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE:
@@ -474,6 +486,15 @@
     /* Ensure HB Status for the session has been reseted */
     psessionEntry->LimHBFailureStatus = eANI_BOOLEAN_FALSE;
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+    {
+        limLog(pMac, LOGE,
+               FL("Ignore Heartbeat failure as LFR MBB in progress"));
+        return;
+    }
+#endif
+
     if (((psessionEntry->limSystemRole == eLIM_STA_ROLE)||
          (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
          (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)&&
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index ab54e41..8b402d1 100644
--- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.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.
  *
@@ -68,6 +68,10 @@
 #endif
 #include "wlan_qct_wda.h"
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
 
 #define BA_DEFAULT_TX_BUFFER_SIZE 64
 
@@ -169,7 +173,16 @@
 tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
 {
     limLog(pMac, LOG1, FL(" ENTER"));
-    
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+    {
+        limLog(pMac, LOGE,
+             FL("Ignore channel switch as LFR MBB in progress"));
+        return eSIR_SUCCESS;
+    }
+#endif
+
     /*If channel switch is already running and it is on a different session, just return*/  
     /*This need to be removed for MCC */
     if( limIsChanSwitchRunning (pMac) &&
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
index d08df5b..6ff2251 100644
--- a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.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.
  *
@@ -56,6 +56,10 @@
 #include "eseApi.h"
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
 extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry);
 
 
@@ -636,6 +640,11 @@
         limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER);
     else        // Stop Reassociation failure timer
     {
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+        limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_MBB_RSP_TIMER);
+#endif
+
 #if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
         pMac->lim.reAssocRetryAttempt = 0;
         if ((NULL != pMac->lim.pSessionEntry) && (NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq))
@@ -644,7 +653,10 @@
             pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL;
         }
 #endif
-        limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+        /* Dactivate timer when it is not LFR MBB */
+        if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+            limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
     }
 
     if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS)
@@ -668,6 +680,9 @@
         }else
             mlmAssocCnf.resultCode = eSIR_SME_ASSOC_REFUSED;
 
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+            goto assocReject;
+
         // Delete Pre-auth context for the associated BSS
         if (limSearchPreAuthList(pMac, pHdr->sa))
             limDeletePreAuthNode(pMac, pHdr->sa);
@@ -696,18 +711,22 @@
      * assoc/reassoc response
      * NOTE: for BTAMP case, it is being handled in limProcessMlmAssocReq
      */
-    if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) ||
-          ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) &&
-          (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))))
-    {
-            if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId,
-                                psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+    if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+       if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) ||
+              ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) &&
+              (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))))
+        {
+            if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE,
+                                psessionEntry->bssId,
+                                psessionEntry->selfMacAddr,
+                                NULL, NULL) != eSIR_SUCCESS)
             {
                 PELOGE(limLog(pMac, LOGE, FL("Set link state to POSTASSOC failed"));)
                 vos_mem_free(pBeaconStruct);
                 vos_mem_free(pAssocRsp);
                 return;
             }
+        }
     }
     if (subType == LIM_REASSOC)
     {
@@ -776,6 +795,21 @@
             goto assocReject;
         }
 
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            limLog(pMac, LOG1, FL("Reassoc success for LFR MBB in state %d"),
+                   psessionEntry->limMlmState);
+            if (psessionEntry->limMlmState ==
+                             eLIM_MLM_WT_REASSOC_RSP_STATE) {
+                lim_handle_reassoc_mbb_success(pMac, psessionEntry,
+                                               pAssocRsp, pStaDs);
+                return;
+            }
+            goto assocReject;
+        }
+#endif
+
+
 #if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
         if (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
         {
@@ -962,6 +996,14 @@
         }
 #endif /* WLAN_FEATURE_VOWIFI_11R */
     } else {
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            lim_handle_reassoc_mbb_fail(pMac, psessionEntry);
+            vos_mem_free(pBeaconStruct);
+            vos_mem_free(pAssocRsp);
+            return;
+        }
+#endif
         limRestorePreReassocState( pMac, 
                   eSIR_SME_REASSOC_REFUSED, mlmAssocCnf.protStatusCode,psessionEntry); 
     }
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/limProcessDeauthFrame.c b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
index a7d4df8..ef1056e 100644
--- a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -36,6 +36,9 @@
 #include "limSerDesUtils.h"
 #include "schApi.h"
 #include "limSendMessages.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
 
 
 
@@ -77,7 +80,6 @@
 
     pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
 
-
     if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))
     {
         /*Every 15th deauth frame will be logged in kmsg*/
@@ -229,6 +231,14 @@
     {
         pRoamSessionEntry = peFindSessionByBssid(pMac, psessionEntry->limReAssocbssId, &roamSessionId);
     }
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) {
+        limLog(pMac, LOGE, FL("Ignore Deauth frame as LFR MBB in progress"));
+        return;
+    }
+#endif
+
     if (limIsReassocInProgress(pMac,psessionEntry) || limIsReassocInProgress(pMac,pRoamSessionEntry)) {
         if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
             PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from unknown/different "
diff --git a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
index 6483854..88585ab 100644
--- a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.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.
  *
@@ -49,6 +49,9 @@
 #include "limSerDesUtils.h"
 #include "limSendMessages.h"
 #include "schApi.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
 
 
 /**
@@ -84,7 +87,6 @@
     pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
     pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
 
-
     if (limIsGroupAddr(pHdr->sa))
     {
         // Received Disassoc frame from a BC/MC address
@@ -160,6 +162,13 @@
         return;
     }
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) {
+        limLog(pMac, LOGE, FL("Ignore Disassoc frame as LFR MBB in progress"));
+        return;
+    }
+#endif
+
     /** If we are in the Wait for ReAssoc Rsp state */
     if (limIsReassocInProgress(pMac,psessionEntry)) {
         /** If we had received the DisAssoc from,
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index abc8bad..15d6c64 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -776,6 +776,7 @@
     tANI_U8             sessionId;
     tAniBool            isFrmFt = FALSE;
     tANI_U16            fcOffset = WLANHAL_RX_BD_HEADER_SIZE;
+    tANI_S8             pe_sessionid = -1;
 
     *pDeferMsg= false;
     limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
@@ -875,6 +876,24 @@
             pMac->PERroamCandidatesCnt = 0;
         }
 
+        pe_sessionid = limGetInfraSessionId(pMac);
+        if (pe_sessionid != -1) {
+            psessionEntry = peFindSessionBySessionId(pMac, pe_sessionid);
+            if (psessionEntry != NULL)
+            {
+                if ((psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
+                    (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE))
+                {
+                     limLog(pMac, LOG1,
+                       FL("Drop candidate ind as deauth/disassoc in progress"));
+                     goto end;
+                }
+            }
+        }
+        else
+         limLog(pMac, LOGE,
+               FL("session id doesn't exist for infra"));
+
         //send a session 0 for now - TBD
         limSendSmeCandidateFoundInd(pMac, 0);
         goto end;
@@ -1681,6 +1700,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 +2008,10 @@
         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:
+        case SIR_LIM_REASSOC_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..2c9a860 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,14 @@
 #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;
+        case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+             lim_process_reassoc_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/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 98cdc5c..feb52ac 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -61,6 +61,10 @@
 #include "wlan_qct_wda.h"
 #include "vos_utils.h"
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
 static void limHandleSmeJoinResult(tpAniSirGlobal, tSirResultCodes, tANI_U16,tpPESession);
 static void limHandleSmeReaasocResult(tpAniSirGlobal, tSirResultCodes, tANI_U16, tpPESession);
 void limProcessMlmScanCnf(tpAniSirGlobal, tANI_U32 *);
@@ -1981,6 +1985,12 @@
         limProcessBtAmpApMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
         return;
     }
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            lim_process_sta_mlm_add_sta_rsp_mbb(pMac, limMsgQ, psessionEntry);
+            return;
+        }
+#endif
     limProcessStaMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
 }
 void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry)
@@ -2158,6 +2168,13 @@
     tpDphHashNode pStaDs =              dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
     tSirResultCodes statusCode =        eSIR_SME_SUCCESS;
 
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            lim_process_sta_mlm_del_bss_rsp_mbb(pMac, limMsgQ, psessionEntry);
+            return;
+        }
+#endif
+
     if (NULL == pDelBssParams)
     {
         limLog( pMac, LOGE, FL( "Invalid body pointer in message"));
@@ -2431,6 +2448,13 @@
     tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
     tpDphHashNode     pStaDs        = NULL;
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+        lim_process_sta_mlm_del_sta_rsp_mbb(pMac, limMsgQ, psessionEntry);
+        return;
+    }
+#endif
+
     if(NULL == pDelStaParams )
     {
         limLog( pMac, LOGE, FL( "Encountered NULL Pointer" ));
@@ -3430,9 +3454,16 @@
             else
             limProcessApMlmAddBssRsp( pMac,limMsgQ);
         }
-        else
+        else {
+#ifdef WLAN_FEATURE_LFR_MBB
+        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+            lim_process_sta_mlm_add_bss_rsp_mbb(pMac, limMsgQ, psessionEntry);
+            return;
+        }
+#endif
             /* Called while processing assoc response */
             limProcessStaMlmAddBssRsp( pMac, limMsgQ,psessionEntry);
+        }
     }
 
     if(limIsInMCC(pMac))
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index d91635a..1a26981 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 
@@ -243,7 +247,7 @@
  * @return    Total IE length
  */
 
-static tANI_U16
+tANI_U16
 __limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf)
 {
     tANI_U16 len = 0;
@@ -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/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index 85c577b..44bebf2 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.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.
  *
@@ -54,7 +54,7 @@
 #include "limSendSmeRspMessages.h"
 #include "limIbssPeerMgmt.h"
 #include "limSessionUtils.h"
-
+#include "lim_mbb.h"
 
 /**
  * limSendSmeRsp()
@@ -2815,10 +2815,8 @@
     {
          limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry);
     }
-           
     else
          limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry);
-    
 }
 
 #ifdef WLAN_FEATURE_VOWIFI_11R
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
index cbd2e4d..23c53bd 100644
--- a/CORE/MAC/src/pe/lim/limSession.c
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
index 0237271..1e47421 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,34 @@
     }
 #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;
+    }
+
+    cfgValue = PREAUTH_REASSOC_TIMEOUT;
+    cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+    if (tx_timer_create(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer,
+                        "REASSOC MBB RSP TIMEOUT",
+                        limTimerHandler, SIR_LIM_REASSOC_MBB_RSP_TIMEOUT,
+                        cfgValue, 0,
+                        TX_NO_ACTIVATE) != TX_SUCCESS)
+    {
+        limLog(pMac, LOGP, FL("could not create REASSOC_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 +744,10 @@
         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);
+        tx_timer_delete(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer);
+#endif
         tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
         while(((tANI_S32)--i) >= 0)
         {
@@ -1730,6 +1766,30 @@
             }
             break;
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+        case eLIM_PREAUTH_MBB_RSP_TIMER:
+            MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE,
+                                  NO_SESSION, 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;
+        case eLIM_REASSOC_MBB_RSP_TIMER:
+            MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE,
+                                  NO_SESSION, eLIM_REASSOC_MBB_RSP_TIMER));
+            if (tx_timer_deactivate(&pMac->lim.limTimers.
+                          glim_reassoc_mbb_rsp_timer) != TX_SUCCESS) {
+                limLog(pMac, LOGP,
+                       FL("Unable to deactivate reassoc 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..eba64ac 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,11 @@
     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,
+    eLIM_REASSOC_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..d33a33d 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,10 @@
         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);
+        CASE_RETURN_STRING(eLIM_REASSOC_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..abcd9b7 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,13 @@
             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";
+        case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+            return "SIR_LIM_REASSOC_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..e9977b5
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/lim_mbb.c
@@ -0,0 +1,1754 @@
+/*
+ * 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"
+#include "limAssocUtils.h"
+#include "limSerDesUtils.h"
+#include "limSmeReqUtils.h"
+#include "limAdmitControl.h"
+#include "sirApi.h"
+#include "rrmApi.h"
+#include "wlan_qct_tl.h"
+
+#define PREAUTH_REASSOC_TIMEOUT 500
+
+void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+     tpPESession session_entry);
+
+/**
+ * lim_post_pre_auth_reassoc_rsp() -Posts preauth_reassoc response to SME
+ * @mac: MAC context
+ * @status: status
+ * @session_entry: session entry
+ * @reason: indicates which type of clean up needs to be performed
+ *
+ * This function process preauth_reassoc response to SME
+ */
+void lim_post_pre_auth_reassoc_rsp(tpAniSirGlobal mac,
+     tSirRetStatus status, tpPESession session_entry,
+     enum sir_roam_cleanup_type reason)
+{
+    tpSirFTPreAuthRsp pre_auth_rsp;
+    tSirMsgQ mmh_msg;
+    tANI_U16 rsp_len = sizeof(tSirFTPreAuthRsp);
+    tpPESession session_entry_con_ap;
+    tpDphHashNode sta_ds = NULL;
+
+    pre_auth_rsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rsp_len);
+    if (NULL == pre_auth_rsp) {
+        limLog(mac, LOGE, FL("Failed to allocate memory"));
+        return;
+    }
+
+    limLog(mac, LOG1, FL("reason %d"), reason);
+
+    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;
+    pre_auth_rsp->reason = reason;
+
+    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, FL("Pre-Auth Failed, Cleanup!"));
+        limLog(mac, LOG1, FL("flushing cached packets"));
+        WLANTL_PreAssocForward(false);
+
+        /*
+        * If reason is full clean up, add sme session id that
+        * will be useful in CSR during cleanup.
+        */
+        if (reason == SIR_MBB_DISCONNECTED) {
+            session_entry_con_ap =
+               (tpPESession)mac->ft.ftPEContext.psavedsessionEntry;
+            pre_auth_rsp->smeSessionId =
+                  session_entry_con_ap->smeSessionId;
+        }
+        limFTCleanup(mac);
+    }
+
+    if (status == eSIR_SUCCESS) {
+        limLog(mac, LOG1, FL("Success"));
+
+        rsp_len = session_entry->assocReqLen + session_entry->assocRspLen +
+                  session_entry->bcnLen;
+
+        pre_auth_rsp->roam_info = vos_mem_malloc(sizeof(tCsrRoamInfo));
+        if (pre_auth_rsp->roam_info == NULL) {
+            limLog(mac, LOGE,
+                   FL("Failed to allocate memory for roam info"));
+            return;
+        }
+        vos_mem_set(pre_auth_rsp->roam_info, sizeof(tCsrRoamInfo), 0);
+
+        pre_auth_rsp->roam_info->pbFrames = vos_mem_malloc(rsp_len);
+        if (pre_auth_rsp->roam_info->pbFrames == NULL) {
+            limLog(mac, LOGE,
+                   FL("Failed to allocate memory for roam info frames"));
+            return;
+        }
+        vos_mem_set(pre_auth_rsp->roam_info->pbFrames, rsp_len, 0);
+
+
+        pre_auth_rsp->length += rsp_len + sizeof(tCsrRoamInfo);
+
+        session_entry_con_ap =
+               (tpPESession)mac->ft.ftPEContext.psavedsessionEntry;
+            pre_auth_rsp->smeSessionId = session_entry_con_ap->smeSessionId;
+
+        if(session_entry->beacon != NULL) {
+           pre_auth_rsp->roam_info->nBeaconLength = session_entry->bcnLen;
+           vos_mem_copy(pre_auth_rsp->roam_info->pbFrames,
+                        session_entry->beacon,
+                        session_entry->bcnLen);
+           limLog(mac, LOG1, FL("Beacon len %d"), session_entry->bcnLen);
+
+           vos_mem_free(session_entry->beacon);
+           session_entry->beacon = NULL;
+        }
+
+        if(session_entry->assocReq != NULL) {
+           pre_auth_rsp->roam_info->nAssocReqLength =
+                                      session_entry->assocReqLen;
+           vos_mem_copy(pre_auth_rsp->roam_info->pbFrames +
+                        session_entry->bcnLen,
+                        session_entry->assocReq,
+                        session_entry->assocReqLen);
+
+           vos_mem_free(session_entry->assocReq);
+           session_entry->assocReq = NULL;
+
+           limLog(mac, LOG1, FL("AssocReq len %d"), session_entry->assocReqLen);
+        }
+
+        if(session_entry->assocRsp != NULL) {
+           pre_auth_rsp->roam_info->nAssocRspLength =
+                                   session_entry->assocRspLen;
+           vos_mem_copy(pre_auth_rsp->roam_info->pbFrames +
+                        session_entry->bcnLen + session_entry->assocReqLen,
+                        session_entry->assocRsp,
+                        session_entry->assocRspLen);
+
+           vos_mem_free(session_entry->assocRsp);
+           session_entry->assocRsp = NULL;
+
+           limLog(mac, LOG1, FL("AssocRsp len %d"), session_entry->assocRspLen);
+        }
+
+        sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+                                   &session_entry->dph.dphHashTable);
+        if(NULL == sta_ds) {
+           limLog(mac, LOGE,
+                  FL("Unable to get the DPH Hash Entry for AID - %d"),
+                  DPH_STA_HASH_INDEX_PEER);
+           return;
+        }
+
+        pre_auth_rsp->roam_info->staId = sta_ds->staIndex;
+        pre_auth_rsp->roam_info->ucastSig = sta_ds->ucUcastSig;
+        pre_auth_rsp->roam_info->bcastSig = sta_ds->ucBcastSig;
+        pre_auth_rsp->roam_info->maxRateFlags =
+                         limGetMaxRateFlags(sta_ds, session_entry);
+    }
+
+    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_reassoc_fail_cleanup() -handles cleanup during reassoc failure
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function handles cleanup during reassoc failure
+ */
+void lim_reassoc_fail_cleanup(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data)
+{
+    tpPESession session_entry;
+
+    session_entry = (tpPESession)data;
+
+    if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+        limLog(mac, LOGE, FL("pFTPreAuthReq is NULL"));
+        return;
+    }
+
+    if (dphDeleteHashEntry(mac,
+               mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+               DPH_STA_HASH_INDEX_PEER,
+               &session_entry->dph.dphHashTable) != eSIR_SUCCESS) {
+        limLog(mac, LOGE, FL("error deleting hash entry"));
+    }
+
+    /* Delete session as session was created during preauth success */
+    peDeleteSession(mac, session_entry);
+
+    /* Add bss parameter cleanup happens as part of this processing*/
+    if ((status == eHAL_STATUS_MBB_DEL_BSS_FAIL) ||
+        (status == eHAL_STATUS_INVALID_PARAMETER) ||
+        (status == eHAL_STATUS_MBB_ADD_BSS_FAIL))
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                           SIR_MBB_DISCONNECTED);
+     else
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                             SIR_MBB_CONNECTED);
+}
+
+/*
+ * lim_perform_post_reassoc_mbb_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_post_reassoc_mbb_channel_change(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+    tpPESession session_entry_con_ap;
+    tANI_U8 session_id;
+
+    session_entry_con_ap = peFindSessionByBssid(mac,
+                         mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+                         &session_id);
+    if (session_entry_con_ap == NULL) {
+        limLog(mac, LOGE,
+               FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+               MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                             SIR_MBB_CONNECTED);
+        return;
+    }
+
+    peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0);
+    limResumeLink(mac, lim_reassoc_fail_cleanup,
+                                (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_reassoc_mbb_fail() -handles reassoc failure
+ * @mac: MAC context
+ * @session_entry: session entry
+ *
+ * This function handles reassoc failure
+ */
+void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac,
+     tpPESession session_entry)
+{
+    tpPESession session_entry_con_ap;
+    tANI_U8 session_id;
+
+    session_entry_con_ap = peFindSessionByBssid(mac,
+                         mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+                         &session_id);
+    if (session_entry_con_ap == NULL) {
+        limLog(mac, LOGE,
+               FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+               MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                             SIR_MBB_CONNECTED);
+        return;
+    }
+
+    limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"),
+           session_entry_con_ap->currentOperChannel,
+           mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);
+
+    /* Restore set link to post assoc for currently connected AP */
+    if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE,
+                        session_entry_con_ap->bssId,
+                        session_entry_con_ap->selfMacAddr,
+                        NULL, NULL) != eSIR_SUCCESS) {
+        limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                             SIR_MBB_CONNECTED);
+        return;
+    }
+
+    /* Change channel if required as channel might be changed during preauth */
+    if (session_entry_con_ap->currentOperChannel !=
+            mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+        limChangeChannelWithCallback(mac,
+                       session_entry_con_ap->currentOperChannel,
+           lim_perform_post_reassoc_mbb_channel_change, NULL, session_entry);
+    } else {
+       /*
+        * Link needs to be resumed as link was suspended
+        * for same channel during preauth.
+        */
+       peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0);
+       limResumeLink(mac, lim_reassoc_fail_cleanup,
+                     (tANI_U32 *)session_entry);
+    }
+}
+
+/*
+ * lim_preauth_fail_cleanup() -handles cleanup during preauth failure
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function handles cleanup during reassoc failure
+ */
+void lim_preauth_fail_cleanup(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data)
+{
+    tpPESession session_entry;
+
+    session_entry = (tpPESession)data;
+
+    lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                            SIR_MBB_CONNECTED);
+}
+
+/*
+ * lim_perform_preauth_mbb_fail_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_preauth_mbb_fail_channel_change(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+    peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+    limResumeLink(mac, lim_preauth_fail_cleanup,
+                                (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_preauth_mbb_fail() -handles preauth failure
+ * @mac: MAC context
+ * @session_entry: session entry
+ *
+ * This function handles reassoc failure
+ */
+void lim_handle_preauth_mbb_fail(tpAniSirGlobal mac,
+     tpPESession session_entry)
+{
+    limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"),
+           session_entry->currentOperChannel,
+           mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);
+
+    /* Restore set link to post assoc for currently connected AP */
+    if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE,
+                        session_entry->bssId,
+                        session_entry->selfMacAddr,
+                        NULL, NULL) != eSIR_SUCCESS) {
+        limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+
+        lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+                                             SIR_MBB_CONNECTED);
+        return;
+    }
+
+    /* Change channel if required as channel might be changed during preauth */
+    if (session_entry->currentOperChannel !=
+            mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+        limChangeChannelWithCallback(mac,
+                       session_entry->currentOperChannel,
+           lim_perform_preauth_mbb_fail_channel_change, NULL, session_entry);
+    } else {
+       /*
+        * Link needs to be resumed as link was suspended
+        * for same channel during preauth.
+        */
+       peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+       limResumeLink(mac, lim_preauth_fail_cleanup,
+                     (tANI_U32 *)session_entry);
+    }
+}
+
+
+/*
+ * lim_del_sta_mbb() -performs del sta
+ * @mac: MAC context
+ * @sta_ds_connected_ap: station entry of connected AP
+ * @resp_reqd: indicates whether response is required or not
+ * @session_entry_connected_ap: session entry of connected AP
+ *
+ * This function performs del sta
+ */
+tSirRetStatus lim_del_sta_mbb(tpAniSirGlobal mac,
+    tpDphHashNode sta_ds_connected_ap,
+    tANI_BOOLEAN resp_reqd,
+    tpPESession session_entry_connected_ap)
+{
+    tpDeleteStaParams del_sta_params;
+    tSirMsgQ msg;
+    tSirRetStatus ret_code;
+
+    del_sta_params = vos_mem_malloc(sizeof(*del_sta_params));
+    if (NULL == del_sta_params) {
+        limLog(mac, LOGE, FL("Unable to allocate memory during DEL_STA" ));
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+    vos_mem_zero(del_sta_params, sizeof(*del_sta_params));
+
+    del_sta_params->sessionId = session_entry_connected_ap->peSessionId;
+    del_sta_params->status  = eHAL_STATUS_SUCCESS;
+
+#ifdef FEATURE_WLAN_TDLS
+    if(((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) &&
+        (sta_ds_connected_ap->staType !=  STA_ENTRY_TDLS_PEER)) ||
+        (eLIM_BT_AMP_STA_ROLE ==
+                         GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)))
+#else
+    if((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) ||
+              (eLIM_BT_AMP_STA_ROLE ==
+                       GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)))
+#endif
+      del_sta_params->staIdx = session_entry_connected_ap->staId;
+    else
+      del_sta_params->staIdx = sta_ds_connected_ap->staIndex;
+
+    del_sta_params->assocId = sta_ds_connected_ap->assocId;
+    del_sta_params->respReqd = resp_reqd;
+
+    /* Change Mlm state of connected AP to Del sta rsp state */
+    session_entry_connected_ap->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+    MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+      session_entry_connected_ap->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+    msg.type = WDA_DELETE_STA_REQ;
+    msg.reserved = 0;
+    msg.bodyptr = del_sta_params;
+    msg.bodyval = 0;
+
+    limLog(mac, LOG1,
+           FL("sessionId %d staIdx: %d assocId: %d for "MAC_ADDRESS_STR),
+           del_sta_params->sessionId, del_sta_params->staIdx,
+           del_sta_params->assocId,
+           MAC_ADDR_ARRAY(sta_ds_connected_ap->staAddr));
+
+    MTRACE(macTraceMsgTx(mac, session_entry_connected_ap->peSessionId,
+                                                               msg.type));
+
+    ret_code = wdaPostCtrlMsg(mac, &msg);
+    if( eSIR_SUCCESS != ret_code) {
+        if(resp_reqd)
+           SET_LIM_PROCESS_DEFD_MESGS(mac, true);
+        limLog(mac, LOGE,
+               FL("Posting DELETE_STA_REQ failed, reason=%X"), ret_code);
+        vos_mem_free(del_sta_params);
+    }
+
+    return ret_code;
+}
+
+/*
+ * lim_del_bss_mbb() -performs del bss of connected AP
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @bss_idx:BSS index
+ * @session_entry: session entry
+ *
+ * This function performs del bss of connected AP
+ */
+tSirRetStatus lim_del_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+    tANI_U16 bss_idx,tpPESession session_entry)
+{
+    tpDeleteBssParams delbss_params = NULL;
+    tSirMsgQ msg;
+    tSirRetStatus ret_code = eSIR_SUCCESS;
+
+    delbss_params = vos_mem_malloc(sizeof(tDeleteBssParams));
+    if (NULL == delbss_params) {
+        limLog(mac, LOGE,
+               FL("Unable to allocate memory during del bss" ));
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+    vos_mem_set((tANI_U8 *) delbss_params, sizeof(tDeleteBssParams), 0);
+
+    delbss_params->sessionId = session_entry->peSessionId;
+
+    if (sta_ds != NULL) {
+        delbss_params->bssIdx = sta_ds->bssId;
+        sta_ds->valid = 0;
+        sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+    }
+    else
+        delbss_params->bssIdx = bss_idx;
+
+    session_entry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+    MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+          session_entry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE));
+
+    delbss_params->status= eHAL_STATUS_SUCCESS;
+    delbss_params->respReqd = 1;
+
+    limLog(mac, LOG1, FL("Sessionid %d bss idx: %x BSSID:" MAC_ADDRESS_STR),
+           delbss_params->sessionId, delbss_params->bssIdx,
+           MAC_ADDR_ARRAY(session_entry->bssId));
+
+    /* we need to defer the message until we get the response back from HAL. */
+    SET_LIM_PROCESS_DEFD_MESGS(mac, false);
+
+    msg.type = WDA_DELETE_BSS_REQ;
+    msg.reserved = 0;
+    msg.bodyptr = delbss_params;
+    msg.bodyval = 0;
+
+    MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+    if(eSIR_SUCCESS != (ret_code = wdaPostCtrlMsg(mac, &msg)))
+    {
+        SET_LIM_PROCESS_DEFD_MESGS(mac, true);
+        limLog(mac, LOGE,
+               FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), ret_code);
+        vos_mem_free(delbss_params);
+    }
+
+    return ret_code;
+}
+
+/*
+ * lim_add_bss_mbb() -performs add bss of new roamable AP
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @bss_idx:BSS index
+ * @session_entry: session entry
+ *
+ * This function performs add bss of new roamable AP
+ */
+void lim_add_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+    tpPESession session_entry)
+{
+    tSirMsgQ msg;
+    tSirRetStatus ret_code;
+
+    /* we need to defer the message until we get the response back from HAL. */
+    SET_LIM_PROCESS_DEFD_MESGS(mac, false);
+
+    msg.type = SIR_HAL_ADD_BSS_REQ;
+    msg.reserved = 0;
+    msg.bodyptr = mac->ft.ftPEContext.pAddBssReq;
+    msg.bodyval = 0;
+
+    limLog(mac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ"));
+
+    session_entry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+
+    MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+          session_entry->peSessionId, eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE));
+
+    MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+    ret_code = wdaPostCtrlMsg(mac, &msg);
+    if( eSIR_SUCCESS != ret_code) {
+        vos_mem_free(mac->ft.ftPEContext.pAddBssReq);
+        limLog(mac, LOGE,
+               FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), ret_code);
+    }
+    /* Dont need this anymore */
+    mac->ft.ftPEContext.pAddBssReq = NULL;
+}
+
+tSirRetStatus lim_add_sta_mbb(tpAniSirGlobal mac, tANI_U16 assoc_id,
+    tpPESession session_entry)
+{
+    tpAddStaParams add_sta_params = NULL;
+    tSirMsgQ msg;
+    tSirRetStatus retCode = eSIR_SUCCESS;
+
+    add_sta_params = mac->ft.ftPEContext.pAddStaReq;
+    add_sta_params->assocId = assoc_id;
+
+    msg.type = SIR_HAL_ADD_STA_REQ;
+    msg.reserved = 0;
+    msg.bodyptr = add_sta_params;
+    msg.bodyval = 0;
+
+    limLog(mac, LOG1,
+           FL("Sending SIR_HAL_ADD_STA_REQ. aid %d)"),
+           add_sta_params->assocId);
+
+    session_entry->limPrevMlmState = session_entry->limMlmState;
+    session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+
+    MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+          session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
+
+    MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+    if(eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( mac, &msg))) {
+        limLog(mac, LOGE,
+               FL("Posting ADD_STA_REQ to HAL failed, reason=%X"), retCode);
+        vos_mem_free(add_sta_params);
+    }
+
+    mac->ft.ftPEContext.pAddStaReq = NULL;
+    return retCode;
+}
+
+/*
+ * lim_handle_reassoc_mbb_success() -handles reassoc success
+ * @mac: MAC context
+ * @session_entry: session entry
+ * @assoc_rsp: pointer to assoc response
+ * @sta_ds : station entry
+ *
+ * This function handles reassoc success
+ */
+void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac,
+     tpPESession session_entry, tpSirAssocRsp  assoc_rsp, tpDphHashNode sta_ds)
+{
+    tpPESession session_entry_con_ap;
+    tANI_U8 session_id_connected_ap;
+    tpDphHashNode sta_ds_connected_ap;
+    tANI_U16 aid;
+    tSirRetStatus ret_code;
+
+    limUpdateAssocStaDatas(mac, sta_ds, assoc_rsp, session_entry);
+
+    /* Store assigned AID for TIM processing */
+    session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+
+    /* De register STA for currently connected AP */
+    mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+                            NULL, NULL, SIR_ROAMING_DEREGISTER_STA);
+
+    mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+                            NULL, NULL, SIR_STOP_ROAM_OFFLOAD_SCAN);
+
+    if((session_entry_con_ap = peFindSessionByBssid(mac,
+          mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+          &session_id_connected_ap))== NULL) {
+        limLog(mac, LOGE,
+               FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+               MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+        goto end;
+    }
+
+    session_entry->smeSessionId = session_entry_con_ap->smeSessionId;
+
+    sta_ds_connected_ap = dphLookupHashEntry(mac,
+                               mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+                               &aid,
+                               &session_entry_con_ap->dph.dphHashTable);
+    if (sta_ds_connected_ap == NULL) {
+        limLog(mac, LOGE,
+               FL("sta_ds NULL for given BSSID" MAC_ADDRESS_STR),
+               MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+        goto end;
+    }
+
+    /*
+     * Change Mlm state of new AP to Del sta rsp state so that
+     * duplicate reassoc response will be dropped.
+     */
+    session_entry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+    MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+              session_entry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+    /* Delete sta for currently connected AP */
+    ret_code = lim_del_sta_mbb(mac, sta_ds_connected_ap,
+                    false, session_entry_con_ap);
+    if (ret_code == eSIR_SUCCESS)
+        return;
+
+end:
+    /* Connected AP lim cleanup.*/
+    lim_cleanup_connected_ap(mac, sta_ds_connected_ap, session_entry_con_ap);
+    /*
+     * eHAL_STATUS_INVALID_PARAMETER is used
+     * so that full cleanup is triggered.
+     */
+    lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+                                (tANI_U32 *)session_entry);
+}
+
+
+/*
+ * 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, ft_session_entry;
+    tpDphHashNode sta_ds;
+    tAddBssParams *add_bss_params;
+    tSirSmeJoinReq *reassoc_req;
+    tLimMlmReassocReq *mlm_reassoc_req;
+    tANI_U16 caps;
+    tANI_U16 nSize;
+    tpSirSmeJoinReq pReassocReq = NULL;
+
+    if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+        limLog(mac, LOG1, "Pre-Auth request is NULL!");
+        goto end;
+    }
+
+    session_entry = (tpPESession)data;
+
+    /* Post the FT Pre Auth Response to SME in case of failure*/
+    if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_FAILURE)
+        goto end;
+
+    /* Flow for preauth success */
+    limFTSetupAuthSession(mac, session_entry);
+
+    /*
+     * Prepare reassoc request. Memory allocated for tSirSmeJoinReq
+     *reassoc_req in csr_fill_reassoc_req. Free that memory here.
+     */
+    mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+                            mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription,
+                            &reassoc_req, SIR_PREPARE_REASSOC_REQ);
+    if (reassoc_req  == NULL) {
+        limLog(mac, LOGE,
+               FL("reassoc req is NULL"));
+        goto end;
+    }
+
+    nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) reassoc_req);
+    pReassocReq = vos_mem_malloc(nSize);
+    if ( NULL == pReassocReq )
+    {
+        limLog(mac, LOGE,
+               FL("call to AllocateMemory failed for pReassocReq"));
+        goto end;
+    }
+    vos_mem_set((void *) pReassocReq, nSize, 0);
+    if ((limJoinReqSerDes(mac, (tpSirSmeJoinReq) pReassocReq,
+                          (tANI_U8 *) reassoc_req) == eSIR_FAILURE) ||
+        (!limIsSmeJoinReqValid(mac,
+                               (tpSirSmeJoinReq) pReassocReq)))
+    {
+        limLog(mac, LOGE,
+               FL("received SME_REASSOC_REQ with invalid data"));
+        goto end;
+    }
+
+    ft_session_entry = mac->ft.ftPEContext.pftSessionEntry;
+
+    ft_session_entry->pLimReAssocReq = pReassocReq;
+    vos_mem_free(reassoc_req);
+
+    add_bss_params = mac->ft.ftPEContext.pAddBssReq;
+
+    mlm_reassoc_req = vos_mem_malloc(sizeof(tLimMlmReassocReq));
+    if (NULL == mlm_reassoc_req) {
+        limLog(mac, LOGE,
+               FL("call to AllocateMemory failed for mlmReassocReq"));
+        goto end;
+    }
+
+    vos_mem_copy(mlm_reassoc_req->peerMacAddr,
+                 ft_session_entry->limReAssocbssId,
+                 sizeof(tSirMacAddr));
+    mlm_reassoc_req->reassocFailureTimeout = PREAUTH_REASSOC_TIMEOUT;
+
+    if (cfgGetCapabilityInfo(mac, &caps, ft_session_entry) != eSIR_SUCCESS) {
+        limLog(mac, LOGE, FL("could not retrieve Capabilities value"));
+        vos_mem_free(mlm_reassoc_req);
+        goto end;
+    }
+
+    lim_update_caps_info_for_bss(mac, &caps,
+                        reassoc_req->bssDescription.capabilityInfo);
+
+    limLog(mac, LOG1, FL("Capabilities info Reassoc: 0x%X"), caps);
+
+    mlm_reassoc_req->capabilityInfo = caps;
+    mlm_reassoc_req->sessionId = ft_session_entry->peSessionId;
+    mlm_reassoc_req->listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+    if ((sta_ds = dphAddHashEntry(mac, add_bss_params->bssId,
+                  DPH_STA_HASH_INDEX_PEER,
+                  &ft_session_entry->dph.dphHashTable)) == NULL) {
+        limLog(mac, LOGE, FL("could not add hash entry at DPH"));
+        limPrintMacAddr(mac, add_bss_params->bssId, LOGE);
+        vos_mem_free(mlm_reassoc_req);
+        goto end;
+    }
+
+    /* Start timer here to handle reassoc timeout */
+    mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId =
+                                                ft_session_entry->peSessionId;
+
+    MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE,
+             session_entry->peSessionId, eLIM_REASSOC_MBB_RSP_TIMER));
+
+    if(TX_SUCCESS !=
+          tx_timer_activate(&mac->lim.limTimers.glim_reassoc_mbb_rsp_timer)) {
+       limLog(mac, LOGE, FL("Reassoc MBB Rsp Timer Start Failed"));
+
+       if (ft_session_entry->pLimReAssocReq) {
+           vos_mem_free(ft_session_entry->pLimReAssocReq);
+           ft_session_entry->pLimReAssocReq = NULL;
+       }
+
+       vos_mem_free(mlm_reassoc_req);
+       goto end;
+    }
+
+    limLog(mac, LOG1, FL("enabling caching"));
+    WLANTL_EnablePreAssocCaching();
+
+    /* To do: Add changes for reassoc fail timer */
+    limSendReassocReqWithFTIEsMgmtFrame(mac,
+                     mlm_reassoc_req, ft_session_entry);
+
+    ft_session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+
+    limLog(mac, LOG1,  FL("Set the mlm state to %d session=%d"),
+           ft_session_entry->limMlmState, ft_session_entry->peSessionId);
+    return;
+
+end:
+    lim_handle_reassoc_mbb_fail(mac, ft_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);
+
+        /* Prepare session for roamable AP */
+        lim_process_preauth_mbb_result(mac,
+               mac->ft.ftPEContext.ftPreAuthStatus, (tANI_U32 *)session_entry);
+        return;
+    }else {
+        lim_handle_preauth_mbb_fail(mac, session_entry);
+        return;
+    }
+
+out:
+    /* This sequence needs to be executed in case of failure*/
+    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_process_reassoc_mbb_rsp_timeout() -Process reassoc response timeout
+ * @mac: MAC context
+ *
+ * This function is called if preauth response is not received from the
+ * AP within timeout
+ */
+void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac)
+{
+    tpPESession session_entry, ft_session_entry;
+    tANI_U8 session_id;
+
+    if((ft_session_entry = peFindSessionBySessionId(mac,
+        mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId))== NULL) {
+        limLog(mac, LOGE,
+               FL("ft session does not exist for given session id %d"),
+               mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId);
+        return;
+    }
+
+    limLog(mac, LOG1, FL("Reassoc timeout happened in state %d"),
+                         ft_session_entry->limMlmState);
+
+    if((session_entry = peFindSessionByBssid(mac,
+          mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id))== NULL) {
+        limLog(mac, LOGE,
+               FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+               MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+        return;
+    }
+
+    lim_handle_reassoc_mbb_fail(mac, ft_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);
+
+    MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE,
+             session_entry->peSessionId, eLIM_PREAUTH_MBB_RSP_TIMER));
+
+    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, SIR_MBB_CONNECTED);
+        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,
+                                                  SIR_MBB_CONNECTED);
+        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,
+                                                SIR_MBB_CONNECTED);
+        return;
+    }
+
+    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,
+                                                   SIR_MBB_CONNECTED);
+        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);
+}
+
+
+/**
+ * lim_process_sta_mlm_del_sta_rsp_mbb() -Process del sta response
+ * @mac: MAC context
+ * @lim_msg: lim message
+ * @session_entry: session entry
+ *
+ * This function process del sta response
+ */
+void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac,
+     tpSirMsgQ lim_msg, tpPESession session_entry)
+{
+    tpDeleteStaParams del_sta_params = (tpDeleteStaParams)lim_msg->bodyptr;
+    tpDphHashNode sta_ds = NULL;
+    tANI_U8 session_id;
+    tpPESession ft_session_entry;
+
+    if(NULL == del_sta_params) {
+       limLog(mac, LOGE, FL("Encountered NULL Pointer"));
+       goto end;
+    }
+
+    limLog(mac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"),
+           del_sta_params->status, del_sta_params->assocId);
+
+    if (eHAL_STATUS_SUCCESS != del_sta_params->status) {
+        limLog(mac, LOGE, FL("Del STA failed! Status:%d, still proceeding"
+               "with Del BSS"), del_sta_params->status);
+    }
+
+    sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+                             &session_entry->dph.dphHashTable);
+
+    if (sta_ds == NULL) {
+        limLog( mac, LOGE, FL("DPH Entry for STA %X missing"),
+                del_sta_params->assocId);
+        goto end;
+    }
+
+    if (eLIM_MLM_WT_DEL_STA_RSP_STATE != session_entry->limMlmState) {
+        limLog(mac, LOGE,
+               FL( "Received unexpected WDA_DELETE_STA_RSP in state %s" ),
+               limMlmStateStr(session_entry->limMlmState));
+        goto end;
+    }
+
+    limLog( mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId);
+    limPrintMacAddr(mac, sta_ds->staAddr, LOG1);
+
+    /*
+     * we must complete all cleanup related to del sta
+     * before calling del bss.
+     */
+    if (NULL != lim_msg->bodyptr) {
+        vos_mem_free(del_sta_params);
+        lim_msg->bodyptr = NULL;
+    }
+
+    /* Proceed to do del bss even if del sta resulted in failure */
+    lim_del_bss_mbb(mac, sta_ds, 0, session_entry);
+    return;
+
+end:
+    if(NULL != lim_msg->bodyptr) {
+        vos_mem_free(del_sta_params);
+        lim_msg->bodyptr = NULL;
+    }
+
+    /* Connected AP lim cleanup.*/
+    lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+    ft_session_entry = peFindSessionByBssid(mac,
+                         mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+                         &session_id);
+    if (ft_session_entry == NULL) {
+        limLog(mac, LOGE,
+               FL("Unable to find session for the following bssid"));
+        limPrintMacAddr(mac,
+                     mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+        return;
+    }
+
+    /*
+     * eHAL_STATUS_INVALID_PARAMETER is used
+     * so that full cleanup is triggered.
+     */
+    lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+                                (tANI_U32 *)ft_session_entry);
+}
+
+/**
+ * lim_cleanup_rx_path_mbb() -cleans up tspec related info
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @session_entry: session entry of connected AP
+ *
+ * This function cleans up tspec related info
+ */
+void lim_cleanup_rx_path_mbb(tpAniSirGlobal mac,
+    tpDphHashNode sta_ds,tpPESession session_entry)
+{
+    limLog(mac, LOG1, FL("AID %d limSmeState %d, mlmState %d"),
+           sta_ds->assocId, session_entry->limSmeState,
+           sta_ds->mlmStaContext.mlmState);
+
+    session_entry->isCiscoVendorAP = FALSE;
+
+    if (mac->lim.gLimAddtsSent)
+        tx_timer_deactivate(&mac->lim.limTimers.gLimAddtsRspTimer);
+
+    /* delete all tspecs associated with this sta. */
+    limAdmitControlDeleteSta(mac, sta_ds->assocId);
+}
+
+
+/**
+ * lim_cleanup_connected_ap() -cleans up connected AP lim info
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @session_entry: session entry of connected AP
+ *
+ * This function cleans up connected AP lim info
+ */
+void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+     tpPESession session_entry)
+{
+    lim_cleanup_rx_path_mbb(mac, sta_ds, session_entry);
+    limDeleteDphHashEntry(mac, sta_ds->staAddr,
+                          sta_ds->assocId, session_entry);
+
+    /**
+     * Make STA hash entry invalid at eCPU so that DPH
+     * does not process any more data packets and
+     * releases those BDs
+     */
+    sta_ds->valid = 0;
+
+    peDeleteSession(mac, session_entry);
+}
+
+/**
+ * lim_process_sta_mlm_del_bss_rsp_mbb() -Process del bss response of
+ * connected AP
+ * @mac: MAC context
+ * @lim_msg: lim message
+ * @session_entry: session entry of connected AP
+ *
+ * This function process del sta response
+ */
+void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac,
+     tpSirMsgQ lim_msg, tpPESession session_entry)
+{
+    tpDeleteBssParams delbss_params = (tpDeleteBssParams)lim_msg->bodyptr;
+    tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+                                            &session_entry->dph.dphHashTable);
+    tpPESession ft_session_entry;
+    tANI_U8 session_id;
+
+    if (NULL == delbss_params) {
+        limLog(mac, LOGE, FL( "Invalid body pointer in message"));
+        goto end;
+    }
+
+    ft_session_entry = peFindSessionByBssid(mac,
+                         mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+                         &session_id);
+    if (ft_session_entry == NULL) {
+        limLog(mac, LOGE,
+               FL("Unable to find session for the following bssid"));
+        limPrintMacAddr(mac,
+                     mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+        goto end;
+    }
+
+    if(eHAL_STATUS_SUCCESS == delbss_params->status) {
+       limLog(mac, LOG1,
+              FL( "STA received the DEL_BSS_RSP for BSSID: %X."),
+              delbss_params->bssIdx);
+
+       if(sta_ds == NULL) {
+          limLog(mac, LOGE, FL("DPH Entry for STA missing"));
+          goto end;
+       }
+       if(eLIM_MLM_WT_DEL_BSS_RSP_STATE != session_entry->limMlmState) {
+          limLog(mac, LOGE,
+                 FL("Received unexpected WDA_DEL_BSS_RSP in state %d"),
+                    session_entry->limMlmState);
+          goto end;
+       }
+       limLog(mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId );
+       limPrintMacAddr(mac, sta_ds->staAddr, LOG1);
+
+       lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+       lim_add_bss_mbb(mac, sta_ds, ft_session_entry);
+
+       if(NULL != lim_msg->bodyptr) {
+          vos_mem_free(delbss_params);
+          lim_msg->bodyptr = NULL;
+       }
+       return;
+    } else {
+       /*
+        * If del bss response is failure, cleanup sessions of both currently
+        * connected AP and roamable AP as add bss can not be send
+        * without successful delbss.
+        */
+       limLog(mac, LOGE,
+              FL("DEL BSS failed! Status:%d"), delbss_params->status);
+
+       if(NULL != lim_msg->bodyptr) {
+          vos_mem_free(delbss_params);
+          lim_msg->bodyptr = NULL;
+       }
+
+       /* Connected AP lim cleanup.*/
+       lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+       /* Newly created session cleanup */
+       lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_DEL_BSS_FAIL,
+                                (tANI_U32 *)ft_session_entry);
+       return;
+    }
+
+end:
+    if(NULL != lim_msg->bodyptr) {
+       vos_mem_free(delbss_params);
+       lim_msg->bodyptr = NULL;
+    }
+
+    lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+    ft_session_entry = peFindSessionByBssid(mac,
+                         mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+                         &session_id);
+    if (ft_session_entry == NULL) {
+        limLog(mac, LOGE,
+               FL("Unable to find session for the following bssid"));
+        limPrintMacAddr(mac,
+                     mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+        return;
+    }
+
+    /*
+     * eHAL_STATUS_INVALID_PARAMETER is used
+     * so that full cleanup is triggered.
+     */
+    lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+                                (tANI_U32 *)ft_session_entry);
+}
+
+
+void lim_fill_add_sta_params_mbb(tpAniSirGlobal mac,
+     tpPESession session_entry, tpAddStaParams add_sta_params)
+{
+    tANI_U32 listen_interval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+    tANI_U32 self_sta_dot11_mode = 0;
+
+    vos_mem_copy(add_sta_params->staMac, session_entry->selfMacAddr,
+                 sizeof(tSirMacAddr));
+    vos_mem_copy(add_sta_params->bssId, session_entry->bssId,
+                 sizeof(tSirMacAddr));
+
+    add_sta_params->staType = STA_ENTRY_SELF;
+    add_sta_params->status = eHAL_STATUS_SUCCESS;
+    add_sta_params->respReqd = 1;
+
+    add_sta_params->sessionId = session_entry->peSessionId;
+    add_sta_params->staIdx = HAL_STA_INVALID_IDX;
+    add_sta_params->updateSta = FALSE;
+
+    add_sta_params->shortPreambleSupported =
+                 session_entry->beaconParams.fShortPreamble;
+
+#ifdef WLAN_FEATURE_11AC
+    limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL,
+                           false,session_entry, NULL);
+#else
+    limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL,
+                           false,session_entry);
+#endif
+
+    if(session_entry->htCapability) {
+        add_sta_params->htCapable = session_entry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+        add_sta_params->vhtCapable = session_entry->vhtCapability;
+        add_sta_params->vhtTxChannelWidthSet = session_entry->vhtTxChannelWidthSet;
+#endif
+
+#ifdef DISABLE_GF_FOR_INTEROP
+        if((session_entry->pLimJoinReq != NULL) &&
+               (!session_entry->pLimJoinReq->bssDescription.aniIndicator)) {
+            limLog(mac, LOGE,
+                   FL("Turning off Greenfield, when adding self entry"));
+            add_sta_params->greenFieldCapable =
+                          WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+        }
+        else
+#endif
+        add_sta_params->greenFieldCapable =
+                       limGetHTCapability( mac, eHT_GREENFIELD, session_entry);
+
+        if (session_entry->limRFBand == SIR_BAND_2_4_GHZ)
+            add_sta_params->txChannelWidthSet =
+                     mac->roam.configParam.channelBondingMode24GHz;
+        else
+            add_sta_params->txChannelWidthSet =
+                     mac->roam.configParam.channelBondingMode5GHz;
+
+        add_sta_params->mimoPS =
+              limGetHTCapability(mac, eHT_MIMO_POWER_SAVE, session_entry);
+        add_sta_params->rifsMode =
+              limGetHTCapability(mac, eHT_RIFS_MODE, session_entry);
+        add_sta_params->lsigTxopProtection =
+              limGetHTCapability(mac, eHT_LSIG_TXOP_PROTECTION, session_entry);
+        add_sta_params->delBASupport =
+              limGetHTCapability(mac, eHT_DELAYED_BA, session_entry);
+        add_sta_params->maxAmpduDensity =
+              limGetHTCapability(mac, eHT_MPDU_DENSITY, session_entry);
+        add_sta_params->maxAmpduSize =
+              limGetHTCapability(mac, eHT_MAX_RX_AMPDU_FACTOR, session_entry);
+        add_sta_params->maxAmsduSize =
+              limGetHTCapability(mac, eHT_MAX_AMSDU_LENGTH, session_entry);
+        add_sta_params->fDsssCckMode40Mhz =
+              limGetHTCapability(mac, eHT_DSSS_CCK_MODE_40MHZ, session_entry);
+        add_sta_params->fShortGI20Mhz =
+              limGetHTCapability(mac, eHT_SHORT_GI_20MHZ, session_entry);
+        add_sta_params->fShortGI40Mhz =
+              limGetHTCapability(mac, eHT_SHORT_GI_40MHZ, session_entry);
+    }
+
+    if (wlan_cfgGetInt(mac, WNI_CFG_LISTEN_INTERVAL,
+                         &listen_interval) != eSIR_SUCCESS)
+        limLog(mac, LOGE, FL("Couldn't get LISTEN_INTERVAL"));
+
+    add_sta_params->listenInterval = (tANI_U16)listen_interval;
+
+    wlan_cfgGetInt(mac, WNI_CFG_DOT11_MODE, &self_sta_dot11_mode);
+    add_sta_params->supportedRates.opRateMode =
+                       limGetStaRateMode((tANI_U8)self_sta_dot11_mode);
+
+    mac->ft.ftPEContext.pAddStaReq = add_sta_params;
+
+
+}
+
+void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac,
+    tpSirMsgQ limMsgQ,tpPESession session_entry)
+{
+    tpAddBssParams add_bss_params = (tpAddBssParams)limMsgQ->bodyptr;
+    tpAddStaParams add_sta_params = NULL;
+    tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+                                        &session_entry->dph.dphHashTable);
+
+    if(add_bss_params == 0)
+        goto end;
+
+    limLog(mac, LOG1, FL("Add BSS RSP received. Status:%d"),
+                         add_bss_params->status);
+
+    if(eHAL_STATUS_SUCCESS == add_bss_params->status) {
+
+       if(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE != session_entry->limMlmState) {
+          limLog(mac, LOGE,
+                 FL("Received unexpected ADD BSS in state %d"),
+                    session_entry->limMlmState);
+          goto end;
+       }
+
+       session_entry->bssIdx = add_bss_params->bssIdx;
+
+       sta_ds->bssId = add_bss_params->bssIdx;
+       sta_ds->staIndex = add_bss_params->staContext.staIdx;
+       sta_ds->ucUcastSig = add_bss_params->staContext.ucUcastSig;
+       sta_ds->ucBcastSig = add_bss_params->staContext.ucBcastSig;
+
+       rrmCacheMgmtTxPower(mac, add_bss_params->txMgmtPower, session_entry);
+
+       /* Allocate memory for add sta params */
+       add_sta_params = vos_mem_malloc(sizeof( tAddStaParams ));
+       if (NULL == add_sta_params) {
+           limLog(mac, LOGE,
+                  FL("Unable to allocate memory during ADD_STA"));
+           goto end;
+       }
+       vos_mem_set(add_sta_params, sizeof(tAddStaParams), 0);
+
+       /* Prepare add sta params */
+       lim_fill_add_sta_params_mbb(mac, session_entry, add_sta_params);
+
+       if(0 != limMsgQ->bodyptr) {
+          vos_mem_free(add_bss_params);
+          add_bss_params = NULL;
+          limMsgQ->bodyptr = NULL;
+       }
+
+       lim_add_sta_mbb(mac, session_entry->limAID, session_entry);
+
+    } else {
+       /*
+        * If add bss response is failure, cleanup session of roamable AP
+        * as cleanup of connected bss happened during del bss
+        */
+       limLog(mac, LOGE,
+              FL("ADD BSS failed! Status:%d"), add_bss_params->status);
+
+       /* Newly created session cleanup */
+       lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL,
+                                (tANI_U32 *)session_entry);
+    }
+
+end:
+    if(0 != limMsgQ->bodyptr) {
+        vos_mem_free(add_bss_params);
+        add_bss_params = NULL;
+        limMsgQ->bodyptr = NULL;
+    }
+}
+
+/*
+ * lim_perform_post_add_sta_rsp() -invokes resume callback to handle add sta response
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_post_add_sta_rsp(tpAniSirGlobal mac,
+     eHalStatus status, tANI_U32 *data)
+{
+    tpDphHashNode sta_ds;
+    /* session entry for newly roamed ap */
+    tpPESession session_entry;
+
+    session_entry = (tpPESession)data;
+
+    limLog(mac, LOG1, FL("forwarding cached packets"));
+    WLANTL_PreAssocForward(true);
+
+    sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+                              &session_entry->dph.dphHashTable);
+    if(NULL != sta_ds)
+       sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+    else {
+       limLog(mac, LOGE,
+              FL("Unable to get the DPH Hash Entry for AID - %d"),
+              DPH_STA_HASH_INDEX_PEER);
+       return;
+    }
+
+    session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+    MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+          session_entry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+#ifdef FEATURE_WLAN_TDLS
+           /* initialize TDLS peer related data */
+           limInitTdlsData(mac, session_entry);
+#endif
+
+    if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE, session_entry->bssId,
+               session_entry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) {
+        limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+        return;
+    }
+
+    session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
+
+    lim_post_pre_auth_reassoc_rsp(mac, eSIR_SUCCESS, session_entry,
+                                         SIR_MBB_CONNECTED);
+
+    /* Freeup the cached preauth request */
+    if (mac->ft.ftPEContext.pFTPreAuthReq) {
+        limLog(mac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+                             mac->ft.ftPEContext.pFTPreAuthReq);
+        if (mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) {
+            vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription);
+            mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL;
+        }
+        vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq);
+        mac->ft.ftPEContext.pFTPreAuthReq = NULL;
+    }
+}
+
+void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac,
+    tpSirMsgQ limMsgQ,tpPESession session_entry)
+{
+    tpAddStaParams add_sta_params = (tpAddStaParams)limMsgQ->bodyptr;
+
+    if(NULL == add_sta_params) {
+        limLog(mac, LOGE, FL("Encountered NULL Pointer"));
+        return;
+    }
+
+    limLog(mac, LOG1, FL("Add STA RSP received. Status:%d"),
+                         add_sta_params->status);
+
+    if (eHAL_STATUS_SUCCESS == add_sta_params->status) {
+        if ( eLIM_MLM_WT_ADD_STA_RSP_STATE != session_entry->limMlmState) {
+            limLog(mac, LOGE,
+                   FL("Received unexpected ADD_STA_RSP in state %d"),
+                   session_entry->limMlmState);
+            goto end;
+        }
+
+        /*
+         * Storing the self StaIndex(Generated by HAL) in session context,
+         * instead of storing it in DPH Hash entry for Self STA.
+         * DPH entry for the self STA stores the sta index for the BSS entry
+         * to which the STA is associated.
+         */
+        session_entry->staId = add_sta_params->staIdx;
+
+        limLog(mac, LOG1, FL("resuming to oper ch %d"),
+               session_entry->currentOperChannel);
+
+        peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+        limResumeLink(mac, lim_perform_post_add_sta_rsp, (tANI_U32 *)session_entry);
+    } else {
+       limLog(mac, LOGE, FL( "ADD_STA failed!"));
+
+        /* Newly created session cleanup */
+        lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL,
+                                (tANI_U32 *)session_entry);
+
+    }
+end:
+    if( 0 != limMsgQ->bodyptr )
+    {
+      vos_mem_free(add_sta_params);
+      limMsgQ->bodyptr = NULL;
+    }
+}
+
+eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac,
+            tpPESession session_entry)
+{
+    if (session_entry == NULL)
+        return eANI_BOOLEAN_FALSE;
+
+    if ((eLIM_STA_ROLE == session_entry->limSystemRole) &&
+                        mac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+        limLog(mac, LOG1, FL("MBB Reassoc in progress"));
+        return eANI_BOOLEAN_TRUE;
+    }
+
+    return eANI_BOOLEAN_FALSE;
+}
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index e92ff99..7e88126 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1199,6 +1199,11 @@
     v_U32_t PERtimerThreshold;
     v_U32_t PERroamTriggerPercent;
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
 #endif
 
     tANI_BOOLEAN ignorePeerErpInfo;
@@ -1766,6 +1771,5 @@
 ---------------------------------------------------------------------------*/
 eCsrBand csrGetCurrentBand (tHalHandle hHal);
 
-
 #endif
 
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index a780af6..09a507b 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -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.
  *
@@ -206,7 +206,7 @@
     eCsrLostLink1Abort,
     eCsrLostLink2Abort,
     eCsrLostLink3Abort,
-
+    ecsr_mbb_perform_preauth_reassoc,
 }eCsrRoamReason;
 
 typedef enum
@@ -636,6 +636,10 @@
 #endif
 #endif
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
 #ifdef FEATURE_WLAN_ESE
     tANI_U8   isEseIniFeatureEnabled;
 #endif
@@ -1494,3 +1498,18 @@
 eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
 eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
 #endif /* WLAN_FEATURE_RMC */
+
+eHalStatus csrRoamStopNetwork(tpAniSirGlobal pMac, tANI_U32 sessionId,
+    tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc,
+    tDot11fBeaconIEs *pIes);
+
+eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac,
+    tANI_U32 sessionId, eCsrAuthType authType,
+    tSirBssDescription *pSirBssDesc,
+    tDot11fBeaconIEs *pIes);
+
+void csrRoamSubstateChange(tpAniSirGlobal pMac,
+    eCsrRoamSubState NewSubstate, tANI_U32 sessionId);
+
+eHalStatus csrRoamFreeConnectedInfo(tpAniSirGlobal pMac,
+   tCsrRoamConnectedInfo *pConnectedInfo);
diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h
index 5df4eee..8bd7102 100644
--- a/CORE/SME/inc/csrNeighborRoam.h
+++ b/CORE/SME/inc/csrNeighborRoam.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -41,6 +41,12 @@
 #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 #include "sme_Api.h"
 
+/* 15 seconds, for WPA, WPA2, CCKM */
+#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD     (15 * PAL_TIMER_TO_SEC_UNIT)
+/* 120 seconds, for WPS */
+#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT)
+
+
 /* Enumeration of various states in neighbor roam algorithm */
 typedef enum
 {
@@ -55,6 +61,10 @@
     eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING,
     eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE,
 #endif /* WLAN_FEATURE_VOWIFI_11R */    
+#ifdef WLAN_FEATURE_LFR_MBB
+    eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC,
+#endif
+
     eNEIGHBOR_STATE_MAX
 } eCsrNeighborRoamState;
 
@@ -206,6 +216,11 @@
     vos_timer_t                 forcedInitialRoamTo5GHTimer;
     tANI_U8                     isForcedInitialRoamTo5GH;
     tANI_U8                     lastSentCmd;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+     bool is_pre_auth_reassoc_mbb_timer_started;
+#endif
+
 } tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo;
 
 
@@ -251,6 +266,15 @@
                                             tANI_U8  *pOutputChannelList,
                                             tANI_U8  outputNumOfChannels,
                                             tANI_U8  *pMergedOutputNumOfChannels);
+tANI_BOOLEAN
+csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
+                 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+eHalStatus
+csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac,
+                                                          tSirMacAddr bssId);
+void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac,
+                              tpCsrNeighborRoamBSSInfo neighborRoamBSSNode);
+
 
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
 #define ROAM_SCAN_OFFLOAD_START                     1
@@ -282,6 +306,10 @@
 eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac);
 eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status);
 eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 OffloadCmdStopReason);
+eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac,
+           tANI_U32 interval);
+void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid);
+
 #endif
 
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
diff --git a/CORE/SME/inc/csr_roam_mbb.h b/CORE/SME/inc/csr_roam_mbb.h
new file mode 100644
index 0000000..aa0bcbc
--- /dev/null
+++ b/CORE/SME/inc/csr_roam_mbb.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac);
+
+eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal,
+                     tANI_U32 session_id, tpSirBssDescription bss_description);
+
+void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal,
+                          tpSirFTPreAuthRsp pre_auth_rsp);
+
+void csr_preauth_reassoc_mbb_timer_callback(void *context);
+
+void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac);
+
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index ca101f7..79f27af 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -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.
  *
@@ -189,7 +189,10 @@
    void (*pOemDataIndCb) (void *, const tANI_U16, void *, tANI_U32);
    void *pOemDataCallbackContext;
 #endif /* FEATURE_OEM_DATA_SUPPORT */
-
+#ifdef WLAN_FEATURE_LFR_MBB
+   void (*roaming_mbb_callback)(void* mac, tANI_U32 session_id,
+          void* bss_description, void *reassoc_req, tANI_U32 csr_roam_op_code);
+#endif
 } tSmeStruct, *tpSmeStruct;
 
 
diff --git a/CORE/SME/inc/sme_FTApi.h b/CORE/SME/inc/sme_FTApi.h
index 4eed9f5..0a57aa5 100644
--- a/CORE/SME/inc/sme_FTApi.h
+++ b/CORE/SME/inc/sme_FTApi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -72,6 +72,12 @@
     tCsrRoamSetKey    *pCsrFTKeyInfo;
 
     v_BOOL_t          addMDIE;
+
+    tANI_BOOLEAN is_preauth_lfr_mbb;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    vos_timer_t       pre_auth_reassoc_mbb_timer;
+#endif
 } tftSMEContext, *tpftSMEContext;
 
 /*--------------------------------------------------------------------------
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 4c6aa21..893eda0 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -76,14 +76,16 @@
 #include "csrEse.h"
 #endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */
 #include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
+
+
 #define CSR_NUM_IBSS_START_CHANNELS_50      4
 #define CSR_NUM_IBSS_START_CHANNELS_24      3
 #define CSR_DEF_IBSS_START_CHANNEL_50       36
 #define CSR_DEF_IBSS_START_CHANNEL_24       1
-/* 15 seconds, for WPA, WPA2, CCKM */
-#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD     (15 * PAL_TIMER_TO_SEC_UNIT)
-/* 120 seconds, for WPS */
-#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT)
+
 /*---------------------------------------------------------------------------
   OBIWAN recommends [8 10]% : pick 9% 
 ---------------------------------------------------------------------------*/
@@ -214,12 +216,10 @@
 static eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval);
 static eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId);
 static void csrRoamRoamingTimerHandler(void *pv);
-eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval);
 eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac);
 static void csrRoamWaitForKeyTimeOutHandler(void *pv);
 static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
 static eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
-static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo );
 eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, 
            tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType, 
            tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection,
@@ -230,7 +230,6 @@
                                     tCsrRoamProfile *pProfile );
 void csrRoamStatisticsTimerHandler(void *pv);
 void csrRoamStatsGlobalClassDTimerHandler(void *pv);
-static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid);
 VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal, 
                                             v_U8_t  rssiNotification, 
                                             void * context);
@@ -1007,7 +1006,7 @@
     return (status);
 }
 
-static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo )
+eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo )
 {
     eHalStatus status = eHAL_STATUS_SUCCESS;
     if( pConnectedInfo->pbFrames )
@@ -1976,6 +1975,11 @@
                 pParam->PERMinRssiThresholdForRoam;
         pMac->PERroamTimeout = pParam->waitPeriodForNextPERScan;
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+        pMac->roam.configParam.enable_lfr_mbb = pParam->enable_lfr_mbb;
+#endif
+
 #ifdef FEATURE_WLAN_LFR
         pMac->roam.configParam.isFastRoamIniFeatureEnabled = pParam->isFastRoamIniFeatureEnabled;
         pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled;
@@ -2206,6 +2210,11 @@
         pParam->PERMinRssiThresholdForRoam =
                 pMac->roam.configParam.PERMinRssiThresholdForRoam;
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+        pParam->enable_lfr_mbb = pMac->roam.configParam.enable_lfr_mbb;
+#endif
+
 #ifdef FEATURE_WLAN_LFR
         pParam->isFastRoamIniFeatureEnabled = pMac->roam.configParam.isFastRoamIniFeatureEnabled;
 #endif
@@ -5064,6 +5073,20 @@
                 pCommand->u.roamCmd.pLastRoamBss);
         break;
 
+#ifdef WLAN_FEATURE_LFR_MBB
+    case ecsr_mbb_perform_preauth_reassoc:
+        smsLog(pMac, LOG1, FL("Attempting MBB PreAuth/Reassoc Req"));
+        status = csr_roam_issue_preauth_reassoc_req(pMac, sessionId,
+                pCommand->u.roamCmd.pLastRoamBss);
+        if (eHAL_STATUS_SUCCESS != status)
+        {
+            pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+            smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+                    pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+        }
+        break;
+#endif
+
     default:
         csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId );
 
@@ -5201,9 +5224,10 @@
 #endif /* FEATURE_WLAN_WAPI */
 extern tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ];
 
-static eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrAuthType authType, 
-                                         tSirBssDescription *pSirBssDesc,
-                                         tDot11fBeaconIEs *pIes)
+eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac,
+                                    tANI_U32 sessionId, eCsrAuthType authType,
+                                    tSirBssDescription *pSirBssDesc,
+                                    tDot11fBeaconIEs *pIes)
 {
     eHalStatus status = eHAL_STATUS_SUCCESS;
     tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
@@ -7391,6 +7415,9 @@
                 csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
             }
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+            csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
         }
 
         if( fDisassoc )
@@ -10050,6 +10077,10 @@
                         csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
                     }
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+                    csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
+
                     pSession = CSR_GET_SESSION( pMac, sessionId );
 
                     if (!pSession)
@@ -10126,6 +10157,9 @@
                     csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
                 }
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+                csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
                 pSession = CSR_GET_SESSION( pMac, sessionId );
 
                 if(!pSession)
@@ -10918,6 +10952,13 @@
             csrRoamFTPreAuthRspProcessor( pMac, (tpSirFTPreAuthRsp)pSirMsg );
             break;
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+        case eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP:
+             csr_roam_preauth_rsp_mbb_processor(pMac,
+                                           (tpSirFTPreAuthRsp)pSirMsg);
+             break;
+#endif
+
         case eWNI_SME_MAX_ASSOC_EXCEEDED:
             pSmeMaxAssocInd = (tSmeMaxAssocInd*)pSirMsg;
             smsLog( pMac, LOG1, FL("send indication that max assoc have been reached and the new peer cannot be accepted"));
@@ -14008,6 +14049,719 @@
     return( status );
 }
 
+#ifdef WLAN_FEATURE_LFR_MBB
+/**
+ * csr_prepare_reassoc_req () - Prepares reassoc request
+ * @mac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @ies: pointer to beacon IE's
+ * @reassoc_req: pointer to reassociation request
+ *
+ *Return: None
+ */
+eHalStatus csr_fill_reassoc_req(tpAniSirGlobal mac, tANI_U32 session_id,
+    tSirBssDescription *bss_description, tDot11fBeaconIEs *ies,
+    tSirSmeJoinReq **reassoc_req)
+{
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tSirSmeJoinReq *csr_join_req;
+    tANI_U8 *buf;
+    v_U8_t acm_mask = 0, uapsd_mask;
+    tANI_U16 msg_len, w_tmp, ie_len;
+    tSirMacRateSet op_rate_set;
+    tSirMacRateSet ex_rate_set;
+    tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
+    tANI_U32 dw_tmp;
+    tANI_U8 wpa_rsn_ie[DOT11F_IE_RSN_MAX_LEN];
+    tANI_U32 uc_dot11_mode = 0;
+    tANI_U8 tx_bf_csn_value = 0;
+    tANI_U16 rate_bitmap = 0;
+    tANI_U16 message_type = eWNI_SME_REASSOC_REQ;
+    tCsrRoamProfile *profile;
+
+    if(!session) {
+        smsLog(mac, LOGE, FL("  session %d not found "), session_id);
+        return eHAL_STATUS_FAILURE;
+    }
+
+    if (NULL == bss_description) {
+        smsLog(mac, LOGE, FL(" pBssDescription is NULL"));
+        return eHAL_STATUS_FAILURE;
+    }
+
+    smsLog(mac, LOG1,
+           FL("session_id %d"), session_id);
+
+    profile = vos_mem_malloc(sizeof(*profile));
+    if (NULL == profile) {
+        smsLog(mac, LOGE, FL("Memory allocation failure for profile"));
+        return eHAL_STATUS_RESOURCES;
+    }
+
+    status = csrRoamCopyProfile(mac, profile, session->pCurRoamProfile);
+    if(!HAL_STATUS_SUCCESS(status)) {
+       smsLog(mac, LOGE, FL("Profile copy failed"));
+       return eHAL_STATUS_FAILURE;
+    }
+
+    do {
+        /*
+         * There are a number of variable length fields to consider.
+         * First, the tSirSmeJoinReq includes a single bssDescription.
+         * bssDescription includes a single tANI_U32 for the IE fields,
+         * but the length field in the bssDescription needs to be
+         * interpreted to determine length of the IE fields.
+         * So, take the size of the JoinReq, subtract the size of the
+         * bssDescription and add in the length from the bssDescription
+         * (then add the size of the 'length' field itself because that is
+         * NOT included in the length field). msgLen =
+         * sizeof( tSirSmeJoinReq ) - sizeof( *pBssDescription ) +
+         * pBssDescription->length + sizeof( pBssDescription->length ) +
+         * sizeof( tCsrWpaIe ) + sizeof( tCsrWpaAuthIe ) + sizeof( tANI_U16 );
+         * add in the size of the WPA IE that we may build.
+         */
+
+        msg_len = sizeof(tSirSmeJoinReq) - sizeof(*bss_description) +
+            bss_description->length + sizeof(bss_description->length) +
+            sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) + sizeof(tANI_U16);
+
+        csr_join_req = vos_mem_malloc(msg_len);
+        if (NULL == csr_join_req)
+            status = eHAL_STATUS_FAILURE;
+        else
+            status = eHAL_STATUS_SUCCESS;
+        if (!HAL_STATUS_SUCCESS(status)) break;
+
+        vos_mem_set(csr_join_req, msg_len, 0);
+        *reassoc_req = csr_join_req;
+
+        csr_join_req->messageType = pal_cpu_to_be16(eWNI_SME_REASSOC_REQ);
+        csr_join_req->length = pal_cpu_to_be16(msg_len);
+        buf = &csr_join_req->sessionId;
+
+        /* session_id */
+        *buf = (tANI_U8)session_id;
+        buf++;
+
+        /* transactionId */
+        *buf = 0;
+        *(buf + 1) = 0;
+        buf += sizeof(tANI_U16);
+
+        /* ssId */
+        if(ies->SSID.present && ies->SSID.num_ssid)
+        {
+            /* ssId len */
+            *buf = ies->SSID.num_ssid;
+            buf++;
+            vos_mem_copy(buf, ies->SSID.ssid, ies->SSID.num_ssid);
+            buf += ies->SSID.num_ssid;
+        }
+        else
+        {
+            *buf = 0;
+            buf++;
+        }
+
+        /* selfMacAddr */
+        vos_mem_copy((tSirMacAddr *)buf, &session->selfMacAddr,
+                     sizeof(tSirMacAddr));
+        buf += sizeof(tSirMacAddr);
+
+        /* bsstype */
+        dw_tmp =
+            pal_cpu_to_be32(csrTranslateBsstypeToMacType(profile->BSSType));
+        /* Override BssType for BTAMP */
+        if (dw_tmp == eSIR_BTAMP_STA_MODE) dw_tmp = eSIR_BTAMP_AP_MODE;
+        vos_mem_copy(buf, &dw_tmp, sizeof(tSirBssType));
+        buf += sizeof(tSirBssType);
+
+        /* dot11mode */
+        uc_dot11_mode =
+         csrTranslateToWNICfgDot11Mode(mac, session->bssParams.uCfgDot11Mode);
+        if (bss_description->channelId <= 14 &&
+            FALSE == mac->roam.configParam.enableVhtFor24GHz &&
+            WNI_CFG_DOT11_MODE_11AC == uc_dot11_mode)
+        {
+            /* Need to disable VHT operation in 2.4 GHz band */
+            uc_dot11_mode = WNI_CFG_DOT11_MODE_11N;
+        }
+        *buf = (tANI_U8)uc_dot11_mode;
+        buf++;
+
+        /* Persona */
+        *buf = (tANI_U8)profile->csrPersona;
+        buf++;
+        *buf = (tANI_U8)profile->bOSENAssociation;
+        buf++;
+        *buf = (tANI_U8)profile->bWPSAssociation;
+        buf++;
+
+        /* CBMode */
+        *buf = (tANI_U8)session->bssParams.cbMode;
+        buf++;
+
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                  FL("CSR PERSONA=%d CSR CbMode %d"), profile->csrPersona,
+                     session->bssParams.cbMode);
+
+        /* uapsdPerAcBitmask */
+        *buf = profile->uapsd_mask;
+        buf++;
+
+
+        status = csrGetRateSet(mac, profile, (eCsrPhyMode)profile->phyMode,
+                 bss_description, ies, &op_rate_set, &ex_rate_set,&rate_bitmap);
+        if (HAL_STATUS_SUCCESS(status))
+        {
+            /* OperationalRateSet */
+            if (op_rate_set.numRates) {
+                *buf++ = op_rate_set.numRates;
+                vos_mem_copy(buf, op_rate_set.rate, op_rate_set.numRates);
+                buf += op_rate_set.numRates;
+            } else *buf++ = 0;
+
+            /* ExtendedRateSet */
+            if (ex_rate_set.numRates) {
+                *buf++ = ex_rate_set.numRates;
+                vos_mem_copy(buf, ex_rate_set.rate, ex_rate_set.numRates);
+                buf += ex_rate_set.numRates;
+            } else *buf++ = 0;
+        }
+        else
+        {
+            *buf++ = 0;
+            *buf++ = 0;
+        }
+
+        /* rateBitmap */
+        vos_mem_copy(buf, &rate_bitmap, sizeof(tANI_U16));
+        buf += sizeof(tANI_U16);
+
+        profile->negotiatedAuthType =
+            mac->roam.roamSession[session_id].connectedProfile.AuthType;
+        profile->negotiatedUCEncryptionType =
+            mac->roam.roamSession[session_id].connectedProfile.EncryptionType;
+
+        /* rsnIE */
+        if ( csrIsProfileWpa(profile))
+        {
+            /* Insert the Wpa IE into the join request */
+            ie_len = csrRetrieveWpaIe(mac, profile, bss_description, ies,
+                    (tCsrWpaIe *)(wpa_rsn_ie));
+        }
+        else if( csrIsProfileRSN(profile))
+        {
+            /* Insert the RSN IE into the join request */
+            ie_len = csrRetrieveRsnIe(mac, session_id, profile, bss_description,
+                                 ies, (tCsrRSNIe *)(wpa_rsn_ie));
+        }
+#ifdef FEATURE_WLAN_WAPI
+        else if( csrIsProfileWapi(profile))
+        {
+            /* Insert the WAPI IE into the join request */
+            ie_len = csrRetrieveWapiIe(mac, session_id, profile,
+                           bss_description, ies, (tCsrWapiIe *)(wpa_rsn_ie));
+        }
+#endif
+        else
+        {
+            ie_len = 0;
+        }
+        /* remember the IE for future use */
+        if(ie_len)
+        {
+            if(ie_len > DOT11F_IE_RSN_MAX_LEN)
+            {
+                smsLog(mac, LOGE,
+                       FL("WPA RSN IE length :%d is more than RSN_MAX_LEN %d"),
+                       ie_len, DOT11F_IE_RSN_MAX_LEN);
+                ie_len = DOT11F_IE_RSN_MAX_LEN;
+            }
+#ifdef FEATURE_WLAN_WAPI
+            if( csrIsProfileWapi(profile))
+            {
+                /* Check whether we need to allocate more memory */
+                if(ie_len > session->nWapiReqIeLength)
+                {
+                    if(session->pWapiReqIE && session->nWapiReqIeLength)
+                    {
+                        vos_mem_free(session->pWapiReqIE);
+                    }
+                    session->pWapiReqIE = vos_mem_malloc(ie_len);
+                    if (NULL == session->pWapiReqIE)
+                        status = eHAL_STATUS_FAILURE;
+                    else
+                        status = eHAL_STATUS_SUCCESS;
+                    if(!HAL_STATUS_SUCCESS(status)) break;
+                }
+                session->nWapiReqIeLength = ie_len;
+                vos_mem_copy(session->pWapiReqIE, wpa_rsn_ie, ie_len);
+                w_tmp = pal_cpu_to_be16(ie_len);
+                vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+                buf += sizeof(tANI_U16);
+                vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+                buf += ie_len;
+            }
+            else /* should be WPA/WPA2 otherwise */
+#endif
+            {
+                /* Check whether we need to allocate more memory */
+                if(ie_len > session->nWpaRsnReqIeLength)
+                {
+                    if(session->pWpaRsnReqIE && session->nWpaRsnReqIeLength)
+                    {
+                        vos_mem_free(session->pWpaRsnReqIE);
+                    }
+                    session->pWpaRsnReqIE = vos_mem_malloc(ie_len);
+                    if (NULL == session->pWpaRsnReqIE)
+                        status = eHAL_STATUS_FAILURE;
+                    else
+                        status = eHAL_STATUS_SUCCESS;
+                    if(!HAL_STATUS_SUCCESS(status)) break;
+                }
+                session->nWpaRsnReqIeLength = ie_len;
+                vos_mem_copy(session->pWpaRsnReqIE, wpa_rsn_ie, ie_len);
+                w_tmp = pal_cpu_to_be16(ie_len);
+                vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+                buf += sizeof(tANI_U16);
+                vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+                buf += ie_len;
+            }
+        }
+        else
+        {
+            /* free whatever old info */
+            session->nWpaRsnReqIeLength = 0;
+            if(session->pWpaRsnReqIE)
+            {
+                vos_mem_free(session->pWpaRsnReqIE);
+                session->pWpaRsnReqIE = NULL;
+            }
+#ifdef FEATURE_WLAN_WAPI
+            session->nWapiReqIeLength = 0;
+            if(session->pWapiReqIE)
+            {
+                vos_mem_free(session->pWapiReqIE);
+                session->pWapiReqIE = NULL;
+            }
+#endif
+            /* length is two bytes */
+            *buf = 0;
+            *(buf + 1) = 0;
+            buf += 2;
+        }
+#ifdef FEATURE_WLAN_ESE
+        if(eWNI_SME_JOIN_REQ == message_type)
+        {
+            /*
+             * Never include the cckmIE in an Join Request
+             * length is two bytes
+             */
+            *buf = 0;
+            *(buf + 1) = 0;
+            buf += 2;
+        }
+        else if(eWNI_SME_REASSOC_REQ == message_type)
+        {
+            /* cckmIE */
+            if( csrIsProfileESE(profile))
+            {
+                /* Insert the CCKM IE into the join request */
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+                ie_len = session->suppCckmIeInfo.cckmIeLen;
+                vos_mem_copy((void *) (wpa_rsn_ie),
+                     session->suppCckmIeInfo.cckmIe, ie_len);
+#else
+                ie_len = csrConstructEseCckmIe(mac,
+                                          session,
+                                          profile,
+                                          bss_description,
+                                          session->pWpaRsnReqIE,
+                                          session->nWpaRsnReqIeLength,
+                                          (void *)(wpa_rsn_ie));
+#endif
+            }
+            else
+            {
+                ie_len = 0;
+            }
+            /*
+             * If present, copy the IE into the eWNI_SME_REASSOC_REQ
+             * message buffer
+             */
+            if(ie_len)
+            {
+                /* Copy the CCKM IE over from the temp buffer (wpaRsnIE) */
+                w_tmp = pal_cpu_to_be16(ie_len);
+                vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+                buf += sizeof(tANI_U16);
+                vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+                buf += ie_len;
+            }
+            else
+            {
+                /* Indicate you have no CCKM IE length is two bytes */
+                *buf = 0;
+                *(buf + 1) = 0;
+                buf += 2;
+            }
+        }
+#endif
+        /* addIEScan */
+        if (profile->nAddIEScanLength)
+        {
+            ie_len = profile->nAddIEScanLength;
+            memset(session->addIEScan, 0 , session->nAddIEScanLength);
+            session->nAddIEScanLength = ie_len;
+            vos_mem_copy(session->addIEScan, profile->addIEScan, ie_len);
+            w_tmp = pal_cpu_to_be16(ie_len);
+            vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+            buf += sizeof(tANI_U16);
+            vos_mem_copy(buf, profile->addIEScan, ie_len);
+            buf += ie_len;
+        }
+        else
+        {
+            memset(session->addIEScan, 0, session->nAddIEScanLength);
+            session->nAddIEScanLength = 0;
+            *buf = 0;
+            *(buf + 1) = 0;
+            buf += 2;
+        }
+        /* addIEAssoc */
+        if(profile->nAddIEAssocLength && profile->pAddIEAssoc)
+        {
+            ie_len = profile->nAddIEAssocLength;
+            if(ie_len > session->nAddIEAssocLength)
+            {
+                if(session->pAddIEAssoc && session->nAddIEAssocLength)
+                {
+                    vos_mem_free(session->pAddIEAssoc);
+                }
+                session->pAddIEAssoc = vos_mem_malloc(ie_len);
+                if (NULL == session->pAddIEAssoc)
+                    status = eHAL_STATUS_FAILURE;
+                else
+                    status = eHAL_STATUS_SUCCESS;
+                if(!HAL_STATUS_SUCCESS(status)) break;
+            }
+            session->nAddIEAssocLength = ie_len;
+            vos_mem_copy(session->pAddIEAssoc, profile->pAddIEAssoc, ie_len);
+            w_tmp = pal_cpu_to_be16(ie_len);
+            vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+            buf += sizeof(tANI_U16);
+            vos_mem_copy(buf, profile->pAddIEAssoc, ie_len);
+            buf += ie_len;
+        }
+        else
+        {
+            session->nAddIEAssocLength = 0;
+            if(session->pAddIEAssoc)
+            {
+                vos_mem_free(session->pAddIEAssoc);
+                session->pAddIEAssoc = NULL;
+            }
+            *buf = 0;
+            *(buf + 1) = 0;
+            buf += 2;
+        }
+
+        if(eWNI_SME_REASSOC_REQ == message_type )
+        {
+            /*Unmask any AC in reassoc that is ACM-set */
+            uapsd_mask = (v_U8_t)profile->uapsd_mask;
+            if( uapsd_mask && (NULL != bss_description))
+            {
+                if( CSR_IS_QOS_BSS(ies) && CSR_IS_UAPSD_BSS(ies) )
+                {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+                    acm_mask = sme_QosGetACMMask(mac, bss_description, ies);
+#endif
+                }
+                else
+                {
+                    uapsd_mask = 0;
+                }
+            }
+        }
+
+        dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType(
+                                  profile->negotiatedUCEncryptionType));
+        vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+        buf += sizeof(tANI_U32);
+
+        dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType(
+                                 profile->negotiatedMCEncryptionType));
+        vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+        buf += sizeof(tANI_U32);
+#ifdef WLAN_FEATURE_11W
+        /* MgmtEncryption */
+        if (profile->MFPEnabled)
+        {
+            dw_tmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC);
+        }
+        else
+        {
+            dw_tmp = pal_cpu_to_be32(eSIR_ED_NONE);
+        }
+        vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+        buf += sizeof(tANI_U32);
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+        profile->MDID.mdiePresent = bss_description->mdiePresent;
+        if (csrIsProfile11r(profile)
+#ifdef FEATURE_WLAN_ESE
+           && !((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) &&
+                (ies->ESEVersion.present) &&
+                          (mac->roam.configParam.isEseIniFeatureEnabled))
+#endif
+        )
+        {
+            /* is11Rconnection */
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)) ;
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            /* is11Rconnection */
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+#endif
+#ifdef FEATURE_WLAN_ESE
+
+        /* isESEFeatureIniEnabled */
+        if (TRUE == mac->roam.configParam.isEseIniFeatureEnabled)
+        {
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+
+        /* A profile can not be both ESE and 11R. But an 802.11R AP
+         * may be advertising support for ESE as well. So if we are
+         * associating Open or explicitly ESE then we will get ESE.
+         * If we are associating explictly 11R only then we will get
+         * 11R.
+         */
+        if ((csrIsProfileESE(profile) ||
+             ((ies->ESEVersion.present)
+               && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)
+               || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
+               || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
+               || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+               || (profile->negotiatedAuthType ==
+                                              eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+               || (profile->negotiatedAuthType ==
+                                            eCSR_AUTH_TYPE_RSN_8021X_SHA256)
+#endif
+               || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
+               && (mac->roam.configParam.isEseIniFeatureEnabled))
+        {
+            /* isESEconnection */
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            /* isESEconnection */
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+
+        if (eWNI_SME_JOIN_REQ == message_type)
+        {
+            tESETspecInfo eseTspec;
+            /*
+             * ESE-Tspec IEs in the ASSOC request is presently not supported
+             * so nullify the TSPEC parameters
+             */
+            vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+            vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo));
+            buf += sizeof(tESETspecInfo);
+        }
+        else if (eWNI_SME_REASSOC_REQ == message_type)
+        {
+        if ((csrIsProfileESE(profile) ||
+             ((ies->ESEVersion.present)
+              && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)
+                  || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
+                  || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
+                  || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+                  || (profile->negotiatedAuthType ==
+                                              eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+                  || (profile->negotiatedAuthType ==
+                                            eCSR_AUTH_TYPE_RSN_8021X_SHA256)
+#endif
+                  || (profile->negotiatedAuthType ==
+                                                  eCSR_AUTH_TYPE_RSN_PSK))))
+            && (mac->roam.configParam.isEseIniFeatureEnabled))
+        {
+           tESETspecInfo eseTspec;
+           /* ESE Tspec information */
+           vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+           eseTspec.numTspecs = sme_QosESERetrieveTspecInfo(mac, session_id,
+                                           (tTspecInfo *) &eseTspec.tspec[0]);
+           *buf = eseTspec.numTspecs;
+           buf += sizeof(tANI_U8);
+           // Copy the TSPEC information only if present
+           if (eseTspec.numTspecs) {
+               vos_mem_copy(buf, (void*)&eseTspec.tspec[0],
+                           (eseTspec.numTspecs*sizeof(tTspecInfo)));
+           }
+           buf += sizeof(eseTspec.tspec);
+        }
+        else
+        {
+                tESETspecInfo eseTspec;
+                /*
+                 * ESE-Tspec IEs in the ASSOC request is presently
+                 * not supported so nullify the TSPEC parameters
+                 */
+                vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+                vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo));
+                buf += sizeof(tESETspecInfo);
+            }
+        }
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+        /* Fill in isFastTransitionEnabled */
+        if (mac->roam.configParam.isFastTransitionEnabled
+#ifdef FEATURE_WLAN_LFR
+         || csrRoamIsFastRoamEnabled(mac, session_id)
+#endif
+         )
+        {
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+#endif
+#ifdef FEATURE_WLAN_LFR
+        if(csrRoamIsFastRoamEnabled(mac, session_id))
+        {
+            /* legacy fast roaming enabled */
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+#endif
+
+        /* txLdpcIniFeatureEnabled */
+        *buf = (tANI_U8)mac->roam.configParam.txLdpcEnable;
+        buf++;
+
+        if ((csrIs11hSupported(mac)) &&
+            (CSR_IS_CHANNEL_5GHZ(bss_description->channelId)) &&
+            (ies->Country.present) &&\
+            (!mac->roam.configParam.fSupplicantCountryCodeHasPriority))
+        {
+            csrSaveToChannelPower2G_5G(mac,
+                          ies->Country.num_triplets * sizeof(tSirMacChanInfo),
+                          (tSirMacChanInfo *)(&ies->Country.triplets[0]));
+            csrApplyPower2Current(mac);
+        }
+
+#ifdef WLAN_FEATURE_11AC
+        /* txBFIniFeatureEnabled */
+        *buf = (tANI_U8)mac->roam.configParam.txBFEnable;
+        buf++;
+
+        /* txBFCsnValue */
+        if (IS_BSS_VHT_CAPABLE(ies->VHTCaps))
+        {
+            tx_bf_csn_value = (tANI_U8)mac->roam.configParam.txBFCsnValue;
+            if (ies->VHTCaps.numSoundingDim)
+               tx_bf_csn_value = CSR_ROAM_MIN
+                  (tx_bf_csn_value, ies->VHTCaps.numSoundingDim);
+        }
+        *buf = tx_bf_csn_value;
+        buf++;
+
+        /* Only enable MuBf if no other MuBF session exist
+         * and FW and HOST is MuBF capable.
+         */
+        if (IS_MUMIMO_BFORMEE_CAPABLE && (FALSE == mac->isMuBfsessionexist))
+        {
+           *buf = (tANI_U8)mac->roam.configParam.txMuBformee;
+           buf++;
+        }
+        else
+        {
+           *buf = 0;
+           buf++;
+        }
+#endif
+        *buf = (tANI_U8)mac->roam.configParam.isAmsduSupportInAMPDU;
+        buf++;
+
+        /* WME */
+        if(mac->roam.roamSession[session_id].fWMMConnection)
+        {
+           /* WME  enabled */
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+
+        /* QOS */
+        if(mac->roam.roamSession[session_id].fQOSConnection)
+        {
+            /* QOS  enabled */
+            dw_tmp = pal_cpu_to_be32(TRUE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        else
+        {
+            dw_tmp = pal_cpu_to_be32(FALSE);
+            vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+            buf += sizeof(tAniBool);
+        }
+        /* BssDesc */
+        csrPrepareJoinReassocReqBuffer(mac, bss_description, buf,
+                (tANI_U8)profile->uapsd_mask);
+    } while( 0 );
+
+    smsLog(mac, LOG1, FL("status %d"), status);
+
+    vos_mem_free(profile);
+    return status;
+}
+#endif
+
 //
 eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode )
 {
@@ -15450,7 +16204,7 @@
     }
     return (nRet);
 }
-static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid)
+void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid)
 {
    VOS_STATUS status = VOS_STATUS_SUCCESS;
 
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index e9ce0c7..beb4592 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -9174,6 +9174,25 @@
    vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) macHeader->bssId, sizeof(tSirMacAddr));
    pBssDescr->nReceivedTime = vos_timer_get_system_time();
 
+#ifdef WLAN_FEATURE_VOWIFI_11R
+    // MobilityDomain
+    pBssDescr->mdie[0] = 0;
+    pBssDescr->mdie[1] = 0;
+    pBssDescr->mdie[2] = 0;
+    pBssDescr->mdiePresent = FALSE;
+    // If mdie is present in the probe resp we fill it in the bss description
+    if(pParsedFrame->mdiePresent)
+    {
+        pBssDescr->mdiePresent = TRUE;
+        pBssDescr->mdie[0] = pParsedFrame->mdie[0];
+        pBssDescr->mdie[1] = pParsedFrame->mdie[1];
+        pBssDescr->mdie[2] = pParsedFrame->mdie[2];
+    }
+    smsLog(pMac, LOG1, FL("mdie=%02x%02x%02x"),
+           (unsigned int)pBssDescr->mdie[0], (unsigned int)pBssDescr->mdie[1],
+           (unsigned int)pBssDescr->mdie[2]);
+#endif
+
    smsLog( pMac, LOG1, FL("Bssid= "MAC_ADDRESS_STR
                        " chan= %d, rssi = %d "),
                        MAC_ADDR_ARRAY(pBssDescr->bssId),
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index a57a09c..2f57205 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -273,6 +273,10 @@
 void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf );
 tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp );
 void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
+                                        tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+v_U8_t *csrNeighborRoamStateToString(v_U8_t state);
+void csrReleaseCommandPreauth(tpAniSirGlobal pMac, tSmeCmd *pCommand);
 void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand);
 void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand);
 //pIes2 can be NULL
@@ -402,6 +406,10 @@
 eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription, 
                               tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType );
 eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode );
+#ifdef WLAN_FEATURE_LFR_MBB
+eHalStatus csr_fill_reassoc_req(tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription,
+                                  tDot11fBeaconIEs *pIes, tSirSmeJoinReq **reassoc_req);
+#endif
 eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode );
 eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd );
 eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd );
diff --git a/CORE/SME/src/csr/csrNeighborRoam.c b/CORE/SME/src/csr/csrNeighborRoam.c
index da1f2cf..6bebe7a 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.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.
  *
@@ -72,6 +72,9 @@
 #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
 #include "csrEse.h"
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
 
 #define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
 #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
@@ -112,6 +115,9 @@
         CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN );
         CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING );
         CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE );
+#ifdef WLAN_FEATURE_LFR_MBB
+        CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC);
+#endif
             default:
         return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN";
     }
@@ -253,6 +259,36 @@
                                           tpCsrNeighborRoamControlInfo pNeighborRoamInfo)
 {
     eHalStatus status = eHAL_STATUS_SUCCESS;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    smsLog(pMac, LOG1, FL("enable_lfr_mbb %d is mbb supported %d"),
+           pMac->roam.configParam.enable_lfr_mbb,
+           sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK));
+
+    if (pMac->roam.configParam.enable_lfr_mbb
+        && sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+        && (!pNeighborRoamInfo->is11rAssoc)
+#endif
+#ifdef FEATURE_WLAN_ESE
+        && (!pNeighborRoamInfo->isESEAssoc)
+#endif
+    ) {
+        smsLog(pMac, LOG1,
+               FL("Issuing preauth reassoc"));
+        status = csr_neighbor_roam_issue_preauth_reassoc(pMac);
+        if (eHAL_STATUS_SUCCESS != status)
+        {
+            pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+            smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+                    pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+        }
+        return status;
+    }
+
+
+#endif
+
 #ifdef WLAN_FEATURE_VOWIFI_11R
     if ((pNeighborRoamInfo->is11rAssoc)
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
@@ -4442,6 +4478,10 @@
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
             }
 #endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+            csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
             break;
 
         case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
@@ -4560,6 +4600,9 @@
 
     switch (pNeighborRoamInfo->neighborRoamState)
     {
+#ifdef WLAN_FEATURE_LFR_MBB
+        case eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC:
+#endif
         case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
             if (VOS_STATUS_SUCCESS != vosStatus)
             {
@@ -5282,7 +5325,14 @@
                        (eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING == pMac->roam.neighborRoamInfo.neighborRoamState) ||
                        (eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE == pMac->roam.neighborRoamInfo.neighborRoamState) ||
                        (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState) ||
-                       (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState);
+                       (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState)
+
+#ifdef WLAN_FEATURE_LFR_MBB
+                       || (eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC ==
+                                pMac->roam.neighborRoamInfo.neighborRoamState);
+#else
+                       ;
+#endif
     return (val);
 }
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
diff --git a/CORE/SME/src/csr/csr_roam_mbb.c b/CORE/SME/src/csr/csr_roam_mbb.c
new file mode 100644
index 0000000..840dbf8
--- /dev/null
+++ b/CORE/SME/src/csr/csr_roam_mbb.c
@@ -0,0 +1,848 @@
+/*
+ * 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 "smeInside.h"
+#include "csrInsideApi.h"
+#include "smsDebug.h"
+#include "macTrace.h"
+#include "csrNeighborRoam.h"
+#include "csr_roam_mbb.h"
+#include "csrInternal.h"
+#include "wlan_qct_wda.h"
+
+eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac);
+
+#define PREAUTH_REASSOC_MBB_TIMER_VALUE    60
+
+#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
+{\
+    mac->roam.neighborRoamInfo.prevNeighborRoamState = mac->roam.neighborRoamInfo.neighborRoamState;\
+    mac->roam.neighborRoamInfo.neighborRoamState = newState;\
+    VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, \
+               FL("Neighbor Roam Transition from state %s ==> %s"), \
+               csrNeighborRoamStateToString (mac->roam.neighborRoamInfo.prevNeighborRoamState), \
+               csrNeighborRoamStateToString (newState));\
+}
+
+/**
+ * csr_roam_issue_preauth_reassoc_req() -Prepares preauth request
+ * @hal: HAL context
+ * @session_id: session id
+ * @bss_description: BSS description
+ *
+ * This function prepares preauth request and sends request to PE
+ *
+ * Return: eHAL_STATUS_SUCCESS on success,
+ *           : eHAL_STATUS_RESOURCES when resource allocation is failure
+ *           : eHAL_STATUS_FAILURE otherwise
+ */
+eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal,
+                     tANI_U32 session_id, tpSirBssDescription bss_description)
+{
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+    tpSirFTPreAuthReq pre_auth_req;
+    tANI_U16 auth_req_len = 0;
+    tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
+
+    auth_req_len = sizeof(tSirFTPreAuthReq);
+    pre_auth_req = (tpSirFTPreAuthReq)vos_mem_malloc(auth_req_len);
+    if (NULL == pre_auth_req) {
+        smsLog(mac, LOGE,
+               FL("Memory allocation for Preauth request failed"));
+        return eHAL_STATUS_RESOURCES;
+    }
+
+    /*
+     * If neighborRoamState is eCSR_NEIGHBOR_ROAM_STATE_INIT
+     * by the time this API is invoked, disconnect would have happened.
+     * So, need to proceed further.
+     */
+    if (mac->roam.neighborRoamInfo.neighborRoamState ==
+                                          eCSR_NEIGHBOR_ROAM_STATE_INIT) {
+        smsLog(mac, LOGE, FL("neighborRoamState %d"),
+                          mac->roam.neighborRoamInfo.neighborRoamState);
+        return eHAL_STATUS_FAILURE;
+    }
+
+    /*
+     * Save the SME Session ID here. We need it while processing
+     * the preauth response.
+     */
+    mac->ft.ftSmeContext.smeSessionId = session_id;
+    vos_mem_zero(pre_auth_req, auth_req_len);
+
+    pre_auth_req->pbssDescription = (tpSirBssDescription)vos_mem_malloc(
+            sizeof(bss_description->length) + bss_description->length);
+    if (NULL == pre_auth_req->pbssDescription) {
+        smsLog(mac, LOGE,
+               FL("Unable to allocate memory for preauth bss description"));
+        return eHAL_STATUS_RESOURCES;
+    }
+
+    pre_auth_req->messageType =
+                     pal_cpu_to_be16(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ);
+
+    pre_auth_req->preAuthchannelNum = bss_description->channelId;
+
+    vos_mem_copy((void *)&pre_auth_req->currbssId,
+                 (void *)session->connectedProfile.bssid, sizeof(tSirMacAddr));
+    vos_mem_copy((void *)&pre_auth_req->preAuthbssId,
+                 (void *)bss_description->bssId, sizeof(tSirMacAddr));
+
+    vos_mem_copy(pre_auth_req->pbssDescription, bss_description,
+                 sizeof(bss_description->length) + bss_description->length);
+    pre_auth_req->length = pal_cpu_to_be16(auth_req_len);
+
+    /* Register mbb callback */
+    smsLog(mac, LOG1, FL("Registering mbb callback"));
+    csr_register_roaming_mbb_callback(mac);
+
+    return palSendMBMessage(mac->hHdd, pre_auth_req);
+}
+
+/**
+ * csr_neighbor_roam_issue_preauth_reassoc() -issues  preauth_reassoc request
+ * @mac: MAC context
+ *
+ * This function issues preauth_reassoc request to PE with the 1st AP
+ * entry in the roamable AP list
+ *
+ * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
+ */
+eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac)
+{
+    tpCsrNeighborRoamControlInfo neighbor_roam_info =
+                                           &mac->roam.neighborRoamInfo;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpCsrNeighborRoamBSSInfo neighbor_bss_node;
+    tCsrRoamInfo roam_info;
+
+    VOS_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
+                                                         eANI_BOOLEAN_FALSE);
+
+    neighbor_bss_node = csrNeighborRoamGetRoamableAPListNextEntry(mac,
+                               &neighbor_roam_info->roamableAPList, NULL);
+
+    if (neighbor_bss_node == NULL)
+    {
+        smsLog(mac, LOGE, FL("Roamable AP list is empty"));
+        csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_RESTART,
+                            REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+        return eHAL_STATUS_FAILURE;
+    }
+    else
+    {
+        /*
+         * Set is_preauth_lfr_mbb which will be checked in
+         * different API's.
+         */
+        mac->ft.ftSmeContext.is_preauth_lfr_mbb = true;
+        smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"),
+                mac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
+        status = csrRoamEnqueuePreauth(mac,
+                 neighbor_roam_info->csrSessionId,
+                 neighbor_bss_node->pBssDescription,
+                 ecsr_mbb_perform_preauth_reassoc,
+                 eANI_BOOLEAN_TRUE);
+
+        smsLog(mac, LOG1, FL("Before Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"),
+               MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId),
+               neighbor_bss_node->pBssDescription->channelId);
+
+        if (eHAL_STATUS_SUCCESS != status)
+        {
+            smsLog(mac, LOGE,
+                   FL("Send Preauth request to PE failed with status %d"),
+                   status);
+            return status;
+        }
+    }
+
+    neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
+
+    CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)
+
+    if (csrRoamIsFastRoamEnabled(mac, CSR_SESSION_ID_INVALID))
+    {
+        smsLog(mac, LOG1, FL("Invoking eCSR_ROAM_PMK_NOTIFY"));
+        vos_mem_copy((void *)&roam_info.bssid,
+                     (void *)neighbor_bss_node->pBssDescription->bssId,
+                     sizeof(tCsrBssid));
+        csrRoamCallCallback(mac, neighbor_roam_info->csrSessionId, &roam_info,
+                            0, eCSR_ROAM_PMK_NOTIFY, 0);
+    }
+    return status;
+}
+
+/**
+ * csr_stop_preauth_reassoc_mbb_timer() -stops preauth_reassoc timer
+ * @mac: MAC context
+ *
+ * This function stops preauth_reassoc timer
+ *
+ */
+void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac)
+{
+    VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+
+    smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+           mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+
+    if (mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started) {
+        vos_status =
+            vos_timer_stop(&mac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+        mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started =
+                                                                       false;
+    }
+
+    smsLog(mac, LOG1, FL("vos_status %d"), vos_status);
+}
+
+
+/**
+ * csr_preauth_reassoc_mbb_timer_callback() -preauth_reassoc timer callback
+ * @mac: MAC context
+ *
+ * This function issues preauth_reassoc with another roamable entry
+ *
+ */
+void csr_preauth_reassoc_mbb_timer_callback(void *context)
+{
+    tpAniSirGlobal mac = (tpAniSirGlobal)context;
+
+    mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = 0;
+
+    smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+           mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+
+    csr_neighbor_roam_issue_preauth_reassoc(mac);
+}
+
+
+/**
+ * csr_roam_dequeue_preauth_reassoc() -Dequeues
+ * ecsr_mbb_perform_preauth_reassoc
+ * @mac: MAC context
+ *
+ * This function dequeues ecsr_mbb_perform_preauth_reassoc
+ *
+ */
+eHalStatus csr_roam_dequeue_preauth_reassoc(tpAniSirGlobal mac)
+{
+    tListElem *entry;
+    tSmeCmd *command;
+    entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+    if (entry) {
+        command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+        if ((eSmeCommandRoam == command->command) &&
+            (ecsr_mbb_perform_preauth_reassoc ==
+                                    command->u.roamCmd.roamReason)) {
+            smsLog(mac, LOG1, FL("DQ-Command = %d, Reason = %d"),
+                    command->command, command->u.roamCmd.roamReason);
+            if (csrLLRemoveEntry( &mac->sme.smeCmdActiveList,
+                                       entry, LL_ACCESS_LOCK)) {
+                csrReleaseCommandPreauth( mac, command );
+            }
+        } else {
+            smsLog(mac, LOGE, FL("Command = %d, Reason = %d "),
+                    command->command, command->u.roamCmd.roamReason);
+        }
+    }
+    else {
+        smsLog(mac, LOGE,
+               FL("pEntry NULL for eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP"));
+    }
+    smeProcessPendingQueue( mac );
+    return eHAL_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler() -handles preauth
+ * reassoc response
+ * @mac: MAC context
+ * @lim_status: status of preauth reassoc response from lim
+ * @bss_description: bss description pointer
+ *
+ * This function handles preauth_reassoc response from PE. When
+ * preauth_reassoc response failure is received, preauth reassoc
+ * with new candidate will be attempted. In success case, candidate will be
+ * removed from roamable entry.
+ *
+ */
+eHalStatus
+csr_neighbor_roam_preauth_reassoc_rsp_handler(tpAniSirGlobal mac,
+          tSirRetStatus lim_status, tSirBssDescription **bss_description)
+{
+    tpCsrNeighborRoamControlInfo neighbor_roam_info =
+                                      &mac->roam.neighborRoamInfo;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    eHalStatus preauth_processed = eHAL_STATUS_SUCCESS;
+    tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
+
+    if (eANI_BOOLEAN_FALSE ==
+                neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+       /*
+        * This can happen when we disconnect immediately after sending
+        * a pre-auth request. During processing of the disconnect command,
+        * we would have reset preauthRspPending and transitioned to INIT state.
+        */
+       smsLog(mac, LOGE,
+              FL("Unexpected pre-auth response in state %d"),
+              neighbor_roam_info->neighborRoamState);
+       preauth_processed = eHAL_STATUS_FAILURE;
+       goto DEQ_PREAUTH;
+    }
+
+    if ((neighbor_roam_info->neighborRoamState !=
+                            eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)) {
+        smsLog(mac, LOGE,
+               FL("Preauth response received in state %s"),
+               macTraceGetNeighbourRoamState(
+                      neighbor_roam_info->neighborRoamState));
+        preauth_processed = eHAL_STATUS_FAILURE;
+        goto DEQ_PREAUTH;
+    }
+
+    neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
+
+    if (eSIR_SUCCESS == lim_status)
+        preauth_rsp_node = csrNeighborRoamGetRoamableAPListNextEntry(mac,
+                                  &neighbor_roam_info->roamableAPList, NULL);
+
+    if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
+        smsLog(mac, LOG1, FL("MBB Reassoc completed successfully"));
+
+        smsLog(mac, LOG1, FL("After MBB reassoc BSSID "MAC_ADDRESS_STR" Ch %d"),
+               MAC_ADDR_ARRAY(preauth_rsp_node->pBssDescription->bssId),
+               preauth_rsp_node->pBssDescription->channelId);
+
+        /* Memory will be freed in caller of this */
+        *bss_description = (tpSirBssDescription)vos_mem_malloc(
+                           sizeof(preauth_rsp_node->pBssDescription->length) +
+                           preauth_rsp_node->pBssDescription->length);
+        if (NULL == *bss_description) {
+            smsLog(mac, LOGE,
+                   FL("Unable to allocate memory for preauth bss description"));
+            preauth_processed = eHAL_STATUS_RESOURCES;
+            goto DEQ_PREAUTH;
+        }
+
+        vos_mem_copy(*bss_description, preauth_rsp_node->pBssDescription,
+                     sizeof(preauth_rsp_node->pBssDescription->length) +
+                     preauth_rsp_node->pBssDescription->length);
+
+        /*
+        * MBB Reassoc competer successfully. Insert the preauthenticated
+        * node to tail of preAuthDoneList
+        */
+        csrNeighborRoamRemoveRoamableAPListEntry(mac,
+                         &neighbor_roam_info->roamableAPList, preauth_rsp_node);
+        csrLLInsertTail(&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
+                                  &preauth_rsp_node->List, LL_ACCESS_LOCK);
+        return eHAL_STATUS_SUCCESS;
+    } else {
+        tpCsrNeighborRoamBSSInfo    neighbor_bss_node = NULL;
+        tListElem                   *entry;
+
+        /*
+        * Pre-auth failed. Add the bssId to the preAuth failed list MAC Address.
+        * Also remove the AP from roamable AP list. The one in the head of the
+        * list should be one with which we issued pre-auth and failed.
+        */
+        entry = csrLLRemoveHead(&neighbor_roam_info->roamableAPList,
+                                  LL_ACCESS_LOCK);
+        if(entry) {
+           neighbor_bss_node = GET_BASE_ADDR(entry,
+                                            tCsrNeighborRoamBSSInfo, List);
+           /*
+            * Add the BSSID to pre-auth fail list if it is
+            * not requested by HDD
+            */
+           status = csrNeighborRoamAddBssIdToPreauthFailList(mac,
+                                 neighbor_bss_node->pBssDescription->bssId);
+
+           smsLog(mac, LOG1,
+               FL("MBB reassoc failed BSSID "MAC_ADDRESS_STR" Ch:%d status %d"),
+               MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId),
+               neighbor_bss_node->pBssDescription->channelId, lim_status);
+
+           /* Now we can free this node */
+           csrNeighborRoamFreeNeighborRoamBSSNode(mac, neighbor_bss_node);
+        }
+
+        /*
+        * Move state to Connected. Connected state here signifies connection
+        * with current AP as preauth failed with roamable AP. Still driver has
+        * connection with current AP.
+        */
+        CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
+
+        /* Start a timer to issue preauth_reassoc request for the next entry*/
+        status = vos_timer_start(&mac->ft.ftSmeContext.
+                   pre_auth_reassoc_mbb_timer, PREAUTH_REASSOC_MBB_TIMER_VALUE);
+        if (eHAL_STATUS_SUCCESS != status) {
+            smsLog(mac, LOGE,
+                   FL("pre_auth_reassoc_mbb_timer start failed status %d"),
+                   status);
+            preauth_processed = eHAL_STATUS_FAILURE;
+            goto DEQ_PREAUTH;
+        }
+        mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = true;
+        smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+           mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+        preauth_processed = eHAL_STATUS_SUCCESS;
+    }
+
+DEQ_PREAUTH:
+    csr_roam_dequeue_preauth_reassoc(mac);
+    return preauth_processed;
+}
+
+eHalStatus csr_update_roamed_info_mbb(tHalHandle hal,
+     tpSirBssDescription bss_description, tpSirFTPreAuthRsp pre_auth_rsp)
+{
+    eHalStatus status;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+    tDot11fBeaconIEs *ies_local = NULL;
+    tCsrRoamSession *session = NULL;
+    tCsrRoamProfile *profile;
+    tSirMacAddr broadcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    tANI_U32 key_timeout_interval;
+    tCsrRoamInfo roam_info;
+    sme_QosAssocInfo assoc_info;
+    tANI_U32 len;
+    tANI_U8 sme_session_id = pre_auth_rsp->smeSessionId;
+    tANI_U8 acm_mask = 0;
+
+    /* Get profile */
+    session = CSR_GET_SESSION(mac, sme_session_id);
+
+    if (session->abortConnection) {
+        smsLog(mac, LOGE, FL("Disconnect in progress"));
+        return eHAL_STATUS_FAILURE;
+    }
+
+    profile = vos_mem_malloc(sizeof(*profile));
+    if (NULL == profile) {
+        smsLog(mac, LOGE, FL("Memory allocation failure for profile"));
+        return eHAL_STATUS_FAILURE;
+    }
+
+    status = csrRoamCopyProfile(mac, profile, session->pCurRoamProfile);
+    if(!HAL_STATUS_SUCCESS(status)) {
+       smsLog(mac, LOGE, FL("Profile copy failed"));
+       vos_mem_free(profile);
+       return status;
+    }
+
+    profile->negotiatedAuthType =
+       mac->roam.roamSession[sme_session_id].connectedProfile.AuthType;
+    profile->negotiatedUCEncryptionType =
+       mac->roam.roamSession[sme_session_id].connectedProfile.EncryptionType;
+    profile->mcEncryptionType =
+       mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionInfo;
+    profile->negotiatedMCEncryptionType =
+       mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionType;
+
+    smsLog(mac, LOG1,
+           FL("AuthType %d UCEType %d Entries %d encryptionType %d MCEType %d"),
+           profile->negotiatedAuthType,
+           profile->negotiatedUCEncryptionType,
+           profile->mcEncryptionType.numEntries,
+           profile->mcEncryptionType.encryptionType[0],
+           profile->negotiatedMCEncryptionType);
+
+    /* Get IE's */
+    status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local);
+    if (!HAL_STATUS_SUCCESS(status)) {
+        smsLog(mac, LOGE,
+               FL("csrGetParsedBssDescriptionIEs failed"));
+        return status;
+    }
+    if(ies_local == NULL) {
+       smsLog(mac, LOGE,
+              FL("ies_local is NULL "));
+       return eHAL_STATUS_FAILURE;
+    }
+
+    vos_mem_set(&roam_info, sizeof(roam_info), 0);
+
+    csrRoamStopNetwork(mac, sme_session_id, profile,
+                                          bss_description, ies_local);
+
+    session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+
+    csrRoamSaveConnectedInfomation(mac, sme_session_id, profile,
+                                                  bss_description, ies_local);
+    csrRoamSaveSecurityRspIE(mac, sme_session_id,
+                             profile->negotiatedAuthType, bss_description,
+                             ies_local);
+
+    csrRoamStateChange(mac, eCSR_ROAMING_STATE_JOINED, sme_session_id);
+
+    if(CSR_IS_ENC_TYPE_STATIC(profile->negotiatedUCEncryptionType) &&
+                                        !profile->bWPSAssociation) {
+       /*
+        * Issue the set Context request to LIM to establish the
+        * Unicast STA context
+        */
+       if(!HAL_STATUS_SUCCESS(csrRoamIssueSetContextReq(mac,
+                 sme_session_id,
+                 profile->negotiatedUCEncryptionType,
+                 bss_description, &(bss_description->bssId), FALSE, TRUE,
+                 eSIR_TX_RX, 0, 0, NULL, 0))) {
+          smsLog(mac, LOGE, FL("Set context for unicast fail"));
+          csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE,
+                                        sme_session_id);
+       }
+       /*
+        * Issue the set Context request to LIM to establish the
+        * Broadcast STA context
+        */
+       csrRoamIssueSetContextReq(mac, sme_session_id,
+                                 profile->negotiatedMCEncryptionType,
+                                 bss_description, &broadcast_mac,
+                                 FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0);
+    } else if (!session->abortConnection) {
+       /* Need to wait for supplicant authtication */
+       roam_info.fAuthRequired = eANI_BOOLEAN_TRUE;
+       /* Set the subestate to WaitForKey in case authentiation is needed */
+       csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+                                            sme_session_id);
+
+       if(profile->bWPSAssociation)
+          key_timeout_interval = CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
+       else
+          key_timeout_interval = CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD;
+
+       /* Save sessionId in case of timeout */
+       mac->roam.WaitForKeyTimerInfo.sessionId = sme_session_id;
+       /*
+        * This time should be long enough for the rest of the
+        * process plus setting key
+        */
+       if(!HAL_STATUS_SUCCESS(csrRoamStartWaitForKeyTimer(mac,
+                                             key_timeout_interval))) {
+          /* Reset our state so nothting is blocked */
+          smsLog(mac, LOGE, FL("Failed to start pre-auth timer"));
+          csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE,
+                                           sme_session_id);
+       }
+    }
+
+    csrRoamFreeConnectedInfo(mac, &session->connectedInfo);
+
+    assoc_info.pBssDesc = bss_description;
+    assoc_info.pProfile = profile;
+
+    len = pre_auth_rsp->roam_info->nBeaconLength +
+          pre_auth_rsp->roam_info->nAssocReqLength +
+          pre_auth_rsp->roam_info->nAssocRspLength;
+
+    if(len) {
+       session->connectedInfo.pbFrames = vos_mem_malloc(len);
+       if (session->connectedInfo.pbFrames != NULL ) {
+           vos_mem_copy(session->connectedInfo.pbFrames,
+                        pre_auth_rsp->roam_info->pbFrames, len);
+           session->connectedInfo.nAssocReqLength =
+                           pre_auth_rsp->roam_info->nAssocReqLength;
+           session->connectedInfo.nAssocRspLength =
+                           pre_auth_rsp->roam_info->nAssocRspLength;
+           session->connectedInfo.nBeaconLength =
+                           pre_auth_rsp->roam_info->nBeaconLength;
+
+           roam_info.nAssocReqLength = pre_auth_rsp->roam_info->nAssocReqLength;
+           roam_info.nAssocRspLength = pre_auth_rsp->roam_info->nAssocRspLength;
+           roam_info.nBeaconLength = pre_auth_rsp->roam_info->nBeaconLength;
+           roam_info.pbFrames = session->connectedInfo.pbFrames;
+       }
+       session->connectedInfo.staId = pre_auth_rsp->roam_info->staId;
+       roam_info.staId = pre_auth_rsp->roam_info->staId;
+       roam_info.ucastSig = pre_auth_rsp->roam_info->ucastSig;
+       roam_info.bcastSig = pre_auth_rsp->roam_info->bcastSig;
+       roam_info.maxRateFlags = pre_auth_rsp->roam_info->maxRateFlags;
+    }
+
+    roam_info.statusCode = eSIR_SME_SUCCESS;
+    roam_info.reasonCode = eSIR_SME_SUCCESS;
+    roam_info.pBssDesc = bss_description;
+
+    vos_mem_copy(&roam_info.bssid, &bss_description->bssId,
+                                     sizeof(tCsrBssid));
+
+    mac->roam.roamSession[sme_session_id].connectState =
+                                     eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+
+    sme_QosCsrEventInd(mac, sme_session_id,
+                            SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL);
+    sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_REASSOC_REQ, NULL);
+    sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+
+    mac->roam.roamSession[sme_session_id].connectState =
+                                    eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+    sme_QosCsrEventInd(mac, sme_session_id,
+                              SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
+
+
+    acm_mask = sme_QosGetACMMask(mac, bss_description, NULL);
+
+    session->connectedProfile.acm_mask = acm_mask;
+    if(session->connectedProfile.modifyProfileFields.uapsd_mask) {
+       smsLog(mac, LOGE, "uapsd_mask (0x%X) set, request UAPSD now",
+              session->connectedProfile.modifyProfileFields.uapsd_mask);
+              pmcStartUapsd(mac, NULL, NULL);
+    }
+    session->connectedProfile.dot11Mode = session->bssParams.uCfgDot11Mode;
+    roam_info.u.pConnectedProfile = &session->connectedProfile;
+
+    if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+                      (csrIsConcurrentSessionRunning(mac)))
+       mac->roam.configParam.doBMPSWorkaround = 1;
+
+    csr_roam_dequeue_preauth_reassoc(mac);
+
+    csrRoamCallCallback(mac, sme_session_id, &roam_info, 0,
+             eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED);
+
+    csrResetPMKIDCandidateList(mac, sme_session_id);
+#ifdef FEATURE_WLAN_WAPI
+    csrResetBKIDCandidateList(mac, sme_session_id);
+#endif
+
+    if(!CSR_IS_WAIT_FOR_KEY(mac, sme_session_id)) {
+        smsLog(mac, LOG1, "NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up");
+        csrRoamLinkUp(mac, session->connectedProfile.bssid);
+    }
+
+    if (pmcShouldBmpsTimerRun(mac)) {
+        if(eANI_BOOLEAN_TRUE == roam_info.fAuthRequired) {
+           mac->pmc.full_power_till_set_key = true;
+           smsLog(mac, LOG1,
+                  FL("full_power_till_set_key is made true"));
+        }
+
+        if (pmcStartTrafficTimer(mac, BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP)
+                    != eHAL_STATUS_SUCCESS)
+            smsLog(mac, LOGE, FL("Cannot start BMPS Retry timer"));
+
+        smsLog(mac, LOG1, FL("BMPS Retry Timer already running or started"));
+    }
+
+    vos_mem_free(pre_auth_rsp->roam_info->pbFrames);
+    vos_mem_free(pre_auth_rsp->roam_info);
+    vos_mem_free(profile);
+    vos_mem_free(ies_local);
+
+    return eHAL_STATUS_SUCCESS;
+}
+
+
+/**
+ * csr_roam_preauth_rsp_mbb_processor() -handles
+ * eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP
+ * @hal: HAL context
+ *
+ * This function invokes preauth reassoc response handler and
+ * updates CSR with new connection information.
+ *
+ */
+void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal,
+     tpSirFTPreAuthRsp pre_auth_rsp)
+{
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+    eHalStatus  status;
+    tCsrRoamInfo roam_info;
+    tpSirBssDescription  bss_description = NULL;
+
+    mac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+    smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"),
+                         mac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
+    /*
+    * When reason is SIR_MBB_DISCONNECTED, cleanup CSR info
+    * of connected AP.
+    */
+    if (pre_auth_rsp->reason == SIR_MBB_DISCONNECTED) {
+        /* Dequeue ecsr_perform_preauth_reassoc */
+        csr_roam_dequeue_preauth_reassoc(mac);
+
+        vos_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+        csrRoamCallCallback(mac, pre_auth_rsp->smeSessionId, &roam_info, 0,
+                               eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
+
+        csrRoamComplete(mac, eCsrJoinFailure, NULL);
+    }
+
+    status = csr_neighbor_roam_preauth_reassoc_rsp_handler(mac,
+                                       pre_auth_rsp->status, &bss_description);
+    if (status != eHAL_STATUS_SUCCESS) {
+        smsLog(mac, LOGE,FL("Preauth was not processed: %d SessionID: %d"),
+                            status, pre_auth_rsp->smeSessionId);
+        /*
+         * Preauth_reassoc is dequeued already in
+         * csr_neighbor_roam_preauth_reassoc_rsp_handler for error cases.
+         */
+        return;
+    }
+
+    /*
+     * The below function calls/timers should be invoked only
+     * if the pre-auth is successful. Also, Preauth_reassoc is dequeued
+     * already in csr_neighbor_roam_preauth_reassoc_rsp_handler.
+     */
+    if (VOS_STATUS_SUCCESS != (VOS_STATUS)pre_auth_rsp->status)
+        return;
+
+    mac->ft.ftSmeContext.FTState = eFT_AUTH_COMPLETE;
+
+    /* Save the received response */
+    vos_mem_copy((void *)&mac->ft.ftSmeContext.preAuthbssId,
+                 (void *)pre_auth_rsp->preAuthbssId, sizeof(tCsrBssid));
+
+
+    /*
+     * bss_description is updated in
+     * csr_neighbor_roam_preauth_reassoc_rsp_handler
+     */
+    if (NULL == bss_description) {
+        smsLog(mac, LOGE,
+               FL("bss description is NULL"));
+        goto DEQ_PREAUTH;
+    }
+
+    /* Update CSR for new connection */
+    status = csr_update_roamed_info_mbb(hal, bss_description, pre_auth_rsp);
+    /* In success case preauth reassoc is dequeued in
+     * csr_update_roamed_info_mbb before updating HDD.
+     */
+    if(HAL_STATUS_SUCCESS(status))
+       return;
+
+DEQ_PREAUTH:
+    csr_roam_dequeue_preauth_reassoc(mac);
+}
+
+/**
+ * csr_prepare_reassoc_req () - Prepares reassoc request
+ * @pmac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @preassoc_req: pointer to reassociation request
+ *
+ *Return: None
+ */
+static void csr_prepare_reassoc_req(void* pmac, tANI_U32 session_id,
+       void* pbss_description, void *preassoc_req)
+{
+    tDot11fBeaconIEs *ies_local = NULL;
+    eHalStatus status;
+    tpAniSirGlobal mac = (tpAniSirGlobal)pmac;
+    tpSirBssDescription bss_description = (tpSirBssDescription)pbss_description;
+    tSirSmeJoinReq **reassoc_req = (tSirSmeJoinReq **)preassoc_req;
+
+    /* Get IE's */
+    status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local);
+    if (!HAL_STATUS_SUCCESS(status)) {
+        smsLog(mac, LOGE,
+               FL("csrGetParsedBssDescriptionIEs failed"));
+        return;
+    }
+    if(ies_local == NULL) {
+       smsLog(mac, LOGE,
+              FL("ies_local is NULL"));
+       return;
+    }
+
+    smsLog(mac, LOG1, FL("session_id %d"), session_id);
+
+    status = csr_fill_reassoc_req(mac, session_id, bss_description,
+                         ies_local, reassoc_req);
+    if (!HAL_STATUS_SUCCESS(status)) {
+        smsLog(mac, LOGE,
+               FL("Reassociation request filling failed"));
+        return;
+    }
+    vos_mem_free(ies_local);
+    smsLog(mac, LOG1, FL("status %d"), status);
+}
+
+/**
+ * csr_roaming_mbb_callback () - handles mbb callback
+ * @pmac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @preassoc_req: pointer to reassociation request
+ * @csr_roam_op_code: callback opcode
+ *
+ *Return: None
+ */
+static void csr_roaming_mbb_callback(void* pmac, tANI_U32 session_id,
+       void* pbss_description, void *preassoc_req, tANI_U32 csr_roam_op_code)
+{
+    tpAniSirGlobal mac = (tpAniSirGlobal)pmac;
+
+    smsLog(mac, LOG1,
+           FL("csr_roam_op_code %d"), csr_roam_op_code);
+
+    switch(csr_roam_op_code) {
+    case SIR_ROAMING_DEREGISTER_STA:
+         csrRoamCallCallback(mac, session_id, NULL, 0,
+                              eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+        break;
+    case SIR_STOP_ROAM_OFFLOAD_SCAN:
+         csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED);
+       break;
+    case SIR_PREPARE_REASSOC_REQ:
+         csr_prepare_reassoc_req(pmac, session_id, pbss_description,
+                         preassoc_req);
+         break;
+    }
+}
+
+/**
+ * csr_register_roaming_mbb_callback () - registers roaming callback
+ * @mac: MAC context
+ *
+ *Return: eHAL_STATUS_SUCCESS on success, otherwise  failure
+ */
+eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac)
+{
+    eHalStatus status;
+
+    status = sme_AcquireGlobalLock(&mac->sme);
+    if (eHAL_STATUS_SUCCESS == status) {
+        mac->sme.roaming_mbb_callback = csr_roaming_mbb_callback;
+        sme_ReleaseGlobalLock(&mac->sme);
+    } else
+        smsLog(mac, LOGE,
+               FL("sme_AcquireGlobalLock error"));
+    return status;
+}
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 0fcac9f..0dd99ae 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1537,6 +1537,10 @@
 #if defined WLAN_FEATURE_VOWIFI_11R
       sme_FTOpen(pMac);
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+
+#endif
+
       sme_p2pOpen(pMac);
       smeTraceInit(pMac);
       sme_register_debug_callback();
diff --git a/CORE/SME/src/sme_common/sme_FTApi.c b/CORE/SME/src/sme_common/sme_FTApi.c
index 4d988af..c791338 100644
--- a/CORE/SME/src/sme_common/sme_FTApi.c
+++ b/CORE/SME/src/sme_common/sme_FTApi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -41,6 +41,11 @@
 #include <csrNeighborRoam.h>
 #include "vos_utils.h"
 
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
+
+
 /*--------------------------------------------------------------------------
   Initialize the FT context. 
   ------------------------------------------------------------------------*/
@@ -60,6 +65,18 @@
         return;
     }                 
     vos_reset_roam_timer_log();
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    status = vos_timer_init(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer,
+                            VOS_TIMER_TYPE_SW,
+                            csr_preauth_reassoc_mbb_timer_callback,
+                            (void *)pMac);
+
+    if (eHAL_STATUS_SUCCESS != status) {
+        smsLog(pMac, LOGE, FL("pre_auth_reassoc_mbb_timer allocation failed"));
+        return;
+    }
+#endif
 }
 
 /*--------------------------------------------------------------------------
@@ -71,6 +88,10 @@
     //Clear the FT Context.
     sme_FTReset(hHal);
     vos_timer_destroy(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    vos_timer_destroy(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+#endif
 }
 
 void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state)
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index ff50926..ba7c97a 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -137,6 +137,9 @@
         CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
         CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
         #endif /* WLAN_FEATURE_VOWIFI_11R */
+        #ifdef WLAN_FEATURE_LFR_MBB
+        CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC);
+        #endif
         CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX);
 
         default:
@@ -572,6 +575,10 @@
         CASE_RETURN_STRING(eWNI_SME_UPDATE_MAX_RATE_IND);
         CASE_RETURN_STRING(eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ);
         CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_CB);
+#ifdef WLAN_FEATURE_LFR_MBB
+        CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ);
+        CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP);
+#endif
         CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
         CASE_RETURN_STRING(eWNI_SME_CAP_TSF_REQ);
         CASE_RETURN_STRING(eWNI_SME_GET_TSF_REQ);
@@ -982,7 +989,15 @@
         CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT);
         CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT);
         CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+       CASE_RETURN_STRING(SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT);
+       CASE_RETURN_STRING(SIR_LIM_REASSOC_MBB_RSP_TIMEOUT);
+
+#endif
+
         CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
+
         CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
         CASE_RETURN_STRING(LIM_MLM_SCAN_REQ);
         CASE_RETURN_STRING(LIM_MLM_SCAN_CNF);
diff --git a/CORE/WDA/inc/legacy/halTypes.h b/CORE/WDA/inc/legacy/halTypes.h
index 804925a..f2f1b1f 100644
--- a/CORE/WDA/inc/legacy/halTypes.h
+++ b/CORE/WDA/inc/legacy/halTypes.h
@@ -219,6 +219,12 @@
 #endif
     //CMD not Queued in SME
     eHAL_STATUS_CMD_NOT_QUEUED,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+    eHAL_STATUS_MBB_DEL_BSS_FAIL,
+    eHAL_STATUS_MBB_ADD_BSS_FAIL,
+#endif
+
     // not a real status.  Just a way to mark the maximum in the enum.
     eHAL_STATUS_MAX
 
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 96bef70..8c745d9 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -3307,6 +3307,9 @@
     WDI_LINK_FINISH_CAL_STATE        = 13,
     WDI_LINK_LISTEN_STATE            = 14,
     WDI_LINK_SEND_ACTION_STATE       = 15,
+#ifdef WLAN_FEATURE_LFR_MBB
+    WDI_LINK_PRE_AUTH_REASSOC_STATE  = 17,
+#endif
     WDI_LINK_MAX                     = 0x7FFFFFFF
 } WDI_LinkStateType;
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 04a6add..a153bb9 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -223,7 +223,7 @@
    ,SAP_MODE_WOW                   //64
    ,SAP_OFFLOADS                   //65
    ,SAP_BUFF_ALLOC                 //66
-   ,FEATURE_NOT_SUPPORTED
+   ,MAKE_BEFORE_BREAK              //67
    ,NUD_DEBUG                      //68
 };
 
@@ -2013,6 +2013,13 @@
                                          "%s", "SAP_BUFF_ALLOC");
                           pCapStr += strlen("SAP_BUFF_ALLOC");
                           break;
+
+                     case MAKE_BEFORE_BREAK:
+                          snprintf(pCapStr, sizeof("MAKE_BEFORE_BREAK"),
+                                         "%s", "MAKE_BEFORE_BREAK");
+                          pCapStr += strlen("MAKE_BEFORE_BREAK");
+                          break;
+
                      case NUD_DEBUG:
                           snprintf(pCapStr, sizeof("NUD_DEBUG"),
                                          "%s", "NUD_DEBUG");
@@ -25926,6 +25933,11 @@
   case WDI_LINK_SEND_ACTION_STATE:
     return eSIR_LINK_SEND_ACTION_STATE;
 
+#ifdef WLAN_FEATURE_LFR_MBB
+  case WDI_LINK_PRE_AUTH_REASSOC_STATE:
+    return eSIR_LINK_PRE_AUTH_REASSOC_STATE;
+#endif
+
   default:
     return eSIR_LINK_MAX;
   }
diff --git a/Kbuild b/Kbuild
index a7d0f57..dfa683e 100644
--- a/Kbuild
+++ b/Kbuild
@@ -23,6 +23,9 @@
 #Flag to enable Legacy Fast Roaming(LFR)
     CONFIG_PRIMA_WLAN_LFR := y
 
+#Flag to enable Legacy Fast Roaming(LFR) Make Before Break
+    CONFIG_PRIMA_WLAN_LFR_MBB := y
+
 #JB kernel has PMKSA patches, hence enabling this flag
     CONFIG_PRIMA_WLAN_OKC := y
 
@@ -233,6 +236,10 @@
 MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessTdls.o
 endif
 
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mbb.o
+endif
+
 MAC_PMM_OBJS := $(MAC_SRC_DIR)/pe/pmm/pmmAP.o \
 		$(MAC_SRC_DIR)/pe/pmm/pmmApi.o \
 		$(MAC_SRC_DIR)/pe/pmm/pmmDebug.o
@@ -294,6 +301,10 @@
 SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrTdlsProcess.o
 endif
 
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csr_roam_mbb.o
+endif
+
 SME_PMC_OBJS := $(SME_SRC_DIR)/pmc/pmcApi.o \
 		$(SME_SRC_DIR)/pmc/pmc.o \
 		$(SME_SRC_DIR)/pmc/pmcLogDump.o
@@ -627,6 +638,10 @@
 CDEFINES += -DFEATURE_WLAN_LFR
 endif
 
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+CDEFINES += -DWLAN_FEATURE_LFR_MBB
+endif
+
 ifeq ($(CONFIG_PRIMA_WLAN_OKC),y)
 CDEFINES += -DFEATURE_WLAN_OKC
 endif
diff --git a/riva/inc/wlan_hal_msg.h b/riva/inc/wlan_hal_msg.h
index c91bb38..731d50a 100644
--- a/riva/inc/wlan_hal_msg.h
+++ b/riva/inc/wlan_hal_msg.h
@@ -842,6 +842,9 @@
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
     eSIR_LINK_FT_PREASSOC_STATE = 16,
 #endif
+#ifdef WLAN_FEATURE_LFR_MBB
+    eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
     eSIR_LINK_MAX = WLAN_HAL_MAX_ENUM_SIZE
 } tSirLinkState;
 
@@ -6904,6 +6907,7 @@
     SAP_MODE_WOW           = 64,
     SAP_OFFLOADS           = 65,
     SAP_BUFF_ALLOC         = 66,
+    MAKE_BEFORE_BREAK      = 67,
     NUD_DEBUG              = 68,
     MAX_FEATURE_SUPPORTED  = 128,
 } placeHolderInCapBitmap;