/*
 * Copyright (c) 2017-2018, 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;
    if (session_entry == NULL) {
        limLog(mac, LOGE, FL("Invalid Session Entry"));
        return;
    }

    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;
    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 cleanup;
    }

    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 cleanup;
    }

    /*
     * 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;

    /* Connected AP lim cleanup.*/
    lim_cleanup_connected_ap(mac, sta_ds_connected_ap, session_entry_con_ap);
cleanup:
    /*
     * 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 = NULL;
    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"));
        vos_mem_free(reassoc_req);
        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"));
        vos_mem_free(reassoc_req);
        goto end;
    }

    ft_session_entry = mac->ft.ftPEContext.pftSessionEntry;

    ft_session_entry->pLimReAssocReq = pReassocReq;

    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"));
        vos_mem_free(reassoc_req);
        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);
        vos_mem_free(reassoc_req);
        goto end;
    }

    lim_update_caps_info_for_bss(mac, &caps,
                        reassoc_req->bssDescription.capabilityInfo);
    vos_mem_free(reassoc_req);

    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:
    if (ft_session_entry)
        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 (%pK) 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 %pK"), 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 %pK)"), 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 %pK) 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)
{
    if (!sta_ds || !session_entry)
        return;
    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;
    if (!sta_ds) {
        limLog(mac, LOGE, FL("DPH Entry for STA missing"));
        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= %pK"),
                             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;
}
