/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */


/*
 * This file limProcessSmeReqMessages.cc contains the code
 * for processing SME request messages.
 * Author:        Chandra Modumudi
 * Date:          02/11/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */

#include "palTypes.h"
#include "wniApi.h"
#include "wni_cfg.h"
#include "cfgApi.h"
#include "sirApi.h"
#include "schApi.h"
#include "utilsApi.h"
#include "limTypes.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limSecurityUtils.h"
#include "limSerDesUtils.h"
#include "limSmeReqUtils.h"
#include "limIbssPeerMgmt.h"
#include "limAdmitControl.h"
#include "dphHashTable.h"
#include "limSendMessages.h"
#include "limApi.h"
#include "wmmApsd.h"
#include "sirMacProtDef.h"
#include "regdomain_common.h"
#include "rrmApi.h"
#include "nan_datapath.h"
#include "wma.h"
#include "sapApi.h"
#include "lim_process_fils.h"
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "eseApi.h"
#endif

#if defined WLAN_FEATURE_VOWIFI_11R
#include <limFT.h>
#endif

/* This overhead is time for sending NOA start to host in case of GO/sending NULL data & receiving ACK
 * in case of P2P Client and starting actual scanning with init scan req/rsp plus in case of concurrency,
 * taking care of sending null data and receiving ACK to/from AP/Also SetChannel with calibration is taking
 * around 7ms .
 */
#define SCAN_MESSAGING_OVERHEAD             20      // in msecs
#define JOIN_NOA_DURATION                   2000    // in msecs
#define OEM_DATA_NOA_DURATION               60      // in msecs
#define DEFAULT_PASSIVE_MAX_CHANNEL_TIME    110     // in msecs

#define CONV_MS_TO_US 1024 //conversion factor from ms to us

#define BEACON_INTERVAL_THRESHOLD 50  /* in msecs */
#define STA_BURST_SCAN_DURATION 120   /* in msecs */

// SME REQ processing function templates
static void __limProcessSmeStartReq(tpAniSirGlobal, tANI_U32 *);
static tANI_BOOLEAN __limProcessSmeSysReadyInd(tpAniSirGlobal, tANI_U32 *);
static tANI_BOOLEAN __limProcessSmeStartBssReq(tpAniSirGlobal, tpSirMsgQ pMsg);
static void __limProcessSmeScanReq(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeJoinReq(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeReassocReq(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeDisassocReq(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeDisassocCnf(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeDeauthReq(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeSetContextReq(tpAniSirGlobal, tANI_U32 *);
static tANI_BOOLEAN __limProcessSmeStopBssReq(tpAniSirGlobal, tpSirMsgQ pMsg);
static void limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac,
                                                      tANI_U32 *pMsg);
static void limProcessSmeStartBeaconReq(tpAniSirGlobal pMac,
                                                 tANI_U32 *pMsg);
static void limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg);

static void limStartBssUpdateAddIEBuffer(tpAniSirGlobal pMac,
                             tANI_U8 **pDstData_buff,
                             tANI_U16 *pDstDataLen,
                             tANI_U8 *pSrcData_buff,
                             tANI_U16 srcDataLen);

static void limUpdateAddIEBuffer(tpAniSirGlobal pMac,
                             tANI_U8 **pDstData_buff,
                             tANI_U16 *pDstDataLen,
                             tANI_U8 *pSrcData_buff,
                             tANI_U16 srcDataLen);
static tANI_BOOLEAN limUpdateIBssPropAddIEs(tpAniSirGlobal pMac,
                                            tANI_U8 **pDstData_buff,
                                            tANI_U16 *pDstDataLen,
                                            tSirModifyIE *pModifyIE);
static void limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg);

static void limProcessUpdateAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg);

static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
						uint32_t *msg);

void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *);

extern void peRegisterTLHandle(tpAniSirGlobal pMac);

static void lim_process_set_pdev_IEs(tpAniSirGlobal pMac, tANI_U32 *msg_buf);
static void lim_set_pdev_ht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
		tANI_U8 nss);
static void lim_set_pdev_vht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
		tANI_U8 nss);
static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx,
				uint32_t *msg_buf);

#ifdef BACKGROUND_SCAN_ENABLED

// start the background scan timers if it hasn't already started
static void
__limBackgroundScanInitiate(tpAniSirGlobal pMac)
{
    if (pMac->lim.gLimBackgroundScanStarted)
        return;

    //make sure timer is created first
    if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
    {
        limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
     MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER));
        if (tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
            limLog(pMac, LOGP, FL("could not activate background scan timer"));
        pMac->lim.gLimBackgroundScanStarted   = true;
        pMac->lim.gLimBackgroundScanChannelId = 0;
    }
}

#endif // BACKGROUND_SCAN_ENABLED

/**
 * __limFreshScanReqd() - determine if fresh scan request must be issued or not
 * @mac_ctx - mac global context
 * @return_fresh_results - fresh scan requested
 *
 * PE will do fresh scan, if all of the active sessions are in good state
 * (Link Est or BSS Started). If one of the sessions is not in one of the these
 * states, then PE does not do fresh scan. If no session exists (scanning very
 * first time), then PE will always do fresh scan if SME asks it to do that.
 */
static uint8_t __limFreshScanReqd(tpAniSirGlobal mac_ctx,
				  uint8_t return_fresh_results)
{
	int i;
	uint8_t valid_state = true;

	limLog(mac_ctx, LOG1, FL("gLimSmeState: %d, return_fresh_results 0x%x"),
		mac_ctx->lim.gLimSmeState, return_fresh_results);

	if (mac_ctx->lim.gLimSmeState != eLIM_SME_IDLE_STATE) {
		limLog(mac_ctx, LOG1, FL("return false, global_sme_state: %d"),
			mac_ctx->lim.gLimSmeState);
		return false;
	}

	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
		if (mac_ctx->lim.gpSession[i].valid == false)
			continue;

		limLog(mac_ctx, LOG1,
			FL("session %d, bsstype %d, limSystemRole %d, limSmeState %d"),
			i, mac_ctx->lim.gpSession[i].bssType,
			mac_ctx->lim.gpSession[i].limSystemRole,
			mac_ctx->lim.gpSession[i].limSmeState);

		if (mac_ctx->lim.gpSession[i].bssType == eSIR_NDI_MODE)
			continue;

		if (mac_ctx->lim.gpSession[i].bssType ==
					eSIR_INFRASTRUCTURE_MODE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_LINK_EST_STATE)
			continue;

		if (mac_ctx->lim.gpSession[i].limSystemRole ==
					eLIM_BT_AMP_STA_ROLE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_LINK_EST_STATE)
			continue;

		if (mac_ctx->lim.gpSession[i].bssType == eSIR_IBSS_MODE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_NORMAL_STATE)
			continue;

		if (mac_ctx->lim.gpSession[i].limSystemRole ==
					eLIM_BT_AMP_AP_ROLE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_NORMAL_STATE)
			continue;

		if (mac_ctx->lim.gpSession[i].limSystemRole ==
					eLIM_BT_AMP_STA_ROLE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_NORMAL_STATE)
			continue;

		if (mac_ctx->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE
				&& mac_ctx->lim.gpSession[i].pePersona ==
					VOS_P2P_GO_MODE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_NORMAL_STATE)
			continue;

		if (mac_ctx->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE
				&& mac_ctx->lim.gpSession[i].limSmeState ==
					eLIM_SME_NORMAL_STATE)
			continue;

		valid_state = false;
		break;
	}

	if (valid_state && (return_fresh_results
				& SIR_BG_SCAN_RETURN_FRESH_RESULTS)) {
		limLog(mac_ctx, LOG1, FL("valid_state: %d, return true"),
			valid_state);
		return true;
	} else {
		limLog(mac_ctx, LOG1, FL("valid_state: %d, return false"),
			valid_state);
		return false;
	}
}

/**
 * __limIsSmeAssocCnfValid()
 *
 *FUNCTION:
 * This function is called by limProcessLmmMessages() upon
 * receiving SME_ASSOC_CNF.
 *
 *LOGIC:
 * Message validity checks are performed in this function
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMeasReq  Pointer to Received ASSOC_CNF message
 * @return true      When received SME_ASSOC_CNF is formatted
 *                   correctly
 *         false     otherwise
 */

inline static tANI_U8
__limIsSmeAssocCnfValid(tpSirSmeAssocCnf pAssocCnf)
{
    if (limIsGroupAddr(pAssocCnf->peerMacAddr))
        return false;
    else
        return true;
} /*** end __limIsSmeAssocCnfValid() ***/


/**
 * __limGetSmeJoinReqSizeForAlloc()
 *
 *FUNCTION:
 * This function is called in various places to get IE length
 * from tSirBssDescription structure
 * number being scanned.
 *
 *PARAMS:
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param     pBssDescr
 * @return    Total IE length
 */

static tANI_U16
__limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf)
{
    tANI_U16 len = 0;

    if (!pBuf)
        return len;

    pBuf += sizeof(tANI_U16);
    len = limGetU16( pBuf );
    return (len + sizeof( tANI_U16 ));
} /*** end __limGetSmeJoinReqSizeForAlloc() ***/


/**----------------------------------------------------------------
\fn     __limIsDeferedMsgForLearn

\brief  Has role only if 11h is enabled. Not used on STA side.
        Defers the message if SME is in learn state and brings
        the LIM back to normal mode.

\param  pMac
\param  pMsg - Pointer to message posted from SME to LIM.
\return TRUE - If defered
        FALSE - Otherwise
------------------------------------------------------------------*/
static tANI_BOOLEAN
__limIsDeferedMsgForLearn(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    if (limIsSystemInScanState(pMac))
    {
        if (limDeferMsg(pMac, pMsg) != TX_SUCCESS)
        {
            PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d"), pMsg->type);)
            return eANI_BOOLEAN_FALSE;
        }
        PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d"),
                                                                 pMsg->type);)

        /** Send finish scan req to HAL only if LIM is not waiting for any response
         * from HAL like init scan rsp, start scan rsp etc.
         */
        if (GET_LIM_PROCESS_DEFD_MESGS(pMac))
        {
            //Set the resume channel to Any valid channel (invalid).
            //This will instruct HAL to set it to any previous valid channel.
            peSetResumeChannel(pMac, 0, 0);
            limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE);
        }

        return eANI_BOOLEAN_TRUE;
    }
    return eANI_BOOLEAN_FALSE;
}

/**----------------------------------------------------------------
\fn     __limIsDeferedMsgForRadar

\brief  Has role only if 11h is enabled. Not used on STA side.
        Defers the message if radar is detected.

\param  pMac
\param  pMsg - Pointer to message posted from SME to LIM.
\return TRUE - If defered
        FALSE - Otherwise
------------------------------------------------------------------*/
static tANI_BOOLEAN
__limIsDeferedMsgForRadar(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    /** fRadarDetCurOperChan will be set only if we detect radar in current
     * operating channel and System Role == AP ROLE */
    //TODO: Need to take care radar detection.
    //if (LIM_IS_RADAR_DETECTED(pMac))
    if( 0 )
    {
        if (limDeferMsg(pMac, pMsg) != TX_SUCCESS)
        {
            PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d"), pMsg->type);)
            return eANI_BOOLEAN_FALSE;
        }
        PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d"),
                                                                 pMsg->type);)
        return eANI_BOOLEAN_TRUE;
    }
    return eANI_BOOLEAN_FALSE;
}


/**
 * __limProcessSmeStartReq()
 *
 *FUNCTION:
 * This function is called to process SME_START_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirResultCodes  retCode = eSIR_SME_SUCCESS;
    tANI_U8          smesessionId;
    tANI_U16         smetransactionId;


   PELOG1(limLog(pMac, LOG1, FL("Received START_REQ"));)

    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);

    if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)
    {
        pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE;

        MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState));

        /// By default do not return after first scan match
        pMac->lim.gLimReturnAfterFirstMatch = 0;

        /// By default return unique scan results
        pMac->lim.gLimReturnUniqueResults = true;
        pMac->lim.gLimSmeScanResultLength = 0;
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
        pMac->lim.gLimSmeLfrScanResultLength = 0;
#endif

        if (((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd)
        {
            /*
                     * Need to indicate new BSSs found during background scanning to
                     * host. Update this parameter at CFG
                     */
            if (cfgSetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, ((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd)
                != eSIR_SUCCESS)
            {
                limLog(pMac, LOGP, FL("could not set NEIGHBOR_BSS_IND at CFG"));
                retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
            }
        }
    }
    else
    {
        /**
         * Should not have received eWNI_SME_START_REQ in states
         * other than OFFLINE. Return response to host and
         * log error
         */
        limLog(pMac, LOGE, FL("Invalid SME_START_REQ received in SME state %X"),pMac->lim.gLimSmeState );
        retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
    }
    limSendSmeRsp(pMac, eWNI_SME_START_RSP, retCode,smesessionId,smetransactionId);
} /*** end __limProcessSmeStartReq() ***/


/** -------------------------------------------------------------
\fn __limProcessSmeSysReadyInd
\brief handles the notification from HDD. PE just forwards this message to HAL.
\param   tpAniSirGlobal pMac
\param   tANI_U32* pMsgBuf
\return  TRUE-Posting to HAL failed, so PE will consume the buffer.
\        FALSE-Posting to HAL successful, so HAL will consume the buffer.
  -------------------------------------------------------------*/
static tANI_BOOLEAN
__limProcessSmeSysReadyInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirMsgQ msg;

    msg.type = WDA_SYS_READY_IND;
    msg.reserved = 0;
    msg.bodyptr =  pMsgBuf;
    msg.bodyval = 0;

    if (ANI_DRIVER_TYPE(pMac) != eDRIVER_TYPE_MFG) {
        peRegisterTLHandle(pMac);
    }
    PELOGW(limLog(pMac, LOGW, FL("sending WDA_SYS_READY_IND msg to HAL"));)
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

    if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
    {
        limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed"));
        return eANI_BOOLEAN_TRUE;
    }
    return eANI_BOOLEAN_FALSE;
}

#ifdef WLAN_FEATURE_11AC

tANI_U32 limGetCenterChannel(tpAniSirGlobal pMac,tANI_U8 primarychanNum,ePhyChanBondState secondaryChanOffset, tANI_U8 chanWidth)
{
    if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
    {
        switch(secondaryChanOffset)
        {
            case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
                return primarychanNum;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
               return primarychanNum + 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
               return primarychanNum - 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
               return primarychanNum + 6;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
               return primarychanNum + 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
               return primarychanNum - 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
               return primarychanNum - 6;
            default :
               return eSIR_CFG_INVALID_ID;
        }
    }
    else if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ)
    {
        switch(secondaryChanOffset)
        {
            case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
                return primarychanNum + 2;
            case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
                return primarychanNum - 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
                return primarychanNum;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
               return primarychanNum + 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
               return primarychanNum - 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
               return primarychanNum + 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
               return primarychanNum - 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
               return primarychanNum + 2;
            case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
               return primarychanNum - 2;
            default :
               return eSIR_CFG_INVALID_ID;
        }
    }
    return primarychanNum;
}

#endif
/**
 * __limHandleSmeStartBssRequest()
 *
 *FUNCTION:
 * This function is called to process SME_START_BSS_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U16                size;
    tANI_U32                val = 0;
    tSirRetStatus           retStatus;
    tSirMacChanNum          channelNumber;
    tLimMlmStartReq         *pMlmStartReq = NULL;
    tpSirSmeStartBssReq     pSmeStartBssReq = NULL;
    tSirResultCodes         retCode = eSIR_SME_SUCCESS;
    tANI_U32                autoGenBssId = FALSE;           //Flag Used in case of IBSS to Auto generate BSSID.
    tANI_U8                 sessionId;
    tpPESession             psessionEntry = NULL;
    tANI_U8                 smesessionId;
    tANI_U16                smetransactionId;
    struct vdev_type_nss    *vdev_type_nss;

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    //Since the session is not created yet, sending NULL. The response should have the correct state.
    limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_REQ_EVENT, NULL, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT

    PELOG1(limLog(pMac, LOG1, FL("Received START_BSS_REQ"));)

    /* Global Sme state and mlm states are not defined yet, for BT-AMP Suppoprt . TO BE DONE */
    if ( (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
         (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE))
    {
        size = sizeof(tSirSmeStartBssReq) + SIR_MAC_MAX_IE_LENGTH;

        pSmeStartBssReq = vos_mem_malloc(size);
        if ( NULL == pSmeStartBssReq )
        {
            PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for pMac->lim.gpLimStartBssReq"));)
            /// Send failure response to host
            retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
            goto end;
        }

        vos_mem_set((void *)pSmeStartBssReq, size, 0);

        if ((limStartBssReqSerDes(pMac, pSmeStartBssReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
                (!limIsSmeStartBssReqValid(pMac, pSmeStartBssReq)))
        {
            PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ"));)
            retCode = eSIR_SME_INVALID_PARAMETERS;
            goto free;
        }

        /* This is the place where PE is going to create a session.
         * If session is not existed, then create a new session */
        if((psessionEntry = peFindSessionByBssid(pMac,pSmeStartBssReq->bssId,&sessionId)) != NULL)
        {
            limLog(pMac, LOGW, FL("Session Already exists for given BSSID"));
            retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
            psessionEntry = NULL;
            goto free;
        }
        else
        {
            if((psessionEntry = peCreateSession(pMac,
                                                pSmeStartBssReq->bssId,
                                                &sessionId,
                                                pMac->lim.maxStation,
                                                pSmeStartBssReq->bssType)) == NULL)
            {
                limLog(pMac, LOGW, FL("Session Can not be created "));
                retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
                goto free;
            }
        }

        if (VOS_NDI_MODE != pSmeStartBssReq->bssPersona) {
            /* Probe resp add ie */
            limStartBssUpdateAddIEBuffer(pMac,
                &psessionEntry->addIeParams.probeRespData_buff,
                &psessionEntry->addIeParams.probeRespDataLen,
                pSmeStartBssReq->addIeParams.probeRespData_buff,
                pSmeStartBssReq->addIeParams.probeRespDataLen);

            /* Probe Beacon add ie */
            limStartBssUpdateAddIEBuffer(pMac,
                &psessionEntry->addIeParams.probeRespBCNData_buff,
                &psessionEntry->addIeParams.probeRespBCNDataLen,
                pSmeStartBssReq->addIeParams.probeRespBCNData_buff,
                pSmeStartBssReq->addIeParams.probeRespBCNDataLen);

            /* Assoc resp IE */
            limStartBssUpdateAddIEBuffer(pMac,
                &psessionEntry->addIeParams.assocRespData_buff,
                &psessionEntry->addIeParams.assocRespDataLen,
                pSmeStartBssReq->addIeParams.assocRespData_buff,
                pSmeStartBssReq->addIeParams.assocRespDataLen);
        }

        /* Store the session related parameters in newly created session */
        psessionEntry->pLimStartBssReq = pSmeStartBssReq;

        /* Store PE sessionId in session Table  */
        psessionEntry->peSessionId = sessionId;

        /* Store SME session Id in sessionTable */
        psessionEntry->smeSessionId = pSmeStartBssReq->sessionId;

        psessionEntry->transactionId = pSmeStartBssReq->transactionId;

        vos_mem_copy(&(psessionEntry->htConfig), &(pSmeStartBssReq->htConfig),
                     sizeof(psessionEntry->htConfig));

        sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeStartBssReq->selfMacAddr);

        /* Copy SSID to session table */
        vos_mem_copy( (tANI_U8 *)&psessionEntry->ssId,
                     (tANI_U8 *)&pSmeStartBssReq->ssId,
                      (pSmeStartBssReq->ssId.length + 1));

        psessionEntry->bssType = pSmeStartBssReq->bssType;

        psessionEntry->nwType = pSmeStartBssReq->nwType;

        psessionEntry->beaconParams.beaconInterval = pSmeStartBssReq->beaconInterval;

        /* Store the channel number in session Table */
        psessionEntry->currentOperChannel = pSmeStartBssReq->channelId;

        /*Store Persona */
        psessionEntry->pePersona = pSmeStartBssReq->bssPersona;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,FL("PE PERSONA=%d"),
            psessionEntry->pePersona);

        /*Update the phymode*/
        psessionEntry->gLimPhyMode = pSmeStartBssReq->nwType;

        psessionEntry->maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac,
            psessionEntry->currentOperChannel );
        /* Store the dot 11 mode in to the session Table*/
        psessionEntry->dot11mode = pSmeStartBssReq->dot11mode;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
        psessionEntry->cc_switch_mode = pSmeStartBssReq->cc_switch_mode;
#endif
        psessionEntry->htCapability = IS_DOT11_MODE_HT(psessionEntry->dot11mode);
#ifdef WLAN_FEATURE_11AC
        psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode);
        VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO,
            FL("*****psessionEntry->vhtCapability = %d"),psessionEntry->vhtCapability);
#endif

        psessionEntry->txLdpcIniFeatureEnabled =
                                    pSmeStartBssReq->txLdpcIniFeatureEnabled;

#ifdef WLAN_FEATURE_11W
        psessionEntry->limRmfEnabled = pSmeStartBssReq->pmfCapable ? 1 : 0;
        limLog(pMac, LOG1, FL("Session RMF enabled: %d"), psessionEntry->limRmfEnabled);
#endif

        /* Update sub 20MHz channel width */
        psessionEntry->sub20_channelwidth = pSmeStartBssReq->sub20_channelwidth;
        psessionEntry->lim_sub20_channel_switch_bandwidth =
            pSmeStartBssReq->sub20_channelwidth;

        vos_mem_copy((void*)&psessionEntry->rateSet,
            (void*)&pSmeStartBssReq->operationalRateSet,
            sizeof(tSirMacRateSet));
        vos_mem_copy((void*)&psessionEntry->extRateSet,
            (void*)&pSmeStartBssReq->extendedRateSet,
            sizeof(tSirMacRateSet));

        if (IS_5G_CH(psessionEntry->currentOperChannel))
                vdev_type_nss = &pMac->vdev_type_nss_5g;
        else
                vdev_type_nss = &pMac->vdev_type_nss_2g;
        switch(pSmeStartBssReq->bssType)
        {
            case eSIR_INFRA_AP_MODE:
                 psessionEntry->limSystemRole = eLIM_AP_ROLE;
                 psessionEntry->privacy = pSmeStartBssReq->privacy;
                 psessionEntry->fwdWPSPBCProbeReq = pSmeStartBssReq->fwdWPSPBCProbeReq;
                 psessionEntry->authType = pSmeStartBssReq->authType;
                 /* Store the DTIM period */
                 psessionEntry->dtimPeriod = (tANI_U8)pSmeStartBssReq->dtimPeriod;
                 /*Enable/disable UAPSD*/
                 psessionEntry->apUapsdEnable = pSmeStartBssReq->apUapsdEnable;
                 if (psessionEntry->pePersona == VOS_P2P_GO_MODE)
                 {
                     psessionEntry->proxyProbeRspEn = 0;
                     psessionEntry->vdev_nss = vdev_type_nss->p2p_go;
                 }
                 else
                 {
                     /* To detect PBC overlap in SAP WPS mode, Host handles
                      * Probe Requests.
                      */
                     if(SAP_WPS_DISABLED == pSmeStartBssReq->wps_state)
                     {
                         psessionEntry->proxyProbeRspEn = 1;
                     }
                     else
                     {
                         psessionEntry->proxyProbeRspEn = 0;
                     }
                     psessionEntry->vdev_nss = vdev_type_nss->sap;
                 }
                 psessionEntry->ssidHidden = pSmeStartBssReq->ssidHidden;
                 psessionEntry->wps_state = pSmeStartBssReq->wps_state;
                 psessionEntry->sap_dot11mc = pSmeStartBssReq->sap_dot11mc;
                 psessionEntry->vendor_vht_for_24ghz_sap =
                     pSmeStartBssReq->vendor_vht_for_24ghz_sap;
                 limGetShortSlotFromPhyMode(pMac, psessionEntry,
                                            psessionEntry->gLimPhyMode,
                                            &psessionEntry->shortSlotTimeSupported);
                 psessionEntry->isCoalesingInIBSSAllowed =
                                pSmeStartBssReq->isCoalesingInIBSSAllowed;
                 psessionEntry->beacon_tx_rate =
                                pSmeStartBssReq->beacon_tx_rate;
                 break;
            case eSIR_IBSS_MODE:
                 psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
                 limGetShortSlotFromPhyMode(pMac, psessionEntry,
                                            psessionEntry->gLimPhyMode,
                                            &psessionEntry->shortSlotTimeSupported);

                 // initialize to "OPEN". will be updated upon key installation
                 psessionEntry->encryptType = eSIR_ED_NONE;
                 psessionEntry->vdev_nss = vdev_type_nss->ibss;
                 break;

            case eSIR_BTAMP_AP_MODE:
                 psessionEntry->limSystemRole = eLIM_BT_AMP_AP_ROLE;
                 break;

            case eSIR_BTAMP_STA_MODE:
                 psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
                 break;

            case eSIR_NDI_MODE:
                 psessionEntry->limSystemRole = eLIM_NDI_ROLE;
                 break;

            case eSIR_AUTO_MODE:
            default:
                                   //not used anywhere...used in scan function
                 break;
        }
        limLog(pMac, LOG1, FL("persona - %d, nss - %d"),
                        psessionEntry->pePersona, psessionEntry->vdev_nss);
        // BT-AMP: Allocate memory for the array of parsed (Re)Assoc request structure
        if ( (pSmeStartBssReq->bssType == eSIR_BTAMP_AP_MODE)
        || (pSmeStartBssReq->bssType == eSIR_INFRA_AP_MODE)
        )
        {
            psessionEntry->parsedAssocReq = vos_mem_malloc(
                     psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq));
            if ( NULL == psessionEntry->parsedAssocReq )
            {
                limLog(pMac, LOGW, FL("AllocateMemory() failed"));
                retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
                goto free;
            }
            vos_mem_set(psessionEntry->parsedAssocReq,
                    (psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)),
                     0 );
        }

        /*
         * Channel Bonding is not addressd yet for BT-AMP Support.
         * It will be addressed later.
         * Channel number is ignored in NDI start request. Hence allow the
         * session configuration for NDI mode even if channelId is 0.
         */
        channelNumber = pSmeStartBssReq->channelId;
        if (pSmeStartBssReq->channelId)
        {
#ifdef QCA_HT_2040_COEX
            if (pSmeStartBssReq->obssEnabled)
                psessionEntry->htSupportedChannelWidthSet =
                          IS_DOT11_MODE_HT(psessionEntry->dot11mode)  ? 1 : 0;
            else
#endif
                psessionEntry->htSupportedChannelWidthSet =
                                 (pSmeStartBssReq->cbMode > 0)?1:0;
            psessionEntry->htSecondaryChannelOffset = pSmeStartBssReq->cbMode;
            psessionEntry->htRecommendedTxWidthSet =
                                 (psessionEntry->htSecondaryChannelOffset)? 1:0;
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                      FL("cbMode %u"), pSmeStartBssReq->cbMode);
#ifdef WLAN_FEATURE_11AC
            if(psessionEntry->vhtCapability)
            {
                tANI_U32 centerChan;
                tANI_U32 chanWidth;

                chanWidth = pSmeStartBssReq->vht_channel_width;

                VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                                FL("vht_channel_width %u"),
                                pSmeStartBssReq->vht_channel_width);

                if(channelNumber <= RF_CHAN_14 &&
                                chanWidth != eHT_CHANNEL_WIDTH_20MHZ)
                {
                     chanWidth = eHT_CHANNEL_WIDTH_20MHZ;
                     limLog(pMac, LOG1, FL("Setting chanWidth to 20Mhz for"
                                                " channel %d"),channelNumber);
                }

                /*
                 * For Sta+p2p-Go concurrency
                 * vhtTxChannelWidthSet is used for storing p2p-GO channel width
                 *  apChanWidth is used for storing the AP channel width that
                 * the Sta is going to associate.
                 * Initialize the apChanWidth same as p2p-GO channel width this
                 * gets over written once the station joins the AP
                 */
                if(chanWidth == eHT_CHANNEL_WIDTH_20MHZ ||
                                chanWidth == eHT_CHANNEL_WIDTH_40MHZ)
                {
                    psessionEntry->vhtTxChannelWidthSet =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                    psessionEntry->apChanWidth =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                }
                if (chanWidth == eHT_CHANNEL_WIDTH_80MHZ)
                {
                    psessionEntry->vhtTxChannelWidthSet =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
                    psessionEntry->apChanWidth =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;

                    centerChan = limGetCenterChannel( pMac, channelNumber,
                                         pSmeStartBssReq->cbMode,
                                         WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ);
                    if(centerChan != eSIR_CFG_INVALID_ID)
                    {
                        limLog(pMac, LOGW, FL("***Center Channel for "
                                     "80MHZ channel width = %d"),centerChan);
                        psessionEntry->apCenterChan = centerChan;
                        if (cfgSetInt(pMac,
                                      WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1,
                                      centerChan) != eSIR_SUCCESS)
                        {
                            limLog(pMac, LOGP, FL("could not set  "
                                      "WNI_CFG_CHANNEL_BONDING_MODE at CFG"));
                            retCode = eSIR_LOGP_EXCEPTION;
                            goto free;
                        }
                    }
                }

            }
            psessionEntry->htSecondaryChannelOffset = limGetHTCBState(pSmeStartBssReq->cbMode);
#endif
        }
        else if(pSmeStartBssReq->bssType != eSIR_NDI_MODE) {
            limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ"));
            retCode = eSIR_SME_INVALID_PARAMETERS;
            goto free;
        }

        // Delete pre-auth list if any
        limDeletePreAuthList(pMac);

        psessionEntry->htCapability = IS_DOT11_MODE_HT(pSmeStartBssReq->dot11mode);

        /*
         * keep the RSN/WPA IE information in PE Session Entry
         * later will be using this to check when received (Re)Assoc req
         */
        limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac,&pSmeStartBssReq->rsnIE,psessionEntry);

        if (LIM_IS_AP_ROLE(psessionEntry) ||
            LIM_IS_IBSS_ROLE(psessionEntry) ||
            LIM_IS_NDI_ROLE(psessionEntry)) {
            psessionEntry->gLimProtectionControl = pSmeStartBssReq->protEnabled;
            /*
             * each byte will have the following info
             * bit7       bit6    bit5   bit4 bit3   bit2  bit1 bit0
             * reserved reserved RIFS Lsig n-GF ht20 11g 11b
             */
            vos_mem_copy( (void *) &psessionEntry->cfgProtection,
                          (void *) &pSmeStartBssReq->ht_capab,
                          sizeof( tANI_U16 ));
            /* Initialize WPS PBC session link list */
            psessionEntry->pAPWPSPBCSession = NULL;
        }

        /* Prepare and Issue LIM_MLM_START_REQ to MLM */
        pMlmStartReq = vos_mem_malloc(sizeof(tLimMlmStartReq));
        if (NULL == pMlmStartReq) {
            limLog(pMac, LOGP,
                FL("call to AllocateMemory failed for mlmStartReq"));
            retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
            goto free;
        }

        vos_mem_set((void *) pMlmStartReq, sizeof(tLimMlmStartReq), 0);

        /* Copy SSID to the MLM start structure */
        vos_mem_copy( (tANI_U8 *) &pMlmStartReq->ssId,
                          (tANI_U8 *) &pSmeStartBssReq->ssId,
                          pSmeStartBssReq->ssId.length + 1);
        pMlmStartReq->ssidHidden = pSmeStartBssReq->ssidHidden;
        pMlmStartReq->obssProtEnabled = pSmeStartBssReq->obssProtEnabled;


        pMlmStartReq->bssType = psessionEntry->bssType;

        /* Fill PE session Id from the session Table */
        pMlmStartReq->sessionId = psessionEntry->peSessionId;

        if ((pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE) ||
            (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE) ||
            (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE) ||
            (pMlmStartReq->bssType == eSIR_NDI_MODE)) {
            /* Copy the BSSId from sessionTable to mlmStartReq struct */
            sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId);
        } else {
            /* ibss mode */
            pMac->lim.gLimIbssCoalescingHappened = false;

            retStatus = wlan_cfgGetInt(pMac, WNI_CFG_IBSS_AUTO_BSSID,
                                &autoGenBssId);
            if (retStatus != eSIR_SUCCESS) {
                limLog(pMac, LOGP,
                        FL("Could not retrieve Auto Gen BSSID, retStatus=%d"),
                        retStatus);
                retCode = eSIR_LOGP_EXCEPTION;
                goto free;
            }

            if (!autoGenBssId) {
                /* BSSID is not auto generated. Get it from session entry */
                sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId);

                if (pMlmStartReq->bssId[0] & 0x01) {
                    limLog(pMac, LOGE,
                       FL("Autogenerating BSSID for IBSS with group BSSID"));
                   autoGenBssId = TRUE;
                }
            }

            if (autoGenBssId) {
                /*
                 * if BSSID is not any uc id
                 * then use locally generated BSSID.
                 * Autogenerate the BSSID using a random value.
                 */

                limGetRandomBssid( pMac, pMlmStartReq->bssId);
                pMlmStartReq->bssId[0]= 0x02;

                /* Copy randomly generated BSSID to the session Table */
                sirCopyMacAddr(psessionEntry->bssId,pMlmStartReq->bssId);
            }
        }
        /* store the channel num in mlmstart req structure */
        pMlmStartReq->channelNumber = psessionEntry->currentOperChannel;
        pMlmStartReq->cbMode = pSmeStartBssReq->cbMode;
        pMlmStartReq->beaconPeriod = psessionEntry->beaconParams.beaconInterval;

        if (LIM_IS_AP_ROLE(psessionEntry)) {
            pMlmStartReq->dtimPeriod = psessionEntry->dtimPeriod;
            pMlmStartReq->wps_state = psessionEntry->wps_state;
        } else {
            if (wlan_cfgGetInt(pMac, WNI_CFG_DTIM_PERIOD, &val) != eSIR_SUCCESS)
                limLog(pMac, LOGP, FL("could not retrieve DTIM Period"));
            pMlmStartReq->dtimPeriod = (tANI_U8)val;
        }

        if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_PERIOD, &val) != eSIR_SUCCESS)
            limLog(pMac, LOGP, FL("could not retrieve Beacon interval"));
        pMlmStartReq->cfParamSet.cfpPeriod = (tANI_U8)val;

        if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, &val) != eSIR_SUCCESS)
            limLog(pMac, LOGP, FL("could not retrieve CFPMaxDuration"));
        pMlmStartReq->cfParamSet.cfpMaxDuration = (tANI_U16) val;

        //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context.
        vos_mem_copy((void*)&pMlmStartReq->rateSet, (void*)&psessionEntry->rateSet,
                       sizeof(tSirMacRateSet));

        // Now populate the 11n related parameters
        pMlmStartReq->nwType    = psessionEntry->nwType;
        pMlmStartReq->htCapable = psessionEntry->htCapability;
        //
        // FIXME_GEN4 - Determine the appropriate defaults...
        //
        pMlmStartReq->htOperMode        = pMac->lim.gHTOperMode;
        pMlmStartReq->dualCTSProtection = pMac->lim.gHTDualCTSProtection; // Unused
        pMlmStartReq->txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet;

        psessionEntry->limRFBand = limGetRFBand(channelNumber);

        // Initialize 11h Enable Flag
        psessionEntry->lim11hEnable = 0;
        if (pMlmStartReq->bssType != eSIR_IBSS_MODE) {
            if (CHAN_HOP_ALL_BANDS_ENABLE ||
                SIR_BAND_5_GHZ == psessionEntry->limRFBand) {
                if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) !=
                    eSIR_SUCCESS)
                        limLog(pMac, LOGP,
                               FL("Fail to get WNI_CFG_11H_ENABLED "));
                psessionEntry->lim11hEnable = val;

                if (psessionEntry->lim11hEnable &&
                    (eSIR_INFRA_AP_MODE == pMlmStartReq->bssType)) {
                        if (wlan_cfgGetInt(pMac, WNI_CFG_DFS_MASTER_ENABLED,
                                           &val) != eSIR_SUCCESS)
                        limLog(pMac, LOGE,
                               FL("Fail to get WNI_CFG_DFS_MASTER_ENABLED"));
                    psessionEntry->lim11hEnable = val;
                }
            }
        }

        if (!psessionEntry->lim11hEnable)
        {
            if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) != eSIR_SUCCESS)
                limLog(pMac, LOGE, FL
                      ("Fail to set value for WNI_CFG_LOCAL_POWER_CONSTRAINT"));
        }

        pMlmStartReq->beacon_tx_rate = psessionEntry->beacon_tx_rate;

        psessionEntry ->limPrevSmeState = psessionEntry->limSmeState;
        psessionEntry ->limSmeState     =  eLIM_SME_WT_START_BSS_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry ->limSmeState));

        limPostMlmMessage(pMac, LIM_MLM_START_REQ, (tANI_U32 *) pMlmStartReq);
        return;
    }
    else
    {

        limLog(pMac, LOGE, FL("Received unexpected START_BSS_REQ, in state %X"),pMac->lim.gLimSmeState);
        retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
        goto end;
    } // if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)

free:
    if ((psessionEntry != NULL) &&
        (psessionEntry->pLimStartBssReq == pSmeStartBssReq))
    {
        psessionEntry->pLimStartBssReq = NULL;
    }
    vos_mem_free( pSmeStartBssReq);
    vos_mem_free( pMlmStartReq);

end:

    /* This routine should return the sme sessionId and SME transaction Id */
    limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId);

    if(NULL != psessionEntry)
    {
        peDeleteSession(pMac,psessionEntry);
        psessionEntry = NULL;
    }
    limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP, retCode,psessionEntry,smesessionId,smetransactionId);
} /*** end __limHandleSmeStartBssRequest() ***/


/**--------------------------------------------------------------
\fn     __limProcessSmeStartBssReq

\brief  Wrapper for the function __limHandleSmeStartBssRequest
        This message will be defered until softmac come out of
        scan mode or if we have detected radar on the current
        operating channel.
\param  pMac
\param  pMsg

\return TRUE - If we consumed the buffer
        FALSE - If have defered the message.
 ---------------------------------------------------------------*/
static tANI_BOOLEAN
__limProcessSmeStartBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    if (__limIsDeferedMsgForLearn(pMac, pMsg) ||
            __limIsDeferedMsgForRadar(pMac, pMsg))
    {
        /**
         * If message defered, buffer is not consumed yet.
         * So return false
         */
        return eANI_BOOLEAN_FALSE;
    }

    __limHandleSmeStartBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr);
    return eANI_BOOLEAN_TRUE;
}


/**
 *  limGetRandomBssid()
 *
 *  FUNCTION:This function is called to process generate the random number for bssid
 *  This function is called to process SME_SCAN_REQ message
 *  from HDD or upper layer application.
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 * 1. geneartes the unique random number for bssid in ibss
 *
 *  @param  pMac      Pointer to Global MAC structure
 *  @param  *data      Pointer to  bssid  buffer
 *  @return None
 */
void limGetRandomBssid(tpAniSirGlobal pMac, tANI_U8 *data)
{
     tANI_U32 random[2] ;
     random[0] = tx_time_get();
     random[0] |= (random[0] << 15) ;
     random[1] = random[0] >> 1;
     vos_mem_copy( data, (tANI_U8*)random, sizeof(tSirMacAddr));
}

static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac,
        tpSirSmeScanReq pScanReq)
{
    tSirScanOffloadReq *pScanOffloadReq;
    tANI_U8 *p;
    tANI_U8 *ht_cap_ie;
    tSirMsgQ msg;
    tANI_U16 i, len;
    tANI_U16  ht_cap_len = 0, addn_ie_len = 0;
#ifdef WLAN_FEATURE_11AC
    tANI_U8 *vht_cap_ie;
    tANI_U16 vht_cap_len = 0;
#endif /* WLAN_FEATURE_11AC */
    uint8_t *vendor_tpc_ie;
    tSirRetStatus status, rc = eSIR_SUCCESS;
    tDot11fIEExtCap extracted_extcap = {0};
    bool extcap_present = true;
    uint32_t lim_11h_enable = WNI_CFG_11H_ENABLED_STADEF;

    wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &lim_11h_enable);


    pMac->lim.fOffloadScanPending = 0;
    pMac->lim.fOffloadScanP2PSearch = 0;

    if (pScanReq->uIEFieldLen) {
        status = lim_strip_extcap_update_struct(pMac,
                     (uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
                     &pScanReq->uIEFieldLen, &extracted_extcap);

        if (eSIR_SUCCESS != status) {
            extcap_present = false;
            limLog(pMac, LOG1, FL("Unable to Strip ExtCap IE from Scan Req"));
        }

        if (extcap_present) {
            limLog(pMac, LOG1, FL("Extcap was part of SCAN IE - Updating FW"));
            lim_send_ext_cap_ie(pMac, pScanReq->sessionId,
                                &extracted_extcap, true);
        }
    } else {
        limLog(pMac, LOG1, FL("No IEs in the scan request from supplicant"));
    }

    /* The tSirScanOffloadReq will reserve the space for first channel,
       so allocate the memory for (numChannels - 1) and uIEFieldLen */
    len = sizeof(tSirScanOffloadReq) + (pScanReq->channelList.numChannels - 1) +
        pScanReq->uIEFieldLen + pScanReq->oui_field_len;

    if (!pMac->per_band_chainmask_supp) {
        if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
            limLog(pMac, LOG1,
                   FL("Adding HT Caps IE since dot11mode=%d"),
                   pScanReq->dot11mode);
            ht_cap_len = 2 + sizeof(tHtCaps); /* 2 bytes for EID and Length */
            len += ht_cap_len;
            addn_ie_len += ht_cap_len;
        }

#ifdef WLAN_FEATURE_11AC
        if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
            limLog(pMac, LOG1,
                   FL("Adding VHT Caps IE since dot11mode=%d"),
                pScanReq->dot11mode);
            /* 2 bytes for EID and Length */
            vht_cap_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
                              sizeof(tSirVhtMcsInfo);
            len += vht_cap_len;
            addn_ie_len += vht_cap_len;
        }
#endif /* WLAN_FEATURE_11AC */
    }

    if (lim_11h_enable) {
            addn_ie_len += DOT11F_IE_WFATPC_MAX_LEN + 2;
            len += DOT11F_IE_WFATPC_MAX_LEN + 2;
    }

    pScanOffloadReq = vos_mem_malloc(len);
    if ( NULL == pScanOffloadReq )
    {
        limLog(pMac, LOGE,
                FL("AllocateMemory failed for pScanOffloadReq"));
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_set( (tANI_U8 *) pScanOffloadReq, len, 0);

    msg.type = WDA_START_SCAN_OFFLOAD_REQ;
    msg.bodyptr = pScanOffloadReq;
    msg.bodyval = 0;

    vos_mem_copy((tANI_U8 *) pScanOffloadReq->bssId,
            (tANI_U8*) pScanReq->bssId,
            sizeof(tSirMacAddr));

    if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID)
    {
        limLog(pMac, LOGE,
                FL("Invalid value (%d) for numSsid"), SIR_SCAN_MAX_NUM_SSID);
        vos_mem_free (pScanOffloadReq);
        return eHAL_STATUS_FAILURE;
    }

    pScanOffloadReq->numSsid = pScanReq->numSsid;
    for (i = 0; i < pScanOffloadReq->numSsid; i++)
    {
        pScanOffloadReq->ssId[i].length = pScanReq->ssId[i].length;
        vos_mem_copy((tANI_U8 *) pScanOffloadReq->ssId[i].ssId,
                (tANI_U8 *) pScanReq->ssId[i].ssId,
                pScanOffloadReq->ssId[i].length);
    }

    pScanOffloadReq->hiddenSsid = pScanReq->hiddenSsid;
    vos_mem_copy((tANI_U8 *) pScanOffloadReq->selfMacAddr,
            (tANI_U8 *) pScanReq->selfMacAddr,
            sizeof(tSirMacAddr));
    pScanOffloadReq->bssType = pScanReq->bssType;
    pScanOffloadReq->dot11mode = pScanReq->dot11mode;
    pScanOffloadReq->scanType = pScanReq->scanType;
    pScanOffloadReq->minChannelTime = pScanReq->minChannelTime;
    pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime;
    pScanOffloadReq->restTime= pScanReq->restTime;
    pScanOffloadReq->min_rest_time= pScanReq->min_rest_time;
    pScanOffloadReq->idle_time= pScanReq->idle_time;

    for (i = 0; i < pMac->lim.maxBssId; i++) {
        tpPESession session_entry = peFindSessionBySessionId(pMac,i);
        if (session_entry &&
            (eLIM_MLM_LINK_ESTABLISHED_STATE == session_entry->limMlmState) &&
            (session_entry->beaconParams.beaconInterval
                                      < BEACON_INTERVAL_THRESHOLD)) {
            pScanOffloadReq->burst_scan_duration = STA_BURST_SCAN_DURATION;
            break;
        }
    }
    /* for normal scan, the value for p2pScanType should be 0
       always */
    if (pScanReq->p2pSearch)
        pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_SEARCH;

    pScanOffloadReq->sessionId = pScanReq->sessionId;

    if (pScanOffloadReq->sessionId >= pMac->lim.maxBssId)
        limLog(pMac, LOGE, FL("Invalid pe sessionID : %d"),
                           pScanOffloadReq->sessionId);

    pScanOffloadReq->channelList.numChannels =
        pScanReq->channelList.numChannels;
    p = &(pScanOffloadReq->channelList.channelNumber[0]);
    for (i = 0; i < pScanOffloadReq->channelList.numChannels; i++)
        p[i] = pScanReq->channelList.channelNumber[i];

    pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen;
    pScanOffloadReq->uIEFieldOffset = len - addn_ie_len -
                                      pScanOffloadReq->uIEFieldLen -
                                      pScanReq->oui_field_len;
    vos_mem_copy(
            (tANI_U8 *) pScanOffloadReq + pScanOffloadReq->uIEFieldOffset,
            (tANI_U8 *) pScanReq + pScanReq->uIEFieldOffset,
            pScanReq->uIEFieldLen);

    if (!pMac->per_band_chainmask_supp) {
        /* Copy HT Capability info if dot11mode is HT */
        if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
            /* Populate EID and Length field here */
            ht_cap_ie = (tANI_U8 *) pScanOffloadReq +
                                pScanOffloadReq->uIEFieldOffset +
                                pScanOffloadReq->uIEFieldLen;
            vos_mem_set(ht_cap_ie, ht_cap_len, 0);
            *ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID;
            *(ht_cap_ie + 1) =  ht_cap_len - 2;
            lim_set_ht_caps(pMac, NULL, ht_cap_ie, ht_cap_len);
            pScanOffloadReq->uIEFieldLen += ht_cap_len;
        }

#ifdef WLAN_FEATURE_11AC
        /* Copy VHT Capability info if dot11mode is VHT Capable */
        if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
            /* Populate EID and Length field here */
            vht_cap_ie = (tANI_U8 *) pScanOffloadReq +
                                 pScanOffloadReq->uIEFieldOffset +
                                 pScanOffloadReq->uIEFieldLen;
            vos_mem_set(vht_cap_ie, vht_cap_len, 0);
            *vht_cap_ie = SIR_MAC_VHT_CAPABILITIES_EID;
            *(vht_cap_ie + 1) =  vht_cap_len - 2;
            lim_set_vht_caps(pMac, NULL, vht_cap_ie, vht_cap_len);
            pScanOffloadReq->uIEFieldLen += vht_cap_len;
        }
#endif /* WLAN_FEATURE_11AC */
    }

    if (lim_11h_enable) {
            tDot11fIEWFATPC wfa_tpc;
            vendor_tpc_ie = (uint8_t *) pScanOffloadReq +
                                 pScanOffloadReq->uIEFieldOffset +
                                 pScanOffloadReq->uIEFieldLen;
            PopulateDot11fWFATPC(pMac, &wfa_tpc,
                                 rrmGetMgmtTxPower(pMac, NULL), 0);
            vendor_tpc_ie[0] = DOT11F_EID_WFATPC;
            vendor_tpc_ie[1] = DOT11F_IE_WFATPC_MAX_LEN;
            vos_mem_copy(&vendor_tpc_ie[2], SIR_MAC_WFA_TPC_OUI,
                                 SIR_MAC_WFA_TPC_OUI_SIZE);
            vos_mem_copy(&vendor_tpc_ie[SIR_MAC_WFA_TPC_OUI_SIZE + 2],
                                 ((uint8_t *)&wfa_tpc) + 1,
                                  DOT11F_IE_WFATPC_MAX_LEN
                                  - SIR_MAC_WFA_TPC_OUI_SIZE);
            pScanOffloadReq->uIEFieldLen += DOT11F_IE_WFATPC_MAX_LEN + 2;
    }

    pScanOffloadReq->enable_scan_randomization =
                                           pScanReq->enable_scan_randomization;
    if (pScanOffloadReq->enable_scan_randomization) {
        vos_mem_copy(pScanOffloadReq->mac_addr, pScanReq->mac_addr,
                     VOS_MAC_ADDR_SIZE);
        vos_mem_copy(pScanOffloadReq->mac_addr_mask, pScanReq->mac_addr_mask,
                     VOS_MAC_ADDR_SIZE);
    }

    pScanOffloadReq->oui_field_len = pScanReq->oui_field_len;
    pScanOffloadReq->num_vendor_oui = pScanReq->num_vendor_oui;
    pScanOffloadReq->ie_whitelist = pScanReq->ie_whitelist;
    if (pScanOffloadReq->ie_whitelist)
        vos_mem_copy(pScanOffloadReq->probe_req_ie_bitmap,
                     pScanReq->probe_req_ie_bitmap,
                     PROBE_REQ_BITMAP_LEN * sizeof(uint32_t));
    pScanOffloadReq->oui_field_offset = sizeof(tSirScanOffloadReq) +
                               (pScanOffloadReq->channelList.numChannels - 1) +
                               pScanOffloadReq->uIEFieldLen;
    if (pScanOffloadReq->num_vendor_oui != 0) {
        vos_mem_copy(
            (tANI_U8 *) pScanOffloadReq + pScanOffloadReq->oui_field_offset,
            (uint8_t *) pScanReq + pScanReq->oui_field_offset,
            pScanReq->oui_field_len);
    }

    rc = wdaPostCtrlMsg(pMac, &msg);
    if (rc != eSIR_SUCCESS)
    {
        limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure"));
        vos_mem_free(pScanOffloadReq);
        return eHAL_STATUS_FAILURE;
    }

    pMac->lim.fOffloadScanPending = 1;
    if (pScanReq->p2pSearch)
        pMac->lim.fOffloadScanP2PSearch = 1;
    return eHAL_STATUS_SUCCESS;
}

/**
 * __limProcessSmeScanReq()
 *
 *FUNCTION:
 * This function is called to process SME_SCAN_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 * 1. Periodic scanning should be requesting to return unique
 *    scan results.
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U32            len;
    tLimMlmScanReq      *pMlmScanReq;
    tpSirSmeScanReq     pScanReq;
    tANI_U8             i = 0;

#ifdef FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_REQ_EVENT, NULL,
                       eSIR_SUCCESS, eSIR_SUCCESS);
#endif

    pScanReq = (tpSirSmeScanReq) pMsgBuf;
    limLog(pMac, LOG1,FL("SME SCAN REQ numChan %d min %d max %d IELen %d"
                         "first %d fresh %d unique %d type %s (%d)"
                         " mode %s (%d)rsp %d"),
           pScanReq->channelList.numChannels,
           pScanReq->minChannelTime,
           pScanReq->maxChannelTime,
           pScanReq->uIEFieldLen,
           pScanReq->returnAfterFirstMatch,
           pScanReq->returnFreshResults,
           pScanReq->returnUniqueResults,
           lim_ScanTypetoString(pScanReq->scanType),
           pScanReq->scanType,
           lim_BackgroundScanModetoString(pScanReq->backgroundScanMode),
           pScanReq->backgroundScanMode, pMac->lim.gLimRspReqd ? 1 : 0);


    /* Since scan req always requires a response, we will overwrite response required here.
     * This is added esp to take care of the condition where in p2p go case, we hold the scan req and
     * insert single NOA. We send the held scan request to FW later on getting start NOA ind from FW so
     * we lose state of the gLimRspReqd flag for the scan req if any other request comes by then.
     * e.g. While unit testing, we found when insert single NOA is done, we see a get stats request which turns the flag
     * gLimRspReqd to FALSE; now when we actually start the saved scan req for init scan after getting
     * NOA started, the gLimRspReqd being a global flag is showing FALSE instead of TRUE value for
     * this saved scan req. Since all scan reqs coming to lim require a response, there is no harm in setting
     * the global flag gLimRspReqd to TRUE here.
     */
     pMac->lim.gLimRspReqd = TRUE;

    /*copy the Self MAC address from SmeReq to the globalplace, used for sending probe req*/
    sirCopyMacAddr(pMac->lim.gSelfMacAddr,  pScanReq->selfMacAddr);

   /* This routine should return the sme sessionId and SME transaction Id */

    if (!limIsSmeScanReqValid(pMac, pScanReq))
    {
        limLog(pMac, LOGE, FL("Received SME_SCAN_REQ with invalid parameters"));

        if (pMac->lim.gLimRspReqd)
        {
            pMac->lim.gLimRspReqd = false;

            limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId);

        } // if (pMac->lim.gLimRspReqd)

        return;
    }

    /*
     * if scan is disabled then return as invalid scan request.
     * if scan in power save is disabled, and system is in power save mode,
     * then ignore scan request.
     */
    if((pMac->lim.fScanDisabled) ||
       (!pMac->psOffloadEnabled &&
       !pMac->lim.gScanInPowersave &&
       !limIsSystemInActiveState(pMac)))
    {
        limLog(pMac, LOGE, FL("SCAN is disabled or SCAN in power save"
                           " is disabled and system is in power save."));

        limSendSmeScanRsp(pMac, offsetof(tSirSmeScanRsp,bssDescription[0]), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId);
        return;
    }

    /* Clear P2P scan entries before starting any scan */
    if (pMac->fScanOffload)
        limFlushp2pScanResults(pMac);

    /**
     * If scan request is received in idle, joinFailed
     * states or in link established state (in STA role)
     * or in normal state (in STA-in-IBSS/AP role) with
     * 'return fresh scan results' request from HDD or
     * it is periodic background scanning request,
     * trigger fresh scan request to MLM
     */
  if (__limFreshScanReqd(pMac, pScanReq->returnFreshResults))
  {
      limLog(pMac, LOG1, FL("Fresh scan is required"));

      if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS)
      {
          // Discard previously cached scan results
          limReInitScanResults(pMac);
      }

      pMac->lim.gLim24Band11dScanDone     = 0;
      pMac->lim.gLim50Band11dScanDone     = 0;
      pMac->lim.gLimReturnAfterFirstMatch =
          pScanReq->returnAfterFirstMatch;
      pMac->lim.gLimBackgroundScanMode =
          pScanReq->backgroundScanMode;

      pMac->lim.gLimReturnUniqueResults   =
          ((pScanReq->returnUniqueResults) > 0 ? true : false);

      if (pMac->psOffloadEnabled)
      {
         if ((pMac->lim.gLimBackgroundScanMode != eSIR_ROAMING_SCAN) &&
            (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
         {
            for (i=0;i<pMac->lim.maxBssId;i++)
            {
               tpPESession psessionEntry = peFindSessionBySessionId(pMac,i);
               if (psessionEntry && psessionEntry->valid &&
                  (eLIM_MLM_LINK_ESTABLISHED_STATE ==
                          psessionEntry->limMlmState) &&
                  (psessionEntry->pmmOffloadInfo.psstate == PMM_FULL_POWER))
               {
                  limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
               }
            }
         }
      }
      /* De-activate Heartbeat timers for connected sessions while
       * scan is in progress if the system is in Active mode *
       * AND it is not a ROAMING ("background") scan */
      else if (((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) ||
                  (ePMM_STATE_READY == pMac->pmm.gPmmState)) &&
              (pScanReq->backgroundScanMode != eSIR_ROAMING_SCAN ) &&
              (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
      {
          for(i=0;i<pMac->lim.maxBssId;i++)
          {
              if((peFindSessionBySessionId(pMac,i) != NULL) &&
                      (pMac->lim.gpSession[i].valid == TRUE) &&
                      (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState))
              {
                  limHeartBeatDeactivateAndChangeTimer(pMac, peFindSessionBySessionId(pMac,i));
              }
          }
      }

      if (pMac->fScanOffload)
      {
          if (eHAL_STATUS_SUCCESS !=
                  limSendHalStartScanOffloadReq(pMac, pScanReq))
          {
              limLog(pMac, LOGE, FL("Couldn't send Offload scan request"));
              limSendSmeScanRsp(pMac,
                      offsetof(tSirSmeScanRsp, bssDescription[0]),
                      eSIR_SME_INVALID_PARAMETERS,
                      pScanReq->sessionId,
                      pScanReq->transactionId);
              return;
          }
      }
      else
      {

          /*Change Global SME state  */
          /* Store the previous SME state */
          limLog(pMac, LOG1, FL("Non Offload SCAN request "));
          pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
          pMac->lim.gLimSmeState = eLIM_SME_WT_SCAN_STATE;
          MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, pScanReq->sessionId, pMac->lim.gLimSmeState));

          if (pScanReq->channelList.numChannels == 0)
          {
              tANI_U32            cfg_len;

              limLog(pMac, LOG1,
                    FL("Scan all channels as Number of channels is 0"));

              // Scan all channels
              len = sizeof(tLimMlmScanReq) +
                  (sizeof( pScanReq->channelList.channelNumber ) * (WNI_CFG_VALID_CHANNEL_LIST_LEN - 1)) +
                  pScanReq->uIEFieldLen;
              pMlmScanReq = vos_mem_malloc(len);
              if ( NULL == pMlmScanReq )
              {
                // Log error
                limLog(pMac, LOGP,
                       FL("call to AllocateMemory failed for mlmScanReq (%d)"), len);

                  return;
               }

              // Initialize this buffer
              vos_mem_set( (tANI_U8 *) pMlmScanReq, len, 0 );

              cfg_len = WNI_CFG_VALID_CHANNEL_LIST_LEN;
              if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
                          pMlmScanReq->channelList.channelNumber,
                          &cfg_len) != eSIR_SUCCESS)
              {
                  /**
                   * Could not get Valid channel list from CFG.
                   * Log error.
                   */
                  limLog(pMac, LOGP,
                          FL("could not retrieve Valid channel list"));
              }
              pMlmScanReq->channelList.numChannels = (tANI_U8) cfg_len;
          }
          else
          {
              len = sizeof( tLimMlmScanReq ) - sizeof( pScanReq->channelList.channelNumber ) +
                  (sizeof( pScanReq->channelList.channelNumber ) * pScanReq->channelList.numChannels ) +
                  pScanReq->uIEFieldLen;

              pMlmScanReq = vos_mem_malloc(len);
              if ( NULL == pMlmScanReq )
              {
                // Log error
                limLog(pMac, LOGP,
                    FL("call to AllocateMemory failed for mlmScanReq(%d)"), len);

                  return;
               }

              // Initialize this buffer
              vos_mem_set( (tANI_U8 *) pMlmScanReq, len, 0);
              if (pScanReq->channelList.numChannels <= SIR_ESE_MAX_MEAS_IE_REQS)
              {
                  pMlmScanReq->channelList.numChannels =
                           pScanReq->channelList.numChannels;
              }
              else
              {
                  limLog(pMac, LOGE,
                    FL("numChannels is more than the size(%d)"),
                    pScanReq->channelList.numChannels);
                  pMlmScanReq->channelList.numChannels =
                      SIR_ESE_MAX_MEAS_IE_REQS;
              }

              vos_mem_copy( pMlmScanReq->channelList.channelNumber,
                          pScanReq->channelList.channelNumber,
                          pMlmScanReq->channelList.numChannels);
        }

         pMlmScanReq->uIEFieldLen = pScanReq->uIEFieldLen;
         pMlmScanReq->uIEFieldOffset = len - pScanReq->uIEFieldLen;
         if(pScanReq->uIEFieldLen)
         {
            vos_mem_copy( (tANI_U8 *)pMlmScanReq+ pMlmScanReq->uIEFieldOffset,
                          (tANI_U8 *)pScanReq+(pScanReq->uIEFieldOffset),
                          pScanReq->uIEFieldLen);
         }

         pMlmScanReq->bssType = pScanReq->bssType;
         vos_mem_copy( pMlmScanReq->bssId,
                      pScanReq->bssId,
                      sizeof(tSirMacAddr));
         pMlmScanReq->numSsid = pScanReq->numSsid;
         pMlmScanReq->sessionId = pScanReq->sessionId;

         i = 0;
         while (i < pMlmScanReq->numSsid)
         {
            vos_mem_copy( (tANI_U8 *) &pMlmScanReq->ssId[i],
                      (tANI_U8 *) &pScanReq->ssId[i],
                      pScanReq->ssId[i].length + 1);

              i++;
          }


          pMlmScanReq->scanType = pScanReq->scanType;
          pMlmScanReq->backgroundScanMode = pScanReq->backgroundScanMode;
          pMlmScanReq->minChannelTime = pScanReq->minChannelTime;
          pMlmScanReq->maxChannelTime = pScanReq->maxChannelTime;
          pMlmScanReq->minChannelTimeBtc = pScanReq->minChannelTimeBtc;
          pMlmScanReq->maxChannelTimeBtc = pScanReq->maxChannelTimeBtc;
          pMlmScanReq->dot11mode = pScanReq->dot11mode;
          pMlmScanReq->p2pSearch = pScanReq->p2pSearch;

          //Store the smeSessionID and transaction ID for later use.
          pMac->lim.gSmeSessionId = pScanReq->sessionId;
          pMac->lim.gTransactionId = pScanReq->transactionId;

          // Issue LIM_MLM_SCAN_REQ to MLM
          limLog(pMac, LOG1, FL("Issue Scan request command to MLM "));
          limPostMlmMessage(pMac, LIM_MLM_SCAN_REQ, (tANI_U32 *) pMlmScanReq);
      }
  } // if ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ...

    else
    {
        /// In all other cases return 'cached' scan results
        if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults)
        {
            tANI_U16    scanRspLen = sizeof(tSirSmeScanRsp);

            pMac->lim.gLimRspReqd = false;
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
            if (pScanReq->returnFreshResults & SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS)
            {
                pMac->lim.gLimSmeLfrScanResultLength = pMac->lim.gLimMlmLfrScanResultLength;
                limLog(pMac, LOG1,
                   FL("Returned scan results from LFR cache, length = %d"),
                   pMac->lim.gLimSmeLfrScanResultLength);

                if (pMac->lim.gLimSmeLfrScanResultLength == 0)
                {
                   limSendSmeLfrScanRsp(pMac, scanRspLen,
                                         eSIR_SME_SUCCESS,
                                         pScanReq->sessionId,
                                         pScanReq->transactionId);
                }
                else
                {
                    scanRspLen = sizeof(tSirSmeScanRsp) +
                                 pMac->lim.gLimSmeLfrScanResultLength -
                                 sizeof(tSirBssDescription);
                    limSendSmeLfrScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS,
                               pScanReq->sessionId, pScanReq->transactionId);
                }
            }
            else
            {
#endif
                limLog(pMac, LOG1,
                   FL("Returned scan results from normal cache, length = %d"),
                   pMac->lim.gLimSmeScanResultLength);
               if (pMac->lim.gLimSmeScanResultLength == 0)
               {
                  limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS,
                          pScanReq->sessionId, pScanReq->transactionId);
               }
               else
               {
                  scanRspLen = sizeof(tSirSmeScanRsp) +
                               pMac->lim.gLimSmeScanResultLength -
                               sizeof(tSirBssDescription);
                  limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS,
                                  pScanReq->sessionId, pScanReq->transactionId);
               }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
            }
#endif
            limLog(pMac, LOG1, FL("Cached scan results are returned "));

            if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS)
            {
                // Discard previously cached scan results
                limReInitScanResults(pMac);
            }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
            if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_LFR_RESULTS)
            {
                // Discard previously cached scan results
                limReInitLfrScanResults(pMac);
            }
#endif

        } // if (pMac->lim.gLimRspReqd)
    } // else ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ...

#ifdef BACKGROUND_SCAN_ENABLED
    // start background scans if needed
    // There is a bug opened against softmac. Need to enable when the bug is fixed.
    __limBackgroundScanInitiate(pMac);
#endif

} /*** end __limProcessSmeScanReq() ***/

#ifdef FEATURE_OEM_DATA_SUPPORT

static void __limProcessSmeOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirOemDataReq    pOemDataReq;
    tLimMlmOemDataReq* pMlmOemDataReq;

    pOemDataReq = (tpSirOemDataReq) pMsgBuf;

    //post the lim mlm message now
    pMlmOemDataReq = vos_mem_malloc(sizeof(*pMlmOemDataReq));
    if ( NULL == pMlmOemDataReq )
    {
        limLog(pMac, LOGP, FL("AllocateMemory failed for mlmOemDataReq"));
        return;
    }

    pMlmOemDataReq->data = vos_mem_malloc(pOemDataReq->data_len);
    if (!pMlmOemDataReq->data) {
        limLog(pMac, LOGP, FL("memory allocation failed"));
        vos_mem_free(pMlmOemDataReq);
        /* buffer from SME copied, free it now */
        vos_mem_free(pOemDataReq->data);
        return;
    }

    vos_mem_copy( pMlmOemDataReq->selfMacAddr, pOemDataReq->selfMacAddr,
                  sizeof(tSirMacAddr));

    pMlmOemDataReq->data_len = pOemDataReq->data_len;
    vos_mem_copy(pMlmOemDataReq->data, pOemDataReq->data,
                 pOemDataReq->data_len);
    /* buffer from SME copied, free it now */
    vos_mem_free(pOemDataReq->data);

    //Issue LIM_MLM_OEM_DATA_REQ to MLM
    limPostMlmMessage(pMac, LIM_MLM_OEM_DATA_REQ, (tANI_U32*)pMlmOemDataReq);

    return;

} /*** end __limProcessSmeOemDataReq() ***/

#endif //FEATURE_OEM_DATA_SUPPORT

/**
 * __limProcessClearDfsChannelList()
 *
 *FUNCTION:
 *Clear DFS channel list  when country is changed/aquired.
.*This message is sent from SME.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */
static void __limProcessClearDfsChannelList(tpAniSirGlobal pMac,
                                                           tpSirMsgQ pMsg)
{
    vos_mem_set( &pMac->lim.dfschannelList,
                  sizeof(tSirDFSChannelList), 0);
}

#ifdef WLAN_FEATURE_SAE
/**
 * lim_update_sae_config()- This API update SAE session info to csr config
 * from join request.
 * @session: PE session
 * @sme_join_req: pointer to join request
 *
 * Return: None
 */
static void lim_update_sae_config(tpPESession session,
				tpSirSmeJoinReq sme_join_req)
{
	session->sae_pmk_cached = sme_join_req->sae_pmk_cached;

	VOS_TRACE(VOS_MODULE_ID_PE,
		VOS_TRACE_LEVEL_DEBUG,
		FL("pmk_cached %d for BSSID=" MAC_ADDRESS_STR),
		session->sae_pmk_cached,
		MAC_ADDR_ARRAY(sme_join_req->bssDescription.bssId));
}
#else
static inline void lim_update_sae_config(tpPESession session,
				tpSirSmeJoinReq sme_join_req)
{}
#endif

/**
 * __limProcessSmeJoinReq()
 *
 *FUNCTION:
 * This function is called to process SME_JOIN_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */
static void
__limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
  //  tANI_U8             *pBuf;
    //tANI_U32            len;
//    tSirMacAddr         currentBssId;
    tpSirSmeJoinReq     pSmeJoinReq = NULL;
    tLimMlmJoinReq      *pMlmJoinReq;
    tSirResultCodes     retCode = eSIR_SME_SUCCESS;
    tANI_U32            val = 0;
    tANI_U16            nSize;
    tANI_U8             sessionId;
    tpPESession         psessionEntry = NULL;
    tANI_U8             smesessionId = 0;
    tANI_U16            smetransactionId = 0;
    tPowerdBm           localPowerConstraint = 0, regMax = 0;
    tANI_U16            ieLen;
    v_U8_t              *vendorIE;
    struct vdev_type_nss *vdev_type_nss;

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    //Not sending any session, since it is not created yet. The response whould have correct state.
    limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT

   /**
     * Expect Join request in idle state.
     * Reassociate request is expected in link established state.
     */

    /* Global SME and LIM states are not defined yet for BT-AMP Support */
    if(pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE)
    {
        nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8*) pMsgBuf);

        pSmeJoinReq = vos_mem_malloc(nSize);
        if ( NULL == pSmeJoinReq )
        {
            limLog(pMac, LOGP, FL("call to AllocateMemory failed for "
                                  "pSmeJoinReq"));
            retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
            goto end;
        }
        (void) vos_mem_set((void *) pSmeJoinReq, nSize, 0);

        if ((limJoinReqSerDes(pMac, pSmeJoinReq, (tANI_U8 *)pMsgBuf) == eSIR_FAILURE) ||
                (!limIsSmeJoinReqValid(pMac, pSmeJoinReq)))
        {
            /// Received invalid eWNI_SME_JOIN_REQ
            // Log the event
            limLog(pMac, LOGW, FL("SessionId:%d Received SME_JOIN_REQ with invalid data"),
                   pSmeJoinReq->sessionId);
            retCode = eSIR_SME_INVALID_PARAMETERS;
            goto end;
        }

        /*
         * Update the capability here itself as this is used in
         * limExtractAPCapability() below. If not updated issues like not
         * honoring power constraint on 1st association after driver loading
         * might occur.
         */
        lim_update_rrm_capability(pMac, pSmeJoinReq);

        if (pe_find_session_by_sme_session_id(pMac, pSmeJoinReq->sessionId)) {
            limLog(pMac, LOGE,
                 FL("A session already exist for the SME session %d"),
                 pSmeJoinReq->sessionId);
            vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                           WLAN_LOG_INDICATOR_HOST_DRIVER,
                           WLAN_LOG_REASON_STALE_SESSION_FOUND,
                           DUMP_VOS_TRACE);
            retCode = eSIR_SME_REFUSED;
            goto end;
        }

        /* check for the existence of start BSS session  */
        if((psessionEntry = peFindSessionByBssid(pMac,pSmeJoinReq->bssDescription.bssId,&sessionId)) != NULL)
        {
            limLog(pMac, LOGE, FL("Session(%d) Already exists for BSSID: "
            MAC_ADDRESS_STR" in limSmeState = %X"),sessionId,
            MAC_ADDR_ARRAY(pSmeJoinReq->bssDescription.bssId),
            psessionEntry->limSmeState);

            if(psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE &&
               psessionEntry->smeSessionId == pSmeJoinReq->sessionId)
            {
                // Received eWNI_SME_JOIN_REQ for same
                // BSS as currently associated.
                // Log the event and send success
                PELOGW(limLog(pMac, LOGW, FL("SessionId:%d Received SME_JOIN_REQ for currently joined BSS"),
                       sessionId);)
                /// Send Join success response to host
                retCode = eSIR_SME_ALREADY_JOINED_A_BSS;
                psessionEntry = NULL;
                goto end;
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("SME_JOIN_REQ not for"
                                          "currently joined BSS"));)
                retCode = eSIR_SME_REFUSED;
                psessionEntry = NULL;
                goto end;
            }
        }
        else       /* Session Entry does not exist for given BSSId */
        {
            /* Try to Create a new session */
            if((psessionEntry = peCreateSession(pMac,
                    pSmeJoinReq->bssDescription.bssId,
                    &sessionId,
                    pMac->lim.maxStation,
                    eSIR_INFRASTRUCTURE_MODE )) == NULL)
            {
                limLog(pMac, LOGE, FL("Session Can not be created "));
                retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
                goto end;
            }
            else
              limLog(pMac,LOG2,FL("SessionId:%d New session created"),
                     sessionId);
        }
        psessionEntry->max_amsdu_num = pSmeJoinReq->max_amsdu_num;

        /* Store Session related parameters */
        /* Store PE session Id in session Table */
        psessionEntry->peSessionId = sessionId;

        /* store the smejoin req handle in session table */
        psessionEntry->pLimJoinReq = pSmeJoinReq;

        /* Store SME session Id in sessionTable */
        psessionEntry->smeSessionId = pSmeJoinReq->sessionId;

        /* Store SME transaction Id in session Table */
        psessionEntry->transactionId = pSmeJoinReq->transactionId;

        /* Store beaconInterval */
        psessionEntry->beaconParams.beaconInterval = pSmeJoinReq->bssDescription.beaconInterval;

        vos_mem_copy(&(psessionEntry->htConfig), &(pSmeJoinReq->htConfig),
                     sizeof(psessionEntry->htConfig));

        /* Copying of bssId is already done, while creating session */
        sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeJoinReq->selfMacAddr);
        psessionEntry->bssType = pSmeJoinReq->bsstype;

        psessionEntry->statypeForBss = STA_ENTRY_PEER;
        psessionEntry->limWmeEnabled = pSmeJoinReq->isWMEenabled;
        psessionEntry->limQosEnabled = pSmeJoinReq->isQosEnabled;
        psessionEntry->osen_association = pSmeJoinReq->osen_association;
        psessionEntry->wps_registration = pSmeJoinReq->wps_registration;


        /* Store vendor specfic IE for CISCO AP */
        ieLen = GET_IE_LEN_IN_BSS(pSmeJoinReq->bssDescription.length);

        vendorIE = cfg_get_vendor_ie_ptr_from_oui(pMac, SIR_MAC_CISCO_OUI,
                    SIR_MAC_CISCO_OUI_SIZE,
                   ((tANI_U8 *)&pSmeJoinReq->bssDescription.ieFields) , ieLen);

        if (NULL != vendorIE) {
            limLog(pMac, LOG1, FL("Cisco vendor OUI present"));
            psessionEntry->isCiscoVendorAP = TRUE;
        } else {
            psessionEntry->isCiscoVendorAP = FALSE;
        }

        /* Copy the dot 11 mode in to the session table */

        psessionEntry->dot11mode  = pSmeJoinReq->dot11mode;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
        psessionEntry->cc_switch_mode = pSmeJoinReq->cc_switch_mode;
#endif
        psessionEntry->nwType = pSmeJoinReq->bssDescription.nwType;
        psessionEntry->enableAmpduPs = pSmeJoinReq->enableAmpduPs;
        psessionEntry->enableHtSmps = pSmeJoinReq->enableHtSmps;
        psessionEntry->htSmpsvalue = pSmeJoinReq->htSmps;
        /*
         * By default supported NSS 1x1 is set to true
         * and later on updated while determining session
         * supported rates which is the intersection of
         * self and peer rates
         */
        psessionEntry->supported_nss_1x1 = true;

        /*Store Persona */
        psessionEntry->pePersona = pSmeJoinReq->staPersona;
        /* Copy The channel Id to the session Table */
        psessionEntry->currentOperChannel =
                pSmeJoinReq->bssDescription.channelId;
        if (IS_5G_CH(psessionEntry->currentOperChannel))
                vdev_type_nss = &pMac->vdev_type_nss_5g;
        else
                vdev_type_nss = &pMac->vdev_type_nss_2g;
        if (psessionEntry->pePersona == VOS_P2P_CLIENT_MODE)
            psessionEntry->vdev_nss = vdev_type_nss->p2p_cli;
        else
            psessionEntry->vdev_nss = vdev_type_nss->sta;

        limLog(pMac, LOG1,
              FL("persona: %d, nss: %d cbMode: %d enableHtSmps: %d htSmps: %d supported NSS 1x1: %d force_24ghz_in_ht20 %d"),
                        psessionEntry->pePersona,
                        psessionEntry->vdev_nss,
                        pSmeJoinReq->cbMode,
                        psessionEntry->enableHtSmps,
                        psessionEntry->htSmpsvalue,
                        psessionEntry->supported_nss_1x1,
                        pSmeJoinReq->force_24ghz_in_ht20);

#ifdef WLAN_FEATURE_11AC
        psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode);
        if (psessionEntry->vhtCapability )
        {
            if (psessionEntry->pePersona == VOS_STA_MODE)
            {
                    psessionEntry->txBFIniFeatureEnabled = pSmeJoinReq->txBFIniFeatureEnabled;
            }
            else
            {
                    psessionEntry->txBFIniFeatureEnabled = 0;
            }
            psessionEntry->txMuBformee = pSmeJoinReq->txMuBformee;
            psessionEntry->enableVhtpAid = pSmeJoinReq->enableVhtpAid;
            psessionEntry->enableVhtGid = pSmeJoinReq->enableVhtGid;
            if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
                    psessionEntry->txBFIniFeatureEnabled)) {
                    limLog(pMac, LOGE, FL("Could not set WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG"));
                    retCode = eSIR_LOGP_EXCEPTION;
                    goto end;
            }

            if (psessionEntry->txBFIniFeatureEnabled) {
                if (cfgSetInt(pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
                                                       pSmeJoinReq->txBFCsnValue)
                                                             != eSIR_SUCCESS)
                {
                    limLog(pMac, LOGE, FL("could not set "
                     "WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED at CFG"));
                    retCode = eSIR_LOGP_EXCEPTION;
                    goto end;
                }
            }
        }
        limLog(pMac, LOG1,
              FL("vhtCapability: %d txBFIniFeatureEnabled: %d txBFCsnValue: %d txMuBformee: %d"),
                        psessionEntry->vhtCapability,
                        psessionEntry->txBFIniFeatureEnabled,
                        pSmeJoinReq->txBFCsnValue,
                        psessionEntry->txMuBformee);
#endif

        /*Phy mode*/
        psessionEntry->gLimPhyMode = pSmeJoinReq->bssDescription.nwType;
        handleHTCapabilityandHTInfo(pMac, psessionEntry);
        psessionEntry->htSupportedChannelWidthSet = (pSmeJoinReq->cbMode > 0)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes
        psessionEntry->force_24ghz_in_ht20 = pSmeJoinReq->force_24ghz_in_ht20;
        psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet;
        psessionEntry->htSecondaryChannelOffset = pSmeJoinReq->cbMode;

        /* Record if management frames need to be protected */
#ifdef WLAN_FEATURE_11W
        if(eSIR_ED_AES_128_CMAC == pSmeJoinReq->MgmtEncryptionType)
        {
            VOS_STATUS vosStatus;
            psessionEntry->limRmfEnabled = 1;
            /*
             * For STA profile only:
             * init pmf comeback timer and info struct only if PMF connection
             */
            psessionEntry->pmfComebackTimerInfo.pMac = pMac;
            psessionEntry->pmfComebackTimerInfo.sessionID = sessionId;
            vosStatus = vos_timer_init(&psessionEntry->pmfComebackTimer,
                                   VOS_TIMER_TYPE_SW,
                                   limPmfComebackTimerCallback,
                                   (void*)&psessionEntry->pmfComebackTimerInfo);
            if (VOS_STATUS_SUCCESS != vosStatus) {
                limLog(pMac, LOGP,
                       FL("cannot init pmf comeback timer."));
                retCode = eSIR_LOGP_EXCEPTION;
                goto end;
            }
        }
        else
        {
            psessionEntry->limRmfEnabled = 0;
        }
#endif

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
        psessionEntry->rssi =  pSmeJoinReq->bssDescription.rssi;
#endif


        /* Copy the SSID from smejoinreq to session entry  */
        psessionEntry->ssId.length = pSmeJoinReq->ssId.length;
        vos_mem_copy( psessionEntry->ssId.ssId,
                      pSmeJoinReq->ssId.ssId, psessionEntry->ssId.length);

        // Determin 11r or ESE connection based on input from SME
        // which inturn is dependent on the profile the user wants to connect
        // to, So input is coming from supplicant
#ifdef WLAN_FEATURE_VOWIFI_11R
        psessionEntry->is11Rconnection = pSmeJoinReq->is11Rconnection;
#endif
#ifdef FEATURE_WLAN_ESE
        psessionEntry->isESEconnection = pSmeJoinReq->isESEconnection;
#endif
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
        psessionEntry->isFastTransitionEnabled = pSmeJoinReq->isFastTransitionEnabled;
#endif

#ifdef FEATURE_WLAN_LFR
        psessionEntry->isFastRoamIniFeatureEnabled = pSmeJoinReq->isFastRoamIniFeatureEnabled;
#endif
        psessionEntry->txLdpcIniFeatureEnabled = pSmeJoinReq->txLdpcIniFeatureEnabled;
        lim_update_fils_config(psessionEntry, pSmeJoinReq);
        lim_update_sae_config(psessionEntry, pSmeJoinReq);
        if (psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
        {
            psessionEntry->limSystemRole = eLIM_STA_ROLE;
        }
        else if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
        {
            psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
        }
        else
        {
            /* Throw an error and return and make sure to delete the session.*/
            limLog(pMac, LOGE, FL("received SME_JOIN_REQ with invalid"
                                 " bss type %d"), psessionEntry->bssType);
            retCode = eSIR_SME_INVALID_PARAMETERS;
            goto end;
        }

        if (pSmeJoinReq->addIEScan.length)
        {
            vos_mem_copy( &psessionEntry->pLimJoinReq->addIEScan,
                          &pSmeJoinReq->addIEScan, sizeof(tSirAddie));
        }

        if (pSmeJoinReq->addIEAssoc.length)
        {
            vos_mem_copy( &psessionEntry->pLimJoinReq->addIEAssoc,
                          &pSmeJoinReq->addIEAssoc, sizeof(tSirAddie));
        }

        val = sizeof(tLimMlmJoinReq) + psessionEntry->pLimJoinReq->bssDescription.length + 2;
        pMlmJoinReq = vos_mem_malloc(val);
        if ( NULL == pMlmJoinReq )
        {
            limLog(pMac, LOGP, FL("call to AllocateMemory "
                                "failed for mlmJoinReq"));
            retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
            goto end;
        }
        (void) vos_mem_set((void *) pMlmJoinReq, val, 0);

        /* PE SessionId is stored as a part of JoinReq*/
        pMlmJoinReq->sessionId = psessionEntry->peSessionId;

        if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, (tANI_U32 *) &pMlmJoinReq->joinFailureTimeout)
            != eSIR_SUCCESS)
        {
            limLog(pMac, LOGP, FL("could not retrieve JoinFailureTimer value"
                    " setting to default value"));
            pMlmJoinReq->joinFailureTimeout =
                                WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF;
        }
        /* copy operational rate from psessionEntry*/
        vos_mem_copy((void*)&psessionEntry->rateSet, (void*)&pSmeJoinReq->operationalRateSet,
                            sizeof(tSirMacRateSet));
        vos_mem_copy((void*)&psessionEntry->extRateSet, (void*)&pSmeJoinReq->extendedRateSet,
                            sizeof(tSirMacRateSet));
        //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context.
        vos_mem_copy((void*)&pMlmJoinReq->operationalRateSet, (void*)&psessionEntry->rateSet,
                           sizeof(tSirMacRateSet));

        psessionEntry->encryptType = pSmeJoinReq->UCEncryptionType;

        pMlmJoinReq->bssDescription.length = psessionEntry->pLimJoinReq->bssDescription.length;

        vos_mem_copy((tANI_U8 *) &pMlmJoinReq->bssDescription.bssId,
           (tANI_U8 *) &psessionEntry->pLimJoinReq->bssDescription.bssId,
           psessionEntry->pLimJoinReq->bssDescription.length + 2);

        psessionEntry->limCurrentBssCaps =
           psessionEntry->pLimJoinReq->bssDescription.capabilityInfo;

        regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel );

        localPowerConstraint = regMax;

        if(!pMac->psOffloadEnabled)
        {
           limExtractApCapability( pMac,
              (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields,
              GET_IE_LEN_IN_BSS(
              psessionEntry->pLimJoinReq->bssDescription.length),
              &psessionEntry->limCurrentBssQosCaps,
              &psessionEntry->limCurrentBssPropCap,
              &pMac->lim.gLimCurrentBssUapsd
              , &localPowerConstraint,
              psessionEntry
              );
        }
        else
        {
           limExtractApCapability( pMac,
              (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields,
              GET_IE_LEN_IN_BSS(
              psessionEntry->pLimJoinReq->bssDescription.length),
              &psessionEntry->limCurrentBssQosCaps,
              &psessionEntry->limCurrentBssPropCap,
              &psessionEntry->gLimCurrentBssUapsd,
              &localPowerConstraint,
              psessionEntry
              );
        }

        psessionEntry->maxTxPower = limGetMaxTxPower(regMax,
                   localPowerConstraint, pMac->roam.configParam.nTxPowerCap);

        limLog(pMac, LOG1,
                FL("regMax = %d, localPowerConstraint = %d,"
                    "max tx pwr = %d, UAPSD flag for all AC - 0x%2x"),
                regMax, localPowerConstraint,
                psessionEntry->maxTxPower,
                psessionEntry->gUapsdPerAcBitmask);

        if (pSmeJoinReq->powerCap.maxTxPower > psessionEntry->maxTxPower)
        {
            pSmeJoinReq->powerCap.maxTxPower = psessionEntry->maxTxPower;
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                    "Update MaxTxPower in join Req to %d",
                    pSmeJoinReq->powerCap.maxTxPower);
        }
        if(!pMac->psOffloadEnabled)
        {
            if (pMac->lim.gLimCurrentBssUapsd)
            {
                pMac->lim.gUapsdPerAcBitmask =
                          psessionEntry->pLimJoinReq->uapsdPerAcBitmask;
                // resetting the dynamic uapsd mask
                pMac->lim.gUapsdPerAcDeliveryEnableMask = 0;
                pMac->lim.gUapsdPerAcTriggerEnableMask = 0;
            }
        }
        else
        {
            if (psessionEntry->gLimCurrentBssUapsd)
            {
                psessionEntry->gUapsdPerAcBitmask =
                               psessionEntry->pLimJoinReq->uapsdPerAcBitmask;
                /* resetting the dynamic uapsd mask  */
                psessionEntry->gUapsdPerAcDeliveryEnableMask = 0;
                psessionEntry->gUapsdPerAcTriggerEnableMask = 0;
             }
        }

        psessionEntry->limRFBand = limGetRFBand(psessionEntry->currentOperChannel);

        // Initialize 11h Enable Flag
        if(SIR_BAND_5_GHZ == psessionEntry->limRFBand)
        {
            if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
            {
                limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED "));
                psessionEntry->lim11hEnable = WNI_CFG_11H_ENABLED_STADEF;
            }
            else {
                psessionEntry->lim11hEnable = val;
            }
        }
        else
            psessionEntry->lim11hEnable = 0;

        //To care of the scenario when STA transitions from IBSS to Infrastructure mode.
        pMac->lim.gLimIbssCoalescingHappened = false;

            psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
            psessionEntry->limSmeState = eLIM_SME_WT_JOIN_STATE;
            MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));

        /* Indicate whether spectrum management is enabled*/
        psessionEntry->spectrumMgtEnabled =
           pSmeJoinReq->spectrumMgtIndicator;

        /* Enable the spectrum management if this is a DFS channel */
        if (psessionEntry->countryInfoPresent &&
             limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel))
             psessionEntry->spectrumMgtEnabled = TRUE;

        psessionEntry->isOSENConnection =
           pSmeJoinReq->isOSENConnection;

        psessionEntry->sub20_channelwidth = pSmeJoinReq->sub20_channelwidth;

        /* Issue LIM_MLM_JOIN_REQ to MLM */
        limPostMlmMessage(pMac, LIM_MLM_JOIN_REQ, (tANI_U32 *) pMlmJoinReq);
        return;

    }
    else
    {
        /* Received eWNI_SME_JOIN_REQ un expected state */
        limLog(pMac, LOGE, FL("received unexpected SME_JOIN_REQ "
                             "in state %X"), pMac->lim.gLimSmeState);
        retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
        psessionEntry = NULL;
        goto end;

    }

end:
    limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId);

    if(pSmeJoinReq)
    {
        vos_mem_free(pSmeJoinReq);
        pSmeJoinReq = NULL;
        if (NULL != psessionEntry)
        {
            psessionEntry->pLimJoinReq = NULL;
        }
    }

    if(retCode != eSIR_SME_SUCCESS)
    {
        if(NULL != psessionEntry)
        {
            peDeleteSession(pMac,psessionEntry);
            psessionEntry = NULL;
        }
    }
    limLog(pMac, LOG1, FL("Sending failure status limSendSmeJoinReassocRsp"
                       "on sessionid: %d with retCode = %d"),smesessionId, retCode);
    limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry,smesessionId,smetransactionId);
} /*** end __limProcessSmeJoinReq() ***/


#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI
tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower, tANI_U8 iniTxPower)
{
    tANI_U8 maxTxPower = 0;
    tANI_U8 txPower = VOS_MIN( regMax, (apTxPower) );
    txPower = VOS_MIN(txPower, iniTxPower);
    if((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP))
        maxTxPower =  txPower;
    else if (txPower < MIN_TX_PWR_CAP)
        maxTxPower = MIN_TX_PWR_CAP;
    else
        maxTxPower = MAX_TX_PWR_CAP;

    return (maxTxPower);
}
#endif

/**
 * __limProcessSmeReassocReq()
 *
 *FUNCTION:
 * This function is called to process SME_REASSOC_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U16                caps;
    tANI_U32                val;
    tpSirSmeJoinReq    pReassocReq = NULL;
    tLimMlmReassocReq  *pMlmReassocReq;
    tSirResultCodes    retCode = eSIR_SME_SUCCESS;
    tpPESession        psessionEntry = NULL;
    tANI_U8            sessionId;
    tANI_U8            smeSessionId;
    uint8_t            no_of_sessions;
    tANI_U16           transactionId;
    tPowerdBm            localPowerConstraint = 0, regMax = 0;
    tANI_U32           teleBcnEn = 0;
    tANI_U16            nSize;


    PELOG3(limLog(pMac, LOG3, FL("Received REASSOC_REQ"));)

    nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) pMsgBuf);
    pReassocReq = vos_mem_malloc(nSize);
    if ( NULL == pReassocReq )
    {
        // Log error
        limLog(pMac, LOGP,
               FL("call to AllocateMemory failed for pReassocReq"));

        retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
        goto end;
    }
    (void) vos_mem_set((void *) pReassocReq, nSize, 0);
    if ((limJoinReqSerDes(pMac, (tpSirSmeJoinReq) pReassocReq,
                          (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
        (!limIsSmeJoinReqValid(pMac,
                               (tpSirSmeJoinReq) pReassocReq)))
    {
        /// Received invalid eWNI_SME_REASSOC_REQ
        // Log the event
        limLog(pMac, LOGW,
               FL("received SME_REASSOC_REQ with invalid data"));

        retCode = eSIR_SME_INVALID_PARAMETERS;
        goto end;
    }

    no_of_sessions =
        pe_count_session_with_sme_session_id(pMac, pReassocReq->sessionId);
    if (no_of_sessions > 1) {
        limLog(pMac, LOGE,
               FL("%d sessions exist for the SME session %d"),
               no_of_sessions, pReassocReq->sessionId);
        vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                      WLAN_LOG_INDICATOR_HOST_DRIVER,
                      WLAN_LOG_REASON_STALE_SESSION_FOUND,
                      DUMP_VOS_TRACE);
        retCode = eSIR_SME_REFUSED;
        goto end;
   }

   if((psessionEntry = peFindSessionByBssid(pMac,pReassocReq->bssDescription.bssId,&sessionId))==NULL)
    {
        limLog(pMac, LOGE, FL("Session does not exist for given bssId"));
        limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE);
        retCode = eSIR_SME_INVALID_PARAMETERS;

       limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId);
       psessionEntry = pe_find_session_by_sme_session_id(pMac, smeSessionId);

       if (psessionEntry != NULL)
                   limHandleSmeJoinResult(pMac, eSIR_SME_INVALID_PARAMETERS,
                                 eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
       goto end;
    }

#ifdef FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_REQ_EVENT, psessionEntry,
                       eSIR_SUCCESS, eSIR_SUCCESS);
#endif
    //pMac->lim.gpLimReassocReq = pReassocReq;//TO SUPPORT BT-AMP

    /* Store the reassoc handle in the session Table.. 23rd sep review */
    psessionEntry->pLimReAssocReq = pReassocReq;

    psessionEntry->dot11mode = pReassocReq->dot11mode;
    psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(pReassocReq->dot11mode);

#ifdef WLAN_FEATURE_11AC
        if (psessionEntry->vhtCapability) {
            if (psessionEntry->pePersona == VOS_STA_MODE)
                psessionEntry->txBFIniFeatureEnabled =
                      pReassocReq->txBFIniFeatureEnabled;
            else
                psessionEntry->txBFIniFeatureEnabled = 0;

            psessionEntry->txMuBformee = pReassocReq->txMuBformee;
            psessionEntry->enableVhtpAid = pReassocReq->enableVhtpAid;
            psessionEntry->enableVhtGid = pReassocReq->enableVhtGid;
            if (psessionEntry->txBFIniFeatureEnabled) {
                if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
                                 psessionEntry->txBFIniFeatureEnabled)
                                                      != eSIR_SUCCESS) {
                    limLog(pMac, LOGE, FL("could not set  "
                                "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG"));
                    retCode = eSIR_LOGP_EXCEPTION;
                    goto end;
                }
                if (cfgSetInt(pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
                                              pReassocReq->txBFCsnValue)
                                                       != eSIR_SUCCESS) {
                    limLog(pMac, LOGE, FL("could not set "
                     "WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED at CFG"));
                    retCode = eSIR_LOGP_EXCEPTION;
                    goto end;
                }
            }
        }
        limLog(pMac, LOG1,
               FL("vhtCapability: %d txBFIniFeatureEnabled: %d"
                 "txBFCsnValue: %d txMuBformee: %d"),
               psessionEntry->vhtCapability,
               psessionEntry->txBFIniFeatureEnabled,
               pReassocReq->txBFCsnValue,
               psessionEntry->txMuBformee);
#endif

    psessionEntry->enableHtSmps = pReassocReq->enableHtSmps;
    psessionEntry->htSmpsvalue = pReassocReq->htSmps;
    limLog(pMac, LOG1, FL("enableHtSmps: %d htSmps: %d supported nss 1x1: %d"),
           psessionEntry->enableHtSmps,
           psessionEntry->htSmpsvalue,
           psessionEntry->supported_nss_1x1);

    /**
     * Reassociate request is expected
     * in link established state only.
     */

    if (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)
    {
#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
        if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
        {
            // May be from 11r FT pre-auth. So lets check it before we bail out
            limLog(pMac, LOG1, FL("Session in reassoc state is %d"),
                psessionEntry->peSessionId);

            // Make sure its our preauth bssid
            if (!vos_mem_compare( pReassocReq->bssDescription.bssId,
                psessionEntry->limReAssocbssId, 6))
            {
                limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE);
                limLog(pMac, LOGP, FL("Unknown bssId in reassoc state"));
                retCode = eSIR_SME_INVALID_PARAMETERS;
                goto end;
            }

            limProcessMlmFTReassocReq(pMac, pMsgBuf, psessionEntry);
            return;
        }
#endif
        /// Should not have received eWNI_SME_REASSOC_REQ
        // Log the event
        limLog(pMac, LOGE,
               FL("received unexpected SME_REASSOC_REQ in state %X"),
               psessionEntry->limSmeState);

        retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
        goto end;
    }

    vos_mem_copy( psessionEntry->limReAssocbssId,
             psessionEntry->pLimReAssocReq->bssDescription.bssId,
             sizeof(tSirMacAddr));

    psessionEntry->limReassocChannelId =
         psessionEntry->pLimReAssocReq->bssDescription.channelId;

    psessionEntry->reAssocHtSupportedChannelWidthSet =
         (psessionEntry->pLimReAssocReq->cbMode)?1:0;
    psessionEntry->reAssocHtRecommendedTxWidthSet =
         psessionEntry->reAssocHtSupportedChannelWidthSet;
    psessionEntry->reAssocHtSecondaryChannelOffset =
         psessionEntry->pLimReAssocReq->cbMode;

    psessionEntry->limReassocBssCaps =
                psessionEntry->pLimReAssocReq->bssDescription.capabilityInfo;
    regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel );
    localPowerConstraint = regMax;

    if(!pMac->psOffloadEnabled)
    {
        limExtractApCapability( pMac,
            (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields,
            GET_IE_LEN_IN_BSS(
            psessionEntry->pLimReAssocReq->bssDescription.length),
            &psessionEntry->limReassocBssQosCaps,
            &psessionEntry->limReassocBssPropCap,
            &pMac->lim.gLimCurrentBssUapsd
            , &localPowerConstraint,
            psessionEntry
            );
    }
    else
    {
        limExtractApCapability(pMac,
            (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields,
            GET_IE_LEN_IN_BSS(
            psessionEntry->pLimReAssocReq->bssDescription.length),
            &psessionEntry->limReassocBssQosCaps,
            &psessionEntry->limReassocBssPropCap,
            &psessionEntry->gLimCurrentBssUapsd,
            &localPowerConstraint,
            psessionEntry);
    }

    psessionEntry->maxTxPower = VOS_MIN( regMax, (localPowerConstraint) );
#if defined WLAN_VOWIFI_DEBUG
            limLog( pMac, LOGE, "Regulatory max = %d, local power constraint "
                        "= %d, max tx = %d", regMax, localPowerConstraint,
                          psessionEntry->maxTxPower );
#endif
    {

    /* Copy the SSID from session entry to local variable */
    psessionEntry->limReassocSSID.length = pReassocReq->ssId.length;
    vos_mem_copy(psessionEntry->limReassocSSID.ssId,
                 pReassocReq->ssId.ssId, psessionEntry->limReassocSSID.length);

    }

    if(!pMac->psOffloadEnabled)
    {
        if (pMac->lim.gLimCurrentBssUapsd)
        {
            pMac->lim.gUapsdPerAcBitmask =
                      psessionEntry->pLimReAssocReq->uapsdPerAcBitmask;
            limLog( pMac, LOG1,
                    FL("UAPSD flag for all AC - 0x%2x"),
                    pMac->lim.gUapsdPerAcBitmask);
        }
    }
    else
    {
        if(psessionEntry->gLimCurrentBssUapsd)
        {
            psessionEntry->gUapsdPerAcBitmask =
                           psessionEntry->pLimReAssocReq->uapsdPerAcBitmask;
            limLog( pMac, LOG1,
                    FL("UAPSD flag for all AC - 0x%2x"),
                    psessionEntry->gUapsdPerAcBitmask);
        }
    }

    pMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq));
    if ( NULL == pMlmReassocReq )
    {
        // Log error
        limLog(pMac, LOGP,
               FL("call to AllocateMemory failed for mlmReassocReq"));

        retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
        goto end;
    }

    vos_mem_copy( pMlmReassocReq->peerMacAddr,
                  psessionEntry->limReAssocbssId,
                  sizeof(tSirMacAddr));

    if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
                  (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout)
                           != eSIR_SUCCESS)
    {
        /**
         * Could not get ReassocFailureTimeout value
         * from CFG. Log error.
         */
        limLog(pMac, LOGP,
               FL("could not retrieve ReassocFailureTimeout value"));
    }

    if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
    {
        /**
         * Could not get Capabilities value
         * from CFG. Log error.
         */
        limLog(pMac, LOGP,
               FL("could not retrieve Capabilities value"));
    }

    lim_update_caps_info_for_bss(pMac, &caps,
                        pReassocReq->bssDescription.capabilityInfo);

    limLog(pMac, LOG1, FL("Capabilities info Reassoc: 0x%X"), caps);

    pMlmReassocReq->capabilityInfo = caps;

    /* Update PE sessionId*/
    pMlmReassocReq->sessionId = sessionId;

   /* If telescopic beaconing is enabled, set listen interval to
     WNI_CFG_TELE_BCN_MAX_LI */
    if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
       eSIR_SUCCESS)
       limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));

    val = WNI_CFG_LISTEN_INTERVAL_STADEF;

    if(teleBcnEn)
    {
       if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
          eSIR_SUCCESS)
       {
            /**
            * Could not get ListenInterval value
            * from CFG. Log error.
          */
          limLog(pMac, LOGP, FL("could not retrieve ListenInterval"));
       }
    }
    else
    {
       if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS)
       {
         /**
            * Could not get ListenInterval value
            * from CFG. Log error.
          */
          limLog(pMac, LOGP, FL("could not retrieve ListenInterval"));
       }
    }

    pMlmReassocReq->listenInterval = (tANI_U16) val;

    /* Indicate whether spectrum management is enabled*/
    psessionEntry->spectrumMgtEnabled = pReassocReq->spectrumMgtIndicator;

    /* Enable the spectrum management if this is a DFS channel */
    if (psessionEntry->countryInfoPresent &&
             limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel))
             psessionEntry->spectrumMgtEnabled = TRUE;

    psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
    psessionEntry->limSmeState    = eLIM_SME_WT_REASSOC_STATE;

    MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));

    limPostMlmMessage(pMac,
                      LIM_MLM_REASSOC_REQ,
                      (tANI_U32 *) pMlmReassocReq);
    return;

end:
    if (pReassocReq) {
        vos_mem_free( pReassocReq);
        if (psessionEntry)
            psessionEntry->pLimReAssocReq = NULL;
    }

    if (psessionEntry)
    {
       // error occurred after we determined the session so extract
       // session and transaction info from there
       smeSessionId = psessionEntry->smeSessionId;
       transactionId = psessionEntry->transactionId;
    }
    else
    {
       // error occurred before or during the time we determined the session
       // so extract the session and transaction info from the message
       limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId);
    }

    /// Send Reassoc failure response to host
    /// (note psessionEntry may be NULL, but that's OK)
    limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP,
                             retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS,
                             psessionEntry, smeSessionId, transactionId);

} /*** end __limProcessSmeReassocReq() ***/


tANI_BOOLEAN sendDisassocFrame = 1;
/**
 * __limProcessSmeDisassocReq()
 *
 *FUNCTION:
 * This function is called to process SME_DISASSOC_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U16                disassocTrigger, reasonCode;
    tLimMlmDisassocReq      *pMlmDisassocReq;
    tSirResultCodes         retCode = eSIR_SME_SUCCESS;
    tSirRetStatus           status;
    tSirSmeDisassocReq      smeDisassocReq;
    tpPESession             psessionEntry = NULL;
    tANI_U8                 sessionId;
    tANI_U8                 smesessionId;
    tANI_U16                smetransactionId;

    if (pMsgBuf == NULL)
    {
        limLog(pMac, LOGE, FL("Buffer is Pointing to NULL"));
        return;
    }

    limGetSessionInfo(pMac, (tANI_U8 *)pMsgBuf,&smesessionId, &smetransactionId);

    status = limDisassocReqSerDes(pMac, &smeDisassocReq, (tANI_U8 *) pMsgBuf);

    if ( (eSIR_FAILURE == status) ||
         (!limIsSmeDisassocReqValid(pMac, &smeDisassocReq, psessionEntry)) )
    {
        PELOGE(limLog(pMac, LOGE,
               FL("received invalid SME_DISASSOC_REQ message"));)

        if (pMac->lim.gLimRspReqd)
        {
            pMac->lim.gLimRspReqd = false;

            retCode         = eSIR_SME_INVALID_PARAMETERS;
            disassocTrigger = eLIM_HOST_DISASSOC;
            goto sendDisassoc;
        }

        return;
    }

    if((psessionEntry = peFindSessionByBssid(pMac,smeDisassocReq.bssId,&sessionId))== NULL)
    {
        limLog(pMac, LOGE,FL("session does not exist for given bssId "MAC_ADDRESS_STR),
                          MAC_ADDR_ARRAY(smeDisassocReq.bssId));
        retCode = eSIR_SME_INVALID_PARAMETERS;
        disassocTrigger = eLIM_HOST_DISASSOC;
        goto sendDisassoc;

    }
    limLog(pMac, LOG1, FL("received DISASSOC_REQ message on sessionid %d "
          "Systemrole %d Reason: %u SmeState: %d from: "MAC_ADDRESS_STR),
          smesessionId, GET_LIM_SYSTEM_ROLE(psessionEntry),
          smeDisassocReq.reasonCode, pMac->lim.gLimSmeState,
          MAC_ADDR_ARRAY(smeDisassocReq.peerMacAddr));

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
   limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry, 0, smeDisassocReq.reasonCode);
#endif //FEATURE_WLAN_DIAG_SUPPORT

    /* Update SME session Id and SME transaction ID*/

    psessionEntry->smeSessionId = smesessionId;
    psessionEntry->transactionId = smetransactionId;

    switch (GET_LIM_SYSTEM_ROLE(psessionEntry))
    {
        case eLIM_STA_ROLE:
        case eLIM_BT_AMP_STA_ROLE:
            switch (psessionEntry->limSmeState)
            {
                case eLIM_SME_ASSOCIATED_STATE:
                case eLIM_SME_LINK_EST_STATE:
                    limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ in limSmeState: %d"),
                                       psessionEntry->limSmeState);
                    psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
                    psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE;
#ifdef FEATURE_WLAN_TDLS
                    /* Delete all TDLS peers connected before leaving BSS*/
                    limDeleteTDLSPeers(pMac, psessionEntry);
#endif
                    MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));
                    break;

                case eLIM_SME_WT_DEAUTH_STATE:
                    /* PE shall still process the DISASSOC_REQ and proceed with
                     * link tear down even if it had already sent a DEAUTH_IND to
                     * to SME. pMac->lim.gLimPrevSmeState shall remain the same as
                     * its been set when PE entered WT_DEAUTH_STATE.
                     */
                    psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE;
                    MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));
                    limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in "
                       "SME_WT_DEAUTH_STATE. "));
                    break;

                case eLIM_SME_WT_DISASSOC_STATE:
                    /* PE Recieved a Disassoc frame. Normally it gets DISASSOC_CNF but it
                     * received DISASSOC_REQ. Which means host is also trying to disconnect.
                     * PE can continue processing DISASSOC_REQ and send the response instead
                     * of failing the request. SME will anyway ignore DEAUTH_IND that was sent
                     * for disassoc frame.
                     *
                     * It will send a disassoc, which is ok. However, we can use the global flag
                     * sendDisassoc to not send disassoc frame.
                     */
                    limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in "
                       "SME_WT_DISASSOC_STATE. "));
                    break;

                case eLIM_SME_JOIN_FAILURE_STATE: {
                    /** Return Success as we are already in Disconnected State*/
                    limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in "
                       "eLIM_SME_JOIN_FAILURE_STATE. "));
                     if (pMac->lim.gLimRspReqd) {
                        retCode = eSIR_SME_SUCCESS;
                        disassocTrigger = eLIM_HOST_DISASSOC;
                        goto sendDisassoc;
                    }
                }break;
                default:
                    /**
                     * STA is not currently associated.
                     * Log error and send response to host
                     */
                    limLog(pMac, LOGE,
                       FL("received unexpected SME_DISASSOC_REQ in state %X"),
                       psessionEntry->limSmeState);

                    if (pMac->lim.gLimRspReqd)
                    {
                        if (psessionEntry->limSmeState !=
                                                eLIM_SME_WT_ASSOC_STATE)
                                    pMac->lim.gLimRspReqd = false;

                        retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
                        disassocTrigger = eLIM_HOST_DISASSOC;
                        goto sendDisassoc;
                    }

                    return;
            }

            break;

        case eLIM_AP_ROLE:
    case eLIM_BT_AMP_AP_ROLE:
            // Fall through
            break;

        case eLIM_STA_IN_IBSS_ROLE:
        default: // eLIM_UNKNOWN_ROLE
            limLog(pMac, LOGE,
               FL("received unexpected SME_DISASSOC_REQ for role %d"),
               GET_LIM_SYSTEM_ROLE(psessionEntry));

            retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
            disassocTrigger = eLIM_HOST_DISASSOC;
            goto sendDisassoc;
    } // end switch (pMac->lim.gLimSystemRole)

    disassocTrigger = eLIM_HOST_DISASSOC;
    reasonCode      = smeDisassocReq.reasonCode;

    if (smeDisassocReq.doNotSendOverTheAir)
    {
        limLog(pMac, LOG1, FL("do not send dissoc over the air"));
        sendDisassocFrame = 0;
    }
    // Trigger Disassociation frame to peer MAC entity
    limLog(pMac, LOG1, FL("Sending Disasscoc with disassoc Trigger"
                          " : %d, reasonCode : %d"),
                          disassocTrigger, reasonCode);

    pMlmDisassocReq = vos_mem_malloc(sizeof(tLimMlmDisassocReq));
    if ( NULL == pMlmDisassocReq )
    {
        // Log error
        limLog(pMac, LOGP,
               FL("call to AllocateMemory failed for mlmDisassocReq"));

        return;
    }

    vos_mem_copy( (tANI_U8 *) &pMlmDisassocReq->peerMacAddr,
                  (tANI_U8 *) &smeDisassocReq.peerMacAddr,
                  sizeof(tSirMacAddr));

    pMlmDisassocReq->reasonCode      = reasonCode;
    pMlmDisassocReq->disassocTrigger = disassocTrigger;

    /* Update PE session ID*/
    pMlmDisassocReq->sessionId = sessionId;

    limPostMlmMessage(pMac,
                      LIM_MLM_DISASSOC_REQ,
                      (tANI_U32 *) pMlmDisassocReq);
    return;

sendDisassoc:
    if (psessionEntry)
        limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr,
                          retCode,
                          disassocTrigger,
                          1,smesessionId,smetransactionId,psessionEntry);
    else
        limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr,
                retCode,
                disassocTrigger,
                1, smesessionId, smetransactionId, NULL);


} /*** end __limProcessSmeDisassocReq() ***/


/** -----------------------------------------------------------------
  \brief __limProcessSmeDisassocCnf() - Process SME_DISASSOC_CNF

  This function is called to process SME_DISASSOC_CNF message
  from HDD or upper layer application.

  \param pMac - global mac structure
  \param pStaDs - station dph hash node
  \return none
  \sa
  ----------------------------------------------------------------- */
static void
__limProcessSmeDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirSmeDisassocCnf  smeDisassocCnf;
    tANI_U16  aid;
    tpDphHashNode  pStaDs;
    tSirRetStatus  status = eSIR_SUCCESS;
    tpPESession         psessionEntry;
    tANI_U8             sessionId;


    PELOG1(limLog(pMac, LOG1, FL("received DISASSOC_CNF message"));)

    status = limDisassocCnfSerDes(pMac, &smeDisassocCnf,(tANI_U8 *) pMsgBuf);

    if (status == eSIR_FAILURE)
    {
        PELOGE(limLog(pMac, LOGE, FL("invalid SME_DISASSOC_CNF message"));)
        return;
    }

    if((psessionEntry = peFindSessionByBssid(pMac, smeDisassocCnf.bssId, &sessionId))== NULL)
    {
         limLog(pMac, LOGE,FL("session does not exist for given bssId"));
         return;
    }

    if (!limIsSmeDisassocCnfValid(pMac, &smeDisassocCnf, psessionEntry))
    {
        limLog(pMac, LOGE, FL("received invalid SME_DISASSOC_CNF message"));
        return;
    }

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF)
        limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0);
    else if (smeDisassocCnf.messageType ==  eWNI_SME_DEAUTH_CNF)
        limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT

    switch (GET_LIM_SYSTEM_ROLE(psessionEntry))
    {
        case eLIM_STA_ROLE:
        case eLIM_BT_AMP_STA_ROLE:  //To test reconn
            if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) &&
                (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
                (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE))
            {
                limLog(pMac, LOGE,
                   FL("received unexp SME_DISASSOC_CNF in state %X"),
                  psessionEntry->limSmeState);
                return;
            }
            break;

        case eLIM_AP_ROLE:
            // Fall through
            break;

        case eLIM_STA_IN_IBSS_ROLE:
        default: // eLIM_UNKNOWN_ROLE
            limLog(pMac, LOGE,
               FL("received unexpected SME_DISASSOC_CNF role %d"),
               GET_LIM_SYSTEM_ROLE(psessionEntry));

            return;
    }

    if ((psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) ||
        (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
        LIM_IS_AP_ROLE(psessionEntry)) {
        pStaDs = dphLookupHashEntry(pMac, smeDisassocCnf.peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
        if (pStaDs == NULL)
        {
            PELOGE(limLog(pMac, LOGE, FL("received DISASSOC_CNF for a STA that "
               "does not have context, addr= "MAC_ADDRESS_STR),
                     MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr));)
            return;
        }

        /*
         * If MlM state is either of del_sta or del_bss state, then no need to
         * go ahead and clean up further as there must be some cleanup in
         * progress from upper layer disassoc/deauth request.
         */
        if((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
           (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) {
            limLog(pMac, LOGE, FL("No need to cleanup for addr:"MAC_ADDRESS_STR
                   "as Mlm state is %d"),
                   MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr),
                   pStaDs->mlmStaContext.mlmState);
           return;
        }

#if defined WLAN_FEATURE_VOWIFI_11R
        /* Delete FT session if there exists one */
        limFTCleanupPreAuthInfo(pMac, psessionEntry);
#endif
        limCleanupRxPath(pMac, pStaDs, psessionEntry);

        limCleanUpDisassocDeauthReq(pMac, (char*)&smeDisassocCnf.peerMacAddr, 0);
    }

    return;
}


/**
 * __limProcessSmeDeauthReq()
 *
 *FUNCTION:
 * This function is called to process SME_DEAUTH_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U16                deauthTrigger, reasonCode;
    tLimMlmDeauthReq        *pMlmDeauthReq;
    tSirSmeDeauthReq        smeDeauthReq;
    tSirResultCodes         retCode = eSIR_SME_SUCCESS;
    tSirRetStatus           status = eSIR_SUCCESS;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId; //PE sessionId
    tANI_U8                 smesessionId;
    tANI_U16                smetransactionId;

    PELOG1(limLog(pMac, LOG1,FL("received DEAUTH_REQ message"));)

    status = limDeauthReqSerDes(pMac, &smeDeauthReq,(tANI_U8 *) pMsgBuf);

    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);

    //We need to get a session first but we don't even know if the message is correct.
    if((psessionEntry = peFindSessionByBssid(pMac, smeDeauthReq.bssId, &sessionId)) == NULL)
    {
       limLog(pMac, LOGE,FL("session does not exist for given bssId"));
       retCode = eSIR_SME_INVALID_PARAMETERS;
       deauthTrigger = eLIM_HOST_DEAUTH;
       goto sendDeauth;

    }

    if ((status == eSIR_FAILURE) || (!limIsSmeDeauthReqValid(pMac, &smeDeauthReq, psessionEntry)))
    {
        PELOGE(limLog(pMac, LOGE,FL
                   ("received invalid SME_DEAUTH_REQ message"));)
        pMac->lim.gLimRspReqd = false;

        retCode       = eSIR_SME_INVALID_PARAMETERS;
        deauthTrigger = eLIM_HOST_DEAUTH;
        goto sendDeauth;
    }
    limLog(pMac, LOG1,FL("received DEAUTH_REQ message on sessionid %d "
      "Systemrole %d with reasoncode %u in limSmestate %d from "
      MAC_ADDRESS_STR), smesessionId, GET_LIM_SYSTEM_ROLE(psessionEntry),
      smeDeauthReq.reasonCode, psessionEntry->limSmeState,
      MAC_ADDR_ARRAY(smeDeauthReq.peerMacAddr));
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_REQ_EVENT, psessionEntry, 0, smeDeauthReq.reasonCode);
#endif //FEATURE_WLAN_DIAG_SUPPORT

    /* Update SME session ID and Transaction ID */
    psessionEntry->smeSessionId = smesessionId;
    psessionEntry->transactionId = smetransactionId;


    switch (GET_LIM_SYSTEM_ROLE(psessionEntry))
    {
        case eLIM_STA_ROLE:
        case eLIM_BT_AMP_STA_ROLE:

            switch (psessionEntry->limSmeState)
            {
                case eLIM_SME_ASSOCIATED_STATE:
                case eLIM_SME_LINK_EST_STATE:
                case eLIM_SME_WT_ASSOC_STATE:
                case eLIM_SME_JOIN_FAILURE_STATE:
                case eLIM_SME_IDLE_STATE:
                    psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
                    psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
                    MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));

                    // Send Deauthentication request to MLM below

                    break;
                case eLIM_SME_WT_DEAUTH_STATE:
                case eLIM_SME_WT_DISASSOC_STATE:
                    /*
                     * PE Recieved a Deauth/Disassoc frame. Normally it gets
                     * DEAUTH_CNF/DISASSOC_CNF but it received DEAUTH_REQ. Which
                     * means host is also trying to disconnect.
                     * PE can continue processing DEAUTH_REQ and send
                     * the response instead of failing the request.
                     * SME will anyway ignore DEAUTH_IND/DISASSOC_IND that
                     * was sent for deauth/disassoc frame.
                     */
                    psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
                    limLog(pMac, LOG1, FL("Rcvd SME_DEAUTH_REQ while in "
                       "SME_WT_DEAUTH_STATE. "));
                    break;
                default:
                    /**
                     * STA is not in a state to deauthenticate with
                     * peer. Log error and send response to host.
                     */
                    limLog(pMac, LOGE,
                    FL("received unexp SME_DEAUTH_REQ in state %X"),
                    psessionEntry->limSmeState);

                    if (pMac->lim.gLimRspReqd)
                    {
                        pMac->lim.gLimRspReqd = false;

                        retCode       = eSIR_SME_STA_NOT_AUTHENTICATED;
                        deauthTrigger = eLIM_HOST_DEAUTH;

/*
               here we received deauth request from AP so sme state is
               eLIM_SME_WT_DEAUTH_STATE.if we have ISSUED delSta then
               mlm state should be eLIM_MLM_WT_DEL_STA_RSP_STATE and if
               we got delBSS rsp then mlm state should be eLIM_MLM_IDLE_STATE
               so the below condition captures the state where delSta
               not done and firmware still in connected state.
*/

                        if (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE &&
                            psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE &&
                            psessionEntry->limMlmState != eLIM_MLM_WT_DEL_STA_RSP_STATE)
                        {
                            retCode = eSIR_SME_DEAUTH_STATUS;
                        }
                        goto sendDeauth;
                    }

                    return;
            }

            break;

        case eLIM_STA_IN_IBSS_ROLE:
            limLog(pMac, LOGE,FL("Deauth not allowed in IBSS"));
            if (pMac->lim.gLimRspReqd)
            {
                   pMac->lim.gLimRspReqd = false;
                   retCode = eSIR_SME_INVALID_PARAMETERS;
                   deauthTrigger = eLIM_HOST_DEAUTH;
                   goto sendDeauth;
            }
            return;

        case eLIM_AP_ROLE:
            // Fall through

            break;

        default:
            limLog(pMac, LOGE,
               FL("received unexpected SME_DEAUTH_REQ for role %X"),
               GET_LIM_SYSTEM_ROLE(psessionEntry));
            if (pMac->lim.gLimRspReqd)
            {
                   pMac->lim.gLimRspReqd = false;
                   retCode = eSIR_SME_INVALID_PARAMETERS;
                   deauthTrigger = eLIM_HOST_DEAUTH;
                   goto sendDeauth;
            }
            return;
    } // end switch (pMac->lim.gLimSystemRole)

    if (smeDeauthReq.reasonCode == eLIM_LINK_MONITORING_DEAUTH)
    {
        /// Deauthentication is triggered by Link Monitoring
        PELOG1(limLog(pMac, LOG1, FL("**** Lost link with AP ****"));)
        deauthTrigger = eLIM_LINK_MONITORING_DEAUTH;
        reasonCode    = eSIR_MAC_UNSPEC_FAILURE_REASON;
    }
    else
    {
        deauthTrigger = eLIM_HOST_DEAUTH;
        reasonCode    = smeDeauthReq.reasonCode;
    }

    // Trigger Deauthentication frame to peer MAC entity
    pMlmDeauthReq = vos_mem_malloc(sizeof(tLimMlmDeauthReq));
    if ( NULL == pMlmDeauthReq )
    {
        // Log error
        limLog(pMac, LOGE,
               FL("call to AllocateMemory failed for mlmDeauthReq"));
        if (pMac->lim.gLimRspReqd)
        {
            pMac->lim.gLimRspReqd = false;
            retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
            deauthTrigger = eLIM_HOST_DEAUTH;
            goto sendDeauth;
        }
        return;
    }

    vos_mem_copy( (tANI_U8 *) &pMlmDeauthReq->peerMacAddr,
                  (tANI_U8 *) &smeDeauthReq.peerMacAddr,
                  sizeof(tSirMacAddr));

    pMlmDeauthReq->reasonCode = reasonCode;
    pMlmDeauthReq->deauthTrigger = deauthTrigger;

    /* Update PE session Id*/
    pMlmDeauthReq->sessionId = sessionId;

    limPostMlmMessage(pMac,
                      LIM_MLM_DEAUTH_REQ,
                      (tANI_U32 *) pMlmDeauthReq);
    return;

sendDeauth:
    limSendSmeDeauthNtf(pMac, smeDeauthReq.peerMacAddr,
                        retCode,
                        deauthTrigger,
                        1,
                        smesessionId, smetransactionId);
} /*** end __limProcessSmeDeauthReq() ***/



/**
 * __limProcessSmeSetContextReq()
 *
 *FUNCTION:
 * This function is called to process SME_SETCONTEXT_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeSetContextReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirSmeSetContextReq  pSetContextReq;
    tLimMlmSetKeysReq      *pMlmSetKeysReq;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId;  //PE sessionID
    tANI_U8                 smesessionId;
    tANI_U16                smetransactionId;


    PELOG1(limLog(pMac, LOG1,
           FL("received SETCONTEXT_REQ message")););


    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);

    pSetContextReq = vos_mem_malloc(sizeof(tSirKeys) * SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS);
    if ( NULL == pSetContextReq )
    {
        limLog(pMac, LOGP, FL("call to AllocateMemory failed for pSetContextReq"));
        return;
    }

    if ((limSetContextReqSerDes(pMac, pSetContextReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
        (!limIsSmeSetContextReqValid(pMac, pSetContextReq)))
    {
        limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message"));
        goto end;
    }

    if(pSetContextReq->keyMaterial.numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)
    {
        PELOGE(limLog(pMac, LOGE, FL("numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS"), pSetContextReq->keyMaterial.numKeys);)
        limSendSmeSetContextRsp(pMac,
                                pSetContextReq->peerMacAddr,
                                1,
                                eSIR_SME_INVALID_PARAMETERS,NULL,
                                smesessionId,smetransactionId);

        goto end;
    }


    if((psessionEntry = peFindSessionByBssid(pMac, pSetContextReq->bssId, &sessionId)) == NULL)
    {
        limLog(pMac, LOGW, FL("Session does not exist for given BSSID"));
        limSendSmeSetContextRsp(pMac,
                                pSetContextReq->peerMacAddr,
                                1,
                                eSIR_SME_INVALID_PARAMETERS,NULL,
                                smesessionId,smetransactionId);

        goto end;
    }

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, psessionEntry, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT


    if (((LIM_IS_STA_ROLE(psessionEntry) ||
          LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
         (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
        ((LIM_IS_IBSS_ROLE(psessionEntry) ||
          LIM_IS_AP_ROLE(psessionEntry) ||
          LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
         (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))) {
        // Trigger MLM_SETKEYS_REQ
        pMlmSetKeysReq = vos_mem_malloc(sizeof(tLimMlmSetKeysReq));
        if ( NULL == pMlmSetKeysReq )
        {
            // Log error
            limLog(pMac, LOGP, FL("call to AllocateMemory failed for mlmSetKeysReq"));
            goto end;
        }

        pMlmSetKeysReq->edType  = pSetContextReq->keyMaterial.edType;
        pMlmSetKeysReq->numKeys = pSetContextReq->keyMaterial.numKeys;
        if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)
        {
            limLog(pMac, LOGP, FL("Num of keys exceeded max num of default keys limit"));
            goto end;
        }
        vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->peerMacAddr,
                      (tANI_U8 *) &pSetContextReq->peerMacAddr,
                      sizeof(tSirMacAddr));


        vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->key,
                      (tANI_U8 *) &pSetContextReq->keyMaterial.key,
                      sizeof(tSirKeys) * (pMlmSetKeysReq->numKeys ? pMlmSetKeysReq->numKeys : 1));

        pMlmSetKeysReq->sessionId = sessionId;
        pMlmSetKeysReq->smesessionId = smesessionId;
#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
        PELOG1(limLog(pMac, LOG1,
           FL("received SETCONTEXT_REQ message sessionId=%d"), pMlmSetKeysReq->sessionId););
#endif

        if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) ||
            (pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104)) &&
            LIM_IS_AP_ROLE(psessionEntry)) {
            if(pSetContextReq->keyMaterial.key[0].keyLength)
            {
                tANI_U8 keyId;
                keyId = pSetContextReq->keyMaterial.key[0].keyId;
                vos_mem_copy( (tANI_U8 *)&psessionEntry->WEPKeyMaterial[keyId],
                   (tANI_U8 *) &pSetContextReq->keyMaterial, sizeof(tSirKeyMaterial));
            }
            else {
                tANI_U32 i;
                for( i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++)
                {
                    vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->key[i],
                        (tANI_U8 *)psessionEntry->WEPKeyMaterial[i].key, sizeof(tSirKeys));
                }
            }
        }

        limPostMlmMessage(pMac, LIM_MLM_SETKEYS_REQ, (tANI_U32 *) pMlmSetKeysReq);
    }
    else
    {
        limLog(pMac, LOGE,
           FL("received unexpected SME_SETCONTEXT_REQ for role %d, state=%X"),
           GET_LIM_SYSTEM_ROLE(psessionEntry),
           psessionEntry->limSmeState);

        limSendSmeSetContextRsp(pMac, pSetContextReq->peerMacAddr,
                                1,
                                eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry,
                                smesessionId,
                                smetransactionId);
    }

end:
    vos_mem_free( pSetContextReq);
    return;
} /*** end __limProcessSmeSetContextReq() ***/

/**
 * __limProcessSmeRemoveKeyReq()
 *
 *FUNCTION:
 * This function is called to process SME_REMOVEKEY_REQ message
 * from HDD or upper layer application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirSmeRemoveKeyReq    pRemoveKeyReq;
    tLimMlmRemoveKeyReq     *pMlmRemoveKeyReq;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId;  //PE sessionID
    tANI_U8                 smesessionId;
    tANI_U16                smetransactionId;

    PELOG1(limLog(pMac, LOG1,
           FL("received REMOVEKEY_REQ message"));)

    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
           return;
    }


    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);

    pRemoveKeyReq = vos_mem_malloc(sizeof(*pRemoveKeyReq));
    if ( NULL == pRemoveKeyReq )
    {
        //Log error
        limLog(pMac, LOGP,
               FL("call to AllocateMemory failed for pRemoveKeyReq"));

        return;
     }

    if ((limRemoveKeyReqSerDes(pMac,
                                pRemoveKeyReq,
                                (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
    {
        limLog(pMac, LOGW,
               FL("received invalid SME_REMOVECONTEXT_REQ message"));

        /* extra look up is needed since, session entry to be passed il limsendremovekey response */

        if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId,&sessionId))== NULL)
        {
            limLog(pMac, LOGE,FL("session does not exist for given bssId"));
            //goto end;
        }

        limSendSmeRemoveKeyRsp(pMac,
                                pRemoveKeyReq->peerMacAddr,
                                eSIR_SME_INVALID_PARAMETERS,psessionEntry,
                                smesessionId,smetransactionId);

        goto end;
    }

    if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId, &sessionId))== NULL)
    {
        limLog(pMac, LOGE,
                      FL("session does not exist for given bssId"));
        limSendSmeRemoveKeyRsp(pMac,
                                pRemoveKeyReq->peerMacAddr,
                                eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, NULL,
                                smesessionId, smetransactionId);
        goto end;
    }


    if (((LIM_IS_STA_ROLE(psessionEntry) ||
          LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
         (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
        ((LIM_IS_IBSS_ROLE(psessionEntry) ||
          LIM_IS_AP_ROLE(psessionEntry) ||
          LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
         (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))) {
        // Trigger MLM_REMOVEKEYS_REQ
        pMlmRemoveKeyReq = vos_mem_malloc(sizeof(tLimMlmRemoveKeyReq));
        if ( NULL == pMlmRemoveKeyReq )
        {
            // Log error
            limLog(pMac, LOGP,
                   FL("call to AllocateMemory failed for mlmRemoveKeysReq"));

            goto end;
        }

        pMlmRemoveKeyReq->edType  = (tAniEdType)pRemoveKeyReq->edType;
        pMlmRemoveKeyReq->keyId = pRemoveKeyReq->keyId;
        pMlmRemoveKeyReq->wepType = pRemoveKeyReq->wepType;
        pMlmRemoveKeyReq->unicast = pRemoveKeyReq->unicast;

        /* Update PE session Id */
        pMlmRemoveKeyReq->sessionId = sessionId;

        vos_mem_copy( (tANI_U8 *) &pMlmRemoveKeyReq->peerMacAddr,
                      (tANI_U8 *) &pRemoveKeyReq->peerMacAddr,
                      sizeof(tSirMacAddr));


        limPostMlmMessage(pMac,
                          LIM_MLM_REMOVEKEY_REQ,
                          (tANI_U32 *) pMlmRemoveKeyReq);
    }
    else
    {
        limLog(pMac, LOGE,
           FL("received unexpected SME_REMOVEKEY_REQ for role %d, state=%X"),
           GET_LIM_SYSTEM_ROLE(psessionEntry),
           psessionEntry->limSmeState);

        limSendSmeRemoveKeyRsp(pMac,
                                pRemoveKeyReq->peerMacAddr,
                                eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry,
                                smesessionId,smetransactionId);
    }

end:
    vos_mem_free( pRemoveKeyReq);
} /*** end __limProcessSmeRemoveKeyReq() ***/

void limProcessSmeGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirMsgQ         mmhMsg;
    tpSmeGetScanChnRsp  pSirSmeRsp;
    tANI_U16 len = 0;
    tANI_U8 sessionId;
    tANI_U16 transactionId;

    if(pMac->lim.scanChnInfo.numChnInfo > SIR_MAX_SUPPORTED_CHANNEL_LIST)
    {
        limLog(pMac, LOGW, FL("numChn is out of bounds %d"),
                pMac->lim.scanChnInfo.numChnInfo);
        pMac->lim.scanChnInfo.numChnInfo = SIR_MAX_SUPPORTED_CHANNEL_LIST;
    }

    len = sizeof(tSmeGetScanChnRsp) + (pMac->lim.scanChnInfo.numChnInfo - 1) * sizeof(tLimScanChn);
    pSirSmeRsp = vos_mem_malloc(len);
    if ( NULL == pSirSmeRsp )
    {
        /// Buffer not available. Log error
        limLog(pMac, LOGP,
               FL("call to AllocateMemory failed for JOIN/REASSOC_RSP"));

        return;
    }
    vos_mem_set(pSirSmeRsp, len, 0);

    pSirSmeRsp->mesgType = eWNI_SME_GET_SCANNED_CHANNEL_RSP;
    pSirSmeRsp->mesgLen = len;

    if (pMac->fScanOffload)
    {
        limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&sessionId,&transactionId);
        pSirSmeRsp->sessionId = sessionId;
    }
    else
        pSirSmeRsp->sessionId = 0;

    if(pMac->lim.scanChnInfo.numChnInfo)
    {
        pSirSmeRsp->numChn = pMac->lim.scanChnInfo.numChnInfo;
        vos_mem_copy( pSirSmeRsp->scanChn, pMac->lim.scanChnInfo.scanChn,
                      sizeof(tLimScanChn) * pSirSmeRsp->numChn);
    }
    //Clear the list
    limRessetScanChannelInfo(pMac);

    mmhMsg.type = eWNI_SME_GET_SCANNED_CHANNEL_RSP;
    mmhMsg.bodyptr = pSirSmeRsp;
    mmhMsg.bodyval = 0;

    pMac->lim.gLimRspReqd = false;
    MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type));
    limSysProcessMmhMsgApi(pMac, &mmhMsg,  ePROT);
}


void limProcessSmeGetAssocSTAsInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirSmeGetAssocSTAsReq  getAssocSTAsReq;
    tpDphHashNode           pStaDs = NULL;
    tpPESession             psessionEntry = NULL;
    tSap_Event              sapEvent;
    tpWLAN_SAPEventCB       pSapEventCallback = NULL;
    tpSap_AssocMacAddr      pAssocStasTemp = NULL;// #include "sapApi.h"
    tANI_U8                 sessionId = CSR_SESSION_ID_INVALID;
    tANI_U8                 assocId = 0;
    tANI_U8                 staCount = 0;

    vos_mem_zero(&getAssocSTAsReq, sizeof(getAssocSTAsReq));

    if (!limIsSmeGetAssocSTAsReqValid(pMac, &getAssocSTAsReq, (tANI_U8 *) pMsgBuf))
    {
        limLog(pMac, LOGE,
                        FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message"));
        return;
    }

    switch (getAssocSTAsReq.modId)
    {
        case VOS_MODULE_ID_PE:
        default:
            break;
    }

    // Get Associated stations from PE
    // Find PE session Entry
    if ((psessionEntry = peFindSessionByBssid(pMac, getAssocSTAsReq.bssId, &sessionId)) == NULL)
    {
        limLog(pMac, LOGE,
                        FL("session does not exist for given bssId"));
        goto limAssocStaEnd;
    }

    if (!LIM_IS_AP_ROLE(psessionEntry)) {
        limLog(pMac, LOGE,
               FL("Received unexpected message in state %X, in role %X"),
               psessionEntry->limSmeState, GET_LIM_SYSTEM_ROLE(psessionEntry));
        goto limAssocStaEnd;
    }

    // Retrieve values obtained in the request message
    pSapEventCallback   = (tpWLAN_SAPEventCB)getAssocSTAsReq.pSapEventCallback;
    pAssocStasTemp      = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray;

    if (NULL == pAssocStasTemp)
        goto limAssocStaEnd;

    for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8
    {
        pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);

        if (NULL == pStaDs)
            continue;

        if (pStaDs->valid)
        {
            vos_mem_copy((tANI_U8 *)&pAssocStasTemp->staMac,
                         (tANI_U8 *)&pStaDs->staAddr,
                         sizeof(v_MACADDR_t));  // Mac address
            pAssocStasTemp->assocId = (v_U8_t)pStaDs->assocId;         // Association Id
            pAssocStasTemp->staId   = (v_U8_t)pStaDs->staIndex;        // Station Id

            vos_mem_copy((tANI_U8 *)&pAssocStasTemp->supportedRates,
                                      (tANI_U8 *)&pStaDs->supportedRates,
                                      sizeof(tSirSupportedRates));
            pAssocStasTemp->ShortGI40Mhz = pStaDs->htShortGI40Mhz;
            pAssocStasTemp->ShortGI20Mhz = pStaDs->htShortGI20Mhz;
            pAssocStasTemp->Support40Mhz = pStaDs->htDsssCckRate40MHzSupport;

            limLog(pMac, LOG1, FL("dph Station Number = %d"), staCount+1);
            limLog(pMac, LOG1, FL("MAC = " MAC_ADDRESS_STR),
                                        MAC_ADDR_ARRAY(pStaDs->staAddr));
            limLog(pMac, LOG1, FL("Association Id = %d"),pStaDs->assocId);
            limLog(pMac, LOG1, FL("Station Index = %d"),pStaDs->staIndex);

            pAssocStasTemp++;
            staCount++;
        }
    }

limAssocStaEnd:
    // Call hdd callback with sap event to send the list of associated stations from PE
    if (pSapEventCallback != NULL)
    {
        sapEvent.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT;
        sapEvent.sapevt.sapAssocStaListEvent.module = VOS_MODULE_ID_PE;
        sapEvent.sapevt.sapAssocStaListEvent.noOfAssocSta = staCount;
        sapEvent.sapevt.sapAssocStaListEvent.pAssocStas = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray;
        pSapEventCallback(&sapEvent, getAssocSTAsReq.pUsrContext);
    }
}


/**
 * limProcessSmeGetWPSPBCSessions
 *
 *FUNCTION:
 * This function is called when query the WPS PBC overlap message is received
 *
 *LOGIC:
 * This function parses get WPS PBC overlap information message and call callback to pass
 * WPS PBC overlap information back to hdd.
 *ASSUMPTIONS:
 *
 *
 *NOTE:
 *
 * @param  pMac     Pointer to Global MAC structure
 * @param  pMsgBuf  A pointer to WPS PBC overlap query message
*
 * @return None
 */
void limProcessSmeGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirSmeGetWPSPBCSessionsReq  GetWPSPBCSessionsReq;
    tpPESession                  psessionEntry = NULL;
    tSap_Event                   sapEvent;
    tpWLAN_SAPEventCB            pSapEventCallback = NULL;
    tANI_U8                      sessionId = CSR_SESSION_ID_INVALID;
    tSirMacAddr                  zeroMac = {0,0,0,0,0,0};

    sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_E_FAULT;

    if (limIsSmeGetWPSPBCSessionsReqValid(pMac,  &GetWPSPBCSessionsReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS)
    {
        limLog(pMac, LOGE,
                        FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message"));
        return;
    }

    // Get Associated stations from PE
    // Find PE session Entry
    if ((psessionEntry = peFindSessionByBssid(pMac, GetWPSPBCSessionsReq.bssId, &sessionId)) == NULL)
    {
        limLog(pMac, LOGE,
                        FL("session does not exist for given bssId"));
        goto limGetWPSPBCSessionsEnd;
    }

    if (!LIM_IS_AP_ROLE(psessionEntry)) {
        limLog(pMac, LOGE,
               FL("Received unexpected message in role %X"),
               GET_LIM_SYSTEM_ROLE(psessionEntry));
        goto limGetWPSPBCSessionsEnd;
    }

    // Call hdd callback with sap event to send the WPS PBC overlap information
    sapEvent.sapHddEventCode =  eSAP_GET_WPSPBC_SESSION_EVENT;
    sapEvent.sapevt.sapGetWPSPBCSessionEvent.module = VOS_MODULE_ID_PE;

    if (vos_mem_compare( zeroMac, GetWPSPBCSessionsReq.pRemoveMac, sizeof(tSirMacAddr)))
    { //This is GetWpsSession call

      limGetWPSPBCSessions(pMac,
              sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, sapEvent.sapevt.sapGetWPSPBCSessionEvent.UUID_E,
              &sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap, psessionEntry);
    }
    else
    {
      limRemovePBCSessions(pMac, GetWPSPBCSessionsReq.pRemoveMac,psessionEntry);
      /* don't have to inform the HDD/Host */
      return;
    }

    PELOG4(limLog(pMac, LOGE, FL("wpsPBCOverlap %d"), sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap);)
    PELOG4(limPrintMacAddr(pMac, sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, LOG4);)

    sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_SUCCESS;

limGetWPSPBCSessionsEnd:
    pSapEventCallback   = (tpWLAN_SAPEventCB)GetWPSPBCSessionsReq.pSapEventCallback;
    if (NULL != pSapEventCallback)
       pSapEventCallback(&sapEvent, GetWPSPBCSessionsReq.pUsrContext);
}



/**
 * __limCounterMeasures()
 *
 * FUNCTION:
 * This function is called to "implement" MIC counter measure
 * and is *temporary* only
 *
 * LOGIC: on AP, disassoc all STA associated thru TKIP,
 * we don't do the proper STA disassoc sequence since the
 * BSS will be stoped anyway
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
__limCounterMeasures(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
    tSirMacAddr mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
        LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
        limSendDisassocMgmtFrame(pMac, eSIR_MAC_MIC_FAILURE_REASON, mac, psessionEntry, FALSE);
}


void
limProcessTkipCounterMeasures(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirSmeTkipCntrMeasReq  tkipCntrMeasReq;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId;      //PE sessionId

    if ( limTkipCntrMeasReqSerDes( pMac, &tkipCntrMeasReq, (tANI_U8 *) pMsgBuf ) != eSIR_SUCCESS )
    {
        limLog(pMac, LOGE,
                        FL("received invalid eWNI_SME_TKIP_CNTR_MEAS_REQ message"));
        return;
    }

    if ( NULL == (psessionEntry = peFindSessionByBssid( pMac, tkipCntrMeasReq.bssId, &sessionId )) )
    {
        limLog(pMac, LOGE, FL("session does not exist for given BSSID "));
        return;
    }

    if ( tkipCntrMeasReq.bEnable )
    {
        __limCounterMeasures( pMac, psessionEntry );
    }

    psessionEntry->bTkipCntrMeasActive = tkipCntrMeasReq.bEnable;
}


static void
__limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirSmeStopBssReq  stopBssReq;
    tSirRetStatus      status;
    tLimSmeStates      prevState;
    tANI_U8            sessionId;  //PE sessionId
    tpPESession        psessionEntry;
    tANI_U8            smesessionId;
    tANI_U16           smetransactionId;
    tANI_U8 i = 0;
    tpDphHashNode      pStaDs = NULL;
    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);



    if ((limStopBssReqSerDes(pMac, &stopBssReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS) ||
        !limIsSmeStopBssReqValid(pMsgBuf))
    {
        PELOGW(limLog(pMac, LOGW, FL("received invalid SME_STOP_BSS_REQ message"));)
        /// Send Stop BSS response to host
        limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId);
        return;
    }


    if((psessionEntry = peFindSessionByBssid(pMac,stopBssReq.bssId,&sessionId)) == NULL)
    {
        limLog(pMac, LOGW, FL("session does not exist for given BSSID "));
        limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId);
        return;
    }

#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT


    if ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) ||    /* Added For BT -AMP Support */
        LIM_IS_STA_ROLE(psessionEntry)) {
        /**
         * Should not have received STOP_BSS_REQ in states
         * other than 'normal' state or on STA in Infrastructure
         * mode. Log error and return response to host.
         */
        limLog(pMac, LOGE,
           FL("received unexpected SME_STOP_BSS_REQ in state %X, for role %d"),
           psessionEntry->limSmeState, GET_LIM_SYSTEM_ROLE(psessionEntry));
        /// Send Stop BSS response to host
        limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,smesessionId,smetransactionId);
        return;
    }

    if (LIM_IS_AP_ROLE(psessionEntry)) {
        limWPSPBCClose(pMac, psessionEntry);
    }
    PELOGW(limLog(pMac, LOGW, FL("RECEIVED STOP_BSS_REQ with reason code=%d"), stopBssReq.reasonCode);)

    prevState = psessionEntry->limSmeState;

    psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));

    /* Update SME session Id and Transaction Id */
    psessionEntry->smeSessionId = smesessionId;
    psessionEntry->transactionId = smetransactionId;

    /* BTAMP_STA, STA_IN_IBSS and NDI should NOT send Disassoc frame */
    if (!LIM_IS_IBSS_ROLE(psessionEntry) &&
        !LIM_IS_BT_AMP_STA_ROLE(psessionEntry) &&
        !LIM_IS_NDI_ROLE(psessionEntry)) {
        tSirMacAddr   bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
        if ((stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES))
            // Send disassoc all stations associated thru TKIP
            __limCounterMeasures(pMac,psessionEntry);
        else
            limSendDisassocMgmtFrame(pMac,
                eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                bcAddr, psessionEntry, FALSE);
    }

    if (!LIM_IS_NDI_ROLE(psessionEntry)) {
        /* Free the buffer allocated in START_BSS_REQ */
        vos_mem_free(psessionEntry->addIeParams.probeRespData_buff);
        psessionEntry->addIeParams.probeRespDataLen = 0;
        psessionEntry->addIeParams.probeRespData_buff = NULL;

        vos_mem_free(psessionEntry->addIeParams.assocRespData_buff);
        psessionEntry->addIeParams.assocRespDataLen = 0;
        psessionEntry->addIeParams.assocRespData_buff = NULL;

        vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
        psessionEntry->addIeParams.probeRespBCNDataLen = 0;
        psessionEntry->addIeParams.probeRespBCNData_buff = NULL;

        /*
         * limDelBss is also called as part of coalescing,
         * when we send DEL BSS followed by Add Bss msg.
         */
        pMac->lim.gLimIbssCoalescingHappened = false;
    }
    for(i = 1 ; i < pMac->lim.gLimAssocStaLimit ; i++)
    {
        pStaDs = dphGetHashEntry(pMac, i, &psessionEntry->dph.dphHashTable);
        if (NULL == pStaDs)
            continue;
        status = limDelSta(pMac, pStaDs, false, psessionEntry) ;
        if(eSIR_SUCCESS == status)
        {
            limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ;
            limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ;
        }
        else
        {
            limLog(pMac, LOGE, FL("limDelSta failed with Status : %d"), status);
            VOS_ASSERT(0) ;
        }
    }
    /* send a delBss to HAL and wait for a response */
    status = limDelBss(pMac, NULL,psessionEntry->bssIdx,psessionEntry);

    if (status != eSIR_SUCCESS)
    {
        PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d"), psessionEntry->bssIdx);)
        psessionEntry->limSmeState= prevState;

        MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState));

        limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_STOP_BSS_FAILURE,smesessionId,smetransactionId);
    }
}


/**--------------------------------------------------------------
\fn     __limProcessSmeStopBssReq

\brief  Wrapper for the function __limHandleSmeStopBssRequest
        This message will be defered until softmac come out of
        scan mode. Message should be handled even if we have
        detected radar in the current operating channel.
\param  pMac
\param  pMsg

\return TRUE - If we consumed the buffer
        FALSE - If have defered the message.
 ---------------------------------------------------------------*/
static tANI_BOOLEAN
__limProcessSmeStopBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    if (__limIsDeferedMsgForLearn(pMac, pMsg))
    {
        /**
         * If message defered, buffer is not consumed yet.
         * So return false
         */
        return eANI_BOOLEAN_FALSE;
    }
    __limHandleSmeStopBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr);
    return eANI_BOOLEAN_TRUE;
} /*** end __limProcessSmeStopBssReq() ***/


void limProcessSmeDelBssRsp(
    tpAniSirGlobal  pMac,
    tANI_U32        body,tpPESession psessionEntry)
{

    (void) body;
    SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
    limIbssDelete(pMac,psessionEntry);
    dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);
    limDeletePreAuthList(pMac);
    limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,psessionEntry->smeSessionId,psessionEntry->transactionId);
    return;
}


/**---------------------------------------------------------------
\fn     __limProcessSmeAssocCnfNew
\brief  This function handles SME_ASSOC_CNF/SME_REASSOC_CNF
\       in BTAMP AP.
\
\param  pMac
\param  msgType - message type
\param  pMsgBuf - a pointer to the SME message buffer
\return None
------------------------------------------------------------------*/

  void
__limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
{
    tSirSmeAssocCnf    assocCnf = {0};
    tpDphHashNode      pStaDs = NULL;
    tpPESession        psessionEntry= NULL;
    tANI_U8            sessionId;


    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE, FL("pMsgBuf is NULL "));
        goto end;
    }

    if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
        !__limIsSmeAssocCnfValid(&assocCnf))
    {
        limLog(pMac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message "));
        goto end;
    }

    if((psessionEntry = peFindSessionByBssid(pMac, assocCnf.bssId, &sessionId))== NULL)
    {
        limLog(pMac, LOGE, FL("session does not exist for given bssId"));
        goto end;
    }

    if ((!LIM_IS_AP_ROLE(psessionEntry) &&
         !LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) ||
        ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) &&
        (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) {
        limLog(pMac, LOGE,
               FL("Received unexpected message %X in state %X, in role %X"),
               msgType, psessionEntry->limSmeState,
               GET_LIM_SYSTEM_ROLE(psessionEntry));
        goto end;
    }

    pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable);

    if (pStaDs == NULL)
    {
        limLog(pMac, LOGE,
            FL("Received invalid message %X due to no STA context"
               "for aid %d, peer "),
               msgType, assocCnf.aid);
        limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);

        /*
        ** send a DISASSOC_IND message to WSM to make sure
        ** the state in WSM and LIM is the same
        **/
       limSendSmeDisassocNtf( pMac, assocCnf.peerMacAddr, eSIR_SME_STA_NOT_ASSOCIATED,
                              eLIM_PEER_ENTITY_DISASSOC, assocCnf.aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry);
       goto end;
    }
    if ((pStaDs &&
         (( !vos_mem_compare( (tANI_U8 *) pStaDs->staAddr,
                     (tANI_U8 *) assocCnf.peerMacAddr,
                     sizeof(tSirMacAddr)) ) ||
          (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) ||
          ((pStaDs->mlmStaContext.subType == LIM_ASSOC) &&
           (msgType != eWNI_SME_ASSOC_CNF)) ||
          ((pStaDs->mlmStaContext.subType == LIM_REASSOC) &&
           (msgType != eWNI_SME_ASSOC_CNF))))) // since softap is passing this as ASSOC_CNF and subtype differs
    {
        limLog(pMac, LOG1,
           FL("Received invalid message %X due to peerMacAddr mismatched"
              "or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer "
              "StaD mlmState : %d"),
              msgType, assocCnf.aid, pStaDs->mlmStaContext.mlmState);
        limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);
        goto end;
    }

    /*
    ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF
    ** has been received
    **/
    limLog(pMac, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer"));
    limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, pStaDs->assocId);

    if (assocCnf.statusCode == eSIR_SME_SUCCESS)
    {
        /* In BTAMP-AP, PE already finished the WDA_ADD_STA sequence
         * when it had received Assoc Request frame. Now, PE just needs to send
         * Association Response frame to the requesting BTAMP-STA.
         */
        pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
        pStaDs->mlmStaContext.owe_ie = assocCnf.owe_ie;
        pStaDs->mlmStaContext.owe_ie_len = assocCnf.owe_ie_len;
        limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) "), pStaDs->assocId);
        limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr,
                                  pStaDs->mlmStaContext.subType, pStaDs, psessionEntry);
        pStaDs->mlmStaContext.owe_ie = NULL;
        pStaDs->mlmStaContext.owe_ie_len = 0;
        goto end;
    } // (assocCnf.statusCode == eSIR_SME_SUCCESS)
    else
    {
        uint8_t add_pre_auth_context = true;
        // SME_ASSOC_CNF status is non-success, so STA is not allowed to be associated
        /*Since the HAL sta entry is created for denied STA we need to remove this HAL entry.So to do that set updateContext to 1*/
        tSirMacStatusCodes mac_status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;

        if(!pStaDs->mlmStaContext.updateContext)
           pStaDs->mlmStaContext.updateContext = 1;
        limLog(pMac, LOG1,
               FL("Receive Assoc Cnf with status Code : %d(assoc id=%d) Reason code: %d"),
               assocCnf.statusCode, pStaDs->assocId, assocCnf.mac_status_code);
        if (assocCnf.mac_status_code)
            mac_status_code = assocCnf.mac_status_code;
        if (assocCnf.mac_status_code == eSIR_MAC_INVALID_PMKID ||
            assocCnf.mac_status_code ==
            eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS)
            add_pre_auth_context = false;
        limRejectAssociation(pMac, pStaDs->staAddr,
                             pStaDs->mlmStaContext.subType,
                             add_pre_auth_context,
                             pStaDs->mlmStaContext.authType,
                             pStaDs->assocId, true,
                             mac_status_code,
                             psessionEntry);
    }

end:
    if((psessionEntry != NULL) && (pStaDs != NULL))
    {
        if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL )
        {
            if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame)
            {
                vos_mem_free(((tpSirAssocReq)
                   (psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame);
                ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL;
            }

            vos_mem_free(psessionEntry->parsedAssocReq[pStaDs->assocId]);
            psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
        }
    }
    vos_mem_free(assocCnf.owe_ie);
} /*** end __limProcessSmeAssocCnfNew() ***/

#ifdef SAP_AUTH_OFFLOAD
/**
 * __lim_process_sme_assoc_offload_cnf() station connect confirm
 * @pMac: SirGlobal handler
 * @msgType: message type
 * @pMsgBuf: message body
 *
 * This function handles the station connect confirm of
 * Software AP authentication offload feature
 *
 * Return: None
 */
static void
__lim_process_sme_assoc_offload_cnf(tpAniSirGlobal pmac,
                               tANI_U32 msg_type,
                               tANI_U32 *pmsg_buf)
{
    tSirSmeAssocCnf assoc_cnf;
    tpDphHashNode sta_ds = NULL;
    tpPESession psession_entry= NULL;
    tANI_U8 session_id;
    tANI_U16 aid=0;

    if(pmsg_buf == NULL) {
        limLog(pmac, LOGE, FL("pmsg_buf is NULL "));
        goto end;
    }

    if ((limAssocCnfSerDes(pmac, &assoc_cnf, (tANI_U8 *) pmsg_buf) ==
        eSIR_FAILURE) || !__limIsSmeAssocCnfValid(&assoc_cnf)) {
        limLog(pmac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message "));
        goto end;
    }

    if((psession_entry =
        peFindSessionByBssid(pmac, assoc_cnf.bssId, &session_id))== NULL) {
        limLog(pmac, LOGE, FL("session does not exist for given bssId"));
        goto end;
    }

    if ((!LIM_IS_AP_ROLE(psession_entry) &&
         !LIM_IS_BT_AMP_AP_ROLE(psession_entry)) ||
        ((psession_entry->limSmeState != eLIM_SME_NORMAL_STATE) &&
        (psession_entry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) {
        limLog(pmac, LOGE,
               FL("Received unexpected message %X in state %X, in role %X"),
               msg_type, psession_entry->limSmeState,
               GET_LIM_SYSTEM_ROLE(psession_entry));
        goto end;
    }

    sta_ds = dphGetHashEntry(pmac,
                             assoc_cnf.aid,
                             &psession_entry->dph.dphHashTable);
    if (sta_ds != NULL) {
        aid = sta_ds->assocId;
        limDeactivateAndChangePerStaIdTimer(pmac,
                                            eLIM_CNF_WAIT_TIMER,
                                            aid);
    }

end:
    if((psession_entry != NULL) && (sta_ds != NULL)) {
        if ( psession_entry->parsedAssocReq[aid] != NULL ) {
            if ( ((tpSirAssocReq)
                (psession_entry->parsedAssocReq[aid]))->assocReqFrame) {
                vos_mem_free(((tpSirAssocReq)
                    (psession_entry->parsedAssocReq[aid]))->assocReqFrame);
                ((tpSirAssocReq)
                    (psession_entry->parsedAssocReq[aid]))->assocReqFrame =
                    NULL;
            }
            vos_mem_free(psession_entry->parsedAssocReq[aid]);
            psession_entry->parsedAssocReq[aid] = NULL;
        }
    }

} /*** end __lim_process_sme_assoc_offload_cnf() ***/
#endif /* SAP_AUTH_OFFLOAD */

static void
__limProcessSmeAddtsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpDphHashNode   pStaDs;
    tSirMacAddr     peerMac;
    tpSirAddtsReq   pSirAddts;
    tANI_U32        timeout;
    tpPESession     psessionEntry;
    tANI_U8         sessionId;  //PE sessionId
    tANI_U8         smesessionId;
    tANI_U16        smetransactionId;


    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
           return;
    }

    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);

    pSirAddts = (tpSirAddtsReq) pMsgBuf;

    if((psessionEntry = peFindSessionByBssid(pMac, pSirAddts->bssId,&sessionId))== NULL)
    {
        limLog(pMac, LOGE, "Session Does not exist for given bssId");
        return;
    }
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT



    /* if sta
     *  - verify assoc state
     *  - send addts request to ap
     *  - wait for addts response from ap
     * if ap, just ignore with error log
     */
    PELOG1(limLog(pMac, LOG1,
           FL("Received SME_ADDTS_REQ (TSid %d, UP %d)"),
           pSirAddts->req.tspec.tsinfo.traffic.tsid,
           pSirAddts->req.tspec.tsinfo.traffic.userPrio);)

    if (!LIM_IS_STA_ROLE(psessionEntry) &&
        !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
        PELOGE(limLog(pMac, LOGE, "AddTs received on AP - ignoring");)
        limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
                smesessionId,smetransactionId);
        return;
    }

    pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);

    if(pStaDs == NULL)
    {
        PELOGE(limLog(pMac, LOGE, "Cannot find AP context for addts req");)
        limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
            smesessionId,smetransactionId);
        return;
    }

    if ((! pStaDs->valid) ||
        (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE))
    {
        PELOGE(limLog(pMac, LOGE, "AddTs received in invalid MLM state");)
        limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
            smesessionId,smetransactionId);
        return;
    }

    pSirAddts->req.wsmTspecPresent = 0;
    pSirAddts->req.wmeTspecPresent = 0;
    pSirAddts->req.lleTspecPresent = 0;

    if ((pStaDs->wsmEnabled) &&
        (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA))
        pSirAddts->req.wsmTspecPresent = 1;
    else if (pStaDs->wmeEnabled)
        pSirAddts->req.wmeTspecPresent = 1;
    else if (pStaDs->lleEnabled)
        pSirAddts->req.lleTspecPresent = 1;
    else
    {
        PELOGW(limLog(pMac, LOGW, FL("ADDTS_REQ ignore - qos is disabled"));)
        limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
            smesessionId,smetransactionId);
        return;
    }

    if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
        (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
    {
        limLog(pMac, LOGE, "AddTs received in invalid LIMsme state (%d)",
              psessionEntry->limSmeState);
        limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
            smesessionId,smetransactionId);
        return;
    }

    if (pMac->lim.gLimAddtsSent)
    {
        limLog(pMac, LOGE, "Addts (token %d, tsid %d, up %d) is still pending",
               pMac->lim.gLimAddtsReq.req.dialogToken,
               pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
               pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.userPrio);
        limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
            smesessionId,smetransactionId);
        return;
    }

    sirCopyMacAddr(peerMac,psessionEntry->bssId);

    // save the addts request
    pMac->lim.gLimAddtsSent = true;
    vos_mem_copy( (tANI_U8 *) &pMac->lim.gLimAddtsReq, (tANI_U8 *) pSirAddts, sizeof(tSirAddtsReq));

    // ship out the message now
    limSendAddtsReqActionFrame(pMac, peerMac, &pSirAddts->req,
            psessionEntry);
    PELOG1(limLog(pMac, LOG1, "Sent ADDTS request");)

    // start a timer to wait for the response
    if (pSirAddts->timeout)
        timeout = pSirAddts->timeout;
    else if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &timeout) != eSIR_SUCCESS)
    {
        limLog(pMac, LOGP, FL("Unable to get Cfg param %d (Addts Rsp Timeout)"),
               WNI_CFG_ADDTS_RSP_TIMEOUT);
        return;
    }

    timeout = SYS_MS_TO_TICKS(timeout);
    if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0) != TX_SUCCESS)
    {
        limLog(pMac, LOGP, FL("AddtsRsp timer change failed!"));
        return;
    }
    pMac->lim.gLimAddtsRspTimerCount++;
    if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
                                pMac->lim.gLimAddtsRspTimerCount) != TX_SUCCESS)
    {
        limLog(pMac, LOGP, FL("AddtsRsp timer change failed!"));
        return;
    }
    MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER));

    //add the sessionId to the timer object
    pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId;
    if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS)
    {
        limLog(pMac, LOGP, FL("AddtsRsp timer activation failed!"));
        return;
    }
    return;
}


static void
__limProcessSmeDeltsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirMacAddr     peerMacAddr;
    tANI_U8         ac;
    tSirMacTSInfo   *pTsinfo;
    tpSirDeltsReq   pDeltsReq = (tpSirDeltsReq) pMsgBuf;
    tpDphHashNode   pStaDs = NULL;
    tpPESession     psessionEntry;
    tANI_U8         sessionId;
    tANI_U32        status = eSIR_SUCCESS;
    tANI_U8         smesessionId;
    tANI_U16        smetransactionId;

    limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);

    if((psessionEntry = peFindSessionByBssid(pMac, pDeltsReq->bssId, &sessionId))== NULL)
    {
        limLog(pMac, LOGE, "Session Does not exist for given bssId");
        status = eSIR_FAILURE;
        goto end;
    }
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT


    if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDeltsReq, peerMacAddr,psessionEntry))
    {
        PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed"));)
        status = eSIR_FAILURE;
        limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_FAILURE,psessionEntry,smesessionId,smetransactionId);
        return;
    }

    PELOG1(limLog(pMac, LOG1, FL("Sent DELTS request to station with "
                  "assocId = %d MacAddr = "MAC_ADDRESS_STR),
                  pDeltsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));)

    limSendDeltsReqActionFrame(pMac, peerMacAddr, pDeltsReq->req.wmeTspecPresent, &pDeltsReq->req.tsinfo, &pDeltsReq->req.tspec,
              psessionEntry);

    pTsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo : &pDeltsReq->req.tsinfo;

    /* We've successfully send DELTS frame to AP. Update the
     * dynamic UAPSD mask. The AC for this TSPEC to be deleted
     * is no longer trigger enabled or delivery enabled
     */
    if(!pMac->psOffloadEnabled)
    {
        limSetTspecUapsdMask(pMac, pTsinfo, CLEAR_UAPSD_MASK);

        /* We're deleting the TSPEC, so this particular AC is no longer
         * admitted.  PE needs to downgrade the EDCA
         * parameters(for the AC for which TS is being deleted) to the
         * next best AC for which ACM is not enabled, and send the
         * updated values to HAL.
         */
        ac = upToAc(pTsinfo->traffic.userPrio);

        if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK)
        {
            pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
        }
        else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK)
        {
            pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
        }
        else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR)
        {
            pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
            pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
        }
    }
    else
    {
        limSetTspecUapsdMaskPerSession(pMac, psessionEntry,
                                       pTsinfo, CLEAR_UAPSD_MASK);

        /* We're deleting the TSPEC, so this particular AC is no longer
         * admitted.  PE needs to downgrade the EDCA
         * parameters(for the AC for which TS is being deleted) to the
         * next best AC for which ACM is not enabled, and send the
         * updated values to HAL.
         */
        ac = upToAc(pTsinfo->traffic.userPrio);

        if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK)
        {
            psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
        }
        else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK)
        {
            psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
        }
        else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR)
        {
            psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
            psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
        }
    }

    limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);

    pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
    if (pStaDs != NULL)
    {
        limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive,
                          pStaDs->bssId);
        status = eSIR_SUCCESS;
    }
    else
    {
        limLog(pMac, LOGE, FL("Self entry missing in Hash Table "));
     status = eSIR_FAILURE;
    }
#ifdef FEATURE_WLAN_ESE
#ifdef FEATURE_WLAN_ESE_UPLOAD
    limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0);
#else
    limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER);
#endif /* FEATURE_WLAN_ESE_UPLOAD */
#endif

    // send an sme response back
    end:
         limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_SUCCESS,psessionEntry,smesessionId,smetransactionId);
}


void
limProcessSmeAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param)
{
    //fetch the sessionEntry based on the sessionId
    tpPESession psessionEntry;
    if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAddtsRspTimer.sessionId))== NULL)
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID"));
        return;
    }

    if (!LIM_IS_STA_ROLE(psessionEntry) &&
        !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
        limLog(pMac, LOGW, "AddtsRspTimeout in non-Sta role (%d)",
               GET_LIM_SYSTEM_ROLE(psessionEntry));
        pMac->lim.gLimAddtsSent = false;
        return;
    }

    if (! pMac->lim.gLimAddtsSent)
    {
        PELOGW(limLog(pMac, LOGW, "AddtsRspTimeout but no AddtsSent");)
        return;
    }

    if (param != pMac->lim.gLimAddtsRspTimerCount)
    {
        limLog(pMac, LOGE, FL("Invalid AddtsRsp Timer count %d (exp %d)"),
               param, pMac->lim.gLimAddtsRspTimerCount);
        return;
    }

    // this a real response timeout
    pMac->lim.gLimAddtsSent = false;
    pMac->lim.gLimAddtsRspTimerCount++;

    limSendSmeAddtsRsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT, psessionEntry, pMac->lim.gLimAddtsReq.req.tspec,
            psessionEntry->smeSessionId, psessionEntry->transactionId);
}


/**
 * __limProcessSmeStatsRequest()
 *
 *FUNCTION:
 *
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */
static void
__limProcessSmeStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpAniGetStatsReq    pStatsReq;
    tSirMsgQ msgQ;
    tpPESession psessionEntry;
    tANI_U8     sessionId;


    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
           return;
    }

    pStatsReq = (tpAniGetStatsReq) pMsgBuf;

    if((psessionEntry = peFindSessionByBssid(pMac,pStatsReq->bssId,&sessionId))== NULL)
    {
        limLog(pMac, LOGE, FL("session does not exist for given bssId"));
        vos_mem_free( pMsgBuf );
        pMsgBuf = NULL;
        return;
    }



    switch(pStatsReq->msgType)
    {
        //Add Lim stats here. and send reqsponse.

        //HAL maintained Stats.
        case eWNI_SME_STA_STAT_REQ:
            msgQ.type = WDA_STA_STAT_REQ;
            break;
        case eWNI_SME_AGGR_STAT_REQ:
            msgQ.type = WDA_AGGR_STAT_REQ;
            break;
        case eWNI_SME_GLOBAL_STAT_REQ:
            msgQ.type = WDA_GLOBAL_STAT_REQ;
            break;
        case eWNI_SME_STAT_SUMM_REQ:
            msgQ.type = WDA_STAT_SUMM_REQ;
            break;
        default: //Unknown request.
            PELOGE(limLog(pMac, LOGE, "Unknown Statistics request");)
            vos_mem_free( pMsgBuf );
            pMsgBuf = NULL;
            return;
    }

    msgQ.reserved = 0;
    msgQ.bodyptr = pMsgBuf;
    msgQ.bodyval = 0;
    if(NULL == psessionEntry)
    {
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }
    if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){
        limLog(pMac, LOGP, "Unable to forward request");
        vos_mem_free( pMsgBuf );
        pMsgBuf = NULL;
        return;
    }

    return;
}


/**
 * __limProcessSmeGetStatisticsRequest()
 *
 *FUNCTION:
 *
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */
static void
__limProcessSmeGetStatisticsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpAniGetPEStatsReq    pPEStatsReq;
    tSirMsgQ msgQ;

    pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf;

    msgQ.type = WDA_GET_STATISTICS_REQ;

    msgQ.reserved = 0;
    msgQ.bodyptr = pMsgBuf;
    msgQ.bodyval = 0;
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));

    if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){
        vos_mem_free( pMsgBuf );
        pMsgBuf = NULL;
        limLog(pMac, LOGP, "Unable to forward request");
        return;
    }

    return;
}

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/**
 *FUNCTION: __limProcessSmeGetTsmStatsRequest()
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */
static void
__limProcessSmeGetTsmStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirMsgQ               msgQ;

    msgQ.type = WDA_TSM_STATS_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pMsgBuf;
    msgQ.bodyval = 0;
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));

    if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){
        vos_mem_free( pMsgBuf );
        pMsgBuf = NULL;
        limLog(pMac, LOGP, "Unable to forward request");
        return;
    }
}
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */

static void
__limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirUpdateAPWPSIEsReq  pUpdateAPWPSIEsReq;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId;  //PE sessionID

    PELOG1(limLog(pMac, LOG1,
           FL("received UPDATE_APWPSIEs_REQ message")););

    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    pUpdateAPWPSIEsReq = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
    if ( NULL == pUpdateAPWPSIEsReq )
    {
        limLog(pMac, LOGP, FL("call to AllocateMemory failed for pUpdateAPWPSIEsReq"));
        return;
    }

    if ((limUpdateAPWPSIEsReqSerDes(pMac, pUpdateAPWPSIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
    {
        limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message"));
        goto end;
    }

    if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPSIEsReq->bssId, &sessionId)) == NULL)
    {
        limLog(pMac, LOGW, FL("Session does not exist for given BSSID"));
        goto end;
    }

    vos_mem_copy( &psessionEntry->APWPSIEs, &pUpdateAPWPSIEsReq->APWPSIEs, sizeof(tSirAPWPSIEs));

    schSetFixedBeaconFields(pMac, psessionEntry);
    limSendBeaconInd(pMac, psessionEntry);

end:
    vos_mem_free( pUpdateAPWPSIEsReq);
    return;
} /*** end __limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/

void
limSendVdevRestart(tpAniSirGlobal pMac,
                   tpPESession psessionEntry,
                   tANI_U8 sessionId)
{
    tpHalHiddenSsidVdevRestart pHalHiddenSsidVdevRestart = NULL;
    tSirMsgQ       msgQ;
    tSirRetStatus  retCode = eSIR_SUCCESS;

    if ( psessionEntry == NULL )
    {
        PELOGE(limLog(pMac, LOGE, "%s:%d: Invalid parameters", __func__, __LINE__ );)
        return;
    }

    pHalHiddenSsidVdevRestart = vos_mem_malloc(sizeof(tHalHiddenSsidVdevRestart));
    if (NULL == pHalHiddenSsidVdevRestart)
    {
        PELOGE(limLog(pMac, LOGE, "%s:%d: Unable to allocate memory", __func__, __LINE__ );)
        return;
    }

    pHalHiddenSsidVdevRestart->ssidHidden = psessionEntry->ssidHidden;
    pHalHiddenSsidVdevRestart->sessionId = sessionId;

    msgQ.type = WDA_HIDDEN_SSID_VDEV_RESTART;
    msgQ.bodyptr = pHalHiddenSsidVdevRestart;
    msgQ.bodyval = 0;

    retCode = wdaPostCtrlMsg(pMac, &msgQ);
    if (eSIR_SUCCESS != retCode)
    {
        PELOGE(limLog(pMac, LOGE, "%s:%d: wdaPostCtrlMsg() failed", __func__, __LINE__ );)
        vos_mem_free(pHalHiddenSsidVdevRestart);
    }
}
static void __lim_process_roam_scan_offload_req(tpAniSirGlobal mac_ctx,
	tANI_U32 *msg_buf)
{
	tpPESession pe_session;
	tSirMsgQ       wma_msg;
	tSirRetStatus  status;
	tSirRoamOffloadScanReq *msg, *req_buffer;

	msg = (tSirRoamOffloadScanReq *)msg_buf;
	pe_session = pe_find_session_by_sme_session_id(mac_ctx,
			msg->sessionId);

	/* Set roaming_in_progress flag according to the command */
	if ( pe_session && (msg->Command == ROAM_SCAN_OFFLOAD_START ||
		msg->Command == ROAM_SCAN_OFFLOAD_RESTART ||
	            msg->Command == ROAM_SCAN_OFFLOAD_STOP))
	pe_session->roaming_in_progress = false;

	req_buffer = vos_mem_malloc(sizeof(tSirRoamOffloadScanReq));
	if (NULL == req_buffer) {
		limLog(mac_ctx, LOGE,
			FL("Mem Alloc failed for req buffer"));
		return;
	}

	*req_buffer = *msg;

	vos_mem_zero(&wma_msg, sizeof(tSirMsgQ));
	wma_msg.type = WDA_ROAM_SCAN_OFFLOAD_REQ;
	wma_msg.bodyptr = req_buffer;

	status = wdaPostCtrlMsg(mac_ctx, &wma_msg);
	if (eSIR_SUCCESS != status)
	{
		limLog(mac_ctx, LOGE,
			FL("Posting WDA_ROAM_SCAN_OFFLOAD_REQ failed"));
			vos_mem_free(req_buffer);
	}
}
static void
__limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirUpdateParams       pUpdateParams;
    tpPESession             psessionEntry;

    PELOG1(limLog(pMac, LOG1,
           FL("received HIDE_SSID message")););

    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    pUpdateParams = (tpSirUpdateParams)pMsgBuf;

    psessionEntry = pe_find_session_by_sme_session_id(pMac,
                                          pUpdateParams->sessionId);
    if(NULL == psessionEntry) {
        limLog(pMac, LOGE, "Session does not exist for given sme sessionId %d",
               pUpdateParams->sessionId);
        return;
    }

    if (psessionEntry->ssidHidden != pUpdateParams->ssidHidden) {
            /* Update the session entry */
            psessionEntry->ssidHidden = pUpdateParams->ssidHidden;
    } else {
            PELOG1(limLog(pMac, LOG1,
                   FL("Same config already present!")));
            return;
    }

    /* Send vdev restart */
    limSendVdevRestart(pMac, psessionEntry, pUpdateParams->sessionId);

    /* Update beacon */
    schSetFixedBeaconFields(pMac, psessionEntry);
    limSendBeaconInd(pMac, psessionEntry);

    return;
} /*** end __limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/

static void
__limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirUpdateAPWPARSNIEsReq  pUpdateAPWPARSNIEsReq;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId;  //PE sessionID

    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    pUpdateAPWPARSNIEsReq = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
    if ( NULL == pUpdateAPWPARSNIEsReq )
    {
        limLog(pMac, LOGP, FL("call to AllocateMemory failed for pUpdateAPWPARSNIEsReq"));
        return;
    }

    if ((limUpdateAPWPARSNIEsReqSerDes(pMac, pUpdateAPWPARSNIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
    {
        limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message"));
        goto end;
    }

    if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPARSNIEsReq->bssId, &sessionId)) == NULL)
    {
        limLog(pMac, LOGW, FL("Session does not exist for given BSSID"));
        goto end;
    }

    vos_mem_copy(&psessionEntry->pLimStartBssReq->rsnIE,
                 &pUpdateAPWPARSNIEsReq->APWPARSNIEs, sizeof(tSirRSNie));

    limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac, &psessionEntry->pLimStartBssReq->rsnIE, psessionEntry);

    psessionEntry->pLimStartBssReq->privacy = 1;
    psessionEntry->privacy = 1;

    schSetFixedBeaconFields(pMac, psessionEntry);
    limSendBeaconInd(pMac, psessionEntry);

end:
    vos_mem_free(pUpdateAPWPARSNIEsReq);
    return;
} /*** end __limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/

/*
Update the beacon Interval dynamically if beaconInterval is different in MCC
*/
static void
__limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirChangeBIParams     pChangeBIParams;
    tpPESession             psessionEntry;
    tANI_U8  sessionId = 0;
    tUpdateBeaconParams beaconParams;

    PELOG1(limLog(pMac, LOG1,
           FL("received Update Beacon Interval message")););

    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
    pChangeBIParams = (tpSirChangeBIParams)pMsgBuf;

    if((psessionEntry = peFindSessionByBssid(pMac, pChangeBIParams->bssId, &sessionId)) == NULL)
    {
        limLog(pMac, LOGE, FL("Session does not exist for given BSSID"));
        return;
    }

    /*Update sessionEntry Beacon Interval*/
    if(psessionEntry->beaconParams.beaconInterval !=
                                        pChangeBIParams->beaconInterval )
    {
       psessionEntry->beaconParams.beaconInterval = pChangeBIParams->beaconInterval;
    }

    /*Update sch beaconInterval*/
    if(pMac->sch.schObject.gSchBeaconInterval !=
                                        pChangeBIParams->beaconInterval )
    {
        pMac->sch.schObject.gSchBeaconInterval = pChangeBIParams->beaconInterval;

        PELOG1(limLog(pMac, LOG1,
               FL("LIM send update BeaconInterval Indication : %d"),pChangeBIParams->beaconInterval););

        if (VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)
        {
            /* Update beacon */
            schSetFixedBeaconFields(pMac, psessionEntry);

            beaconParams.bssIdx = psessionEntry->bssIdx;
            //Set change in beacon Interval
            beaconParams.beaconInterval = pChangeBIParams->beaconInterval;
            beaconParams.paramChangeBitmap = PARAM_BCN_INTERVAL_CHANGED;
            limSendBeaconParams(pMac, &beaconParams, psessionEntry);
        }
    }

    return;
} /*** end __limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/

#ifdef QCA_HT_2040_COEX
static void __limProcessSmeSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirSetHT2040Mode     pSetHT2040Mode;
    tpPESession             psessionEntry;
    tANI_U8  sessionId = 0;
    vos_msg_t msg;
    tUpdateVHTOpMode *pHtOpMode = NULL;
    tANI_U16                staId = 0;
    tpDphHashNode pStaDs = NULL;

    PELOG1(limLog(pMac, LOG1,
           FL("received Set HT 20/40 mode message")););
    if(pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    pSetHT2040Mode = (tpSirSetHT2040Mode)pMsgBuf;

    if((psessionEntry = peFindSessionByBssid(pMac, pSetHT2040Mode->bssId,
                                                   &sessionId)) == NULL)
    {
        limLog(pMac, LOG1, FL("Session does not exist for given BSSID "));
        limPrintMacAddr(pMac, pSetHT2040Mode->bssId, LOG1);
        return;
    }

    limLog(pMac, LOG1, FL("Update session entry for cbMod=%d"),
                           pSetHT2040Mode->cbMode);
    /*Update sessionEntry HT related fields*/
    switch(pSetHT2040Mode->cbMode)
    {
    case PHY_SINGLE_CHANNEL_CENTERED:
        psessionEntry->htSecondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
        psessionEntry->htRecommendedTxWidthSet = 0;
        if (pSetHT2040Mode->obssEnabled)
            psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
        else
            psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
        break;
    case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
        psessionEntry->htSecondaryChannelOffset = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
        psessionEntry->htRecommendedTxWidthSet = 1;
        break;
    case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
        psessionEntry->htSecondaryChannelOffset = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
        psessionEntry->htRecommendedTxWidthSet = 1;
        break;
    default:
        limLog(pMac, LOGE,FL("Invalid cbMode"));
        return;
    }

    /* Update beacon */
    schSetFixedBeaconFields(pMac, psessionEntry);
    limSendBeaconInd(pMac, psessionEntry);

    /* update OP Mode for each associated peer */
    for (staId = 0; staId < psessionEntry->dph.dphHashTable.size; staId++)
    {
        pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable);
        if (NULL == pStaDs)
            continue;

        if (pStaDs->valid && pStaDs->htSupportedChannelWidthSet)
        {
            pHtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode));
            if ( NULL == pHtOpMode )
            {
                limLog(pMac, LOGE,
                      FL("%s: Not able to allocate memory for setting OP mode"),
                      __func__);
                return;
            }
            pHtOpMode->opMode = (psessionEntry->htSecondaryChannelOffset ==
                          PHY_SINGLE_CHANNEL_CENTERED)?
                          eHT_CHANNEL_WIDTH_20MHZ:eHT_CHANNEL_WIDTH_40MHZ;
            pHtOpMode->staId = staId;
            vos_mem_copy(pHtOpMode->peer_mac, &pStaDs->staAddr,
                 sizeof(tSirMacAddr));
            pHtOpMode->smesessionId = sessionId;
            pHtOpMode->chanMode = wma_chan_to_mode(
                                     psessionEntry->currentOperChannel,
                                     psessionEntry->htSecondaryChannelOffset,
                                     psessionEntry->vhtCapability,
                                     psessionEntry->dot11mode);

            msg.type     = WDA_UPDATE_OP_MODE;
            msg.reserved = 0;
            msg.bodyptr  = pHtOpMode;
            if (!VOS_IS_STATUS_SUCCESS(
                     vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
            {
                 limLog(pMac, LOGE,
                   FL("%s: Not able to post WDA_UPDATE_OP_MODE message to WDA"),
                   __func__);
                 vos_mem_free(pHtOpMode);
                 return;
            }
            limLog(pMac, LOG1,
                        FL("%s: Notifed FW about OP mode: %d for staId=%d"),
                        __func__, pHtOpMode->opMode, staId);

         }
         else
            limLog(pMac, LOG1, FL("%s: station %d does not support HT40\n"),
                        __func__, staId);
    }

    return;
}
#endif

// --------------------------------------------------------------------
/**
 * __limProcessReportMessage
 *
 * FUNCTION:  Processes the next received Radio Resource Management message
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param None
 * @return None
 */

void __limProcessReportMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
#ifdef WLAN_FEATURE_VOWIFI
   switch (pMsg->type)
   {
      case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
         rrmProcessNeighborReportReq( pMac, pMsg->bodyptr );
         break;
      case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
        {
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
         tpSirBeaconReportXmitInd pBcnReport=NULL;
         tpPESession psessionEntry=NULL;
         tANI_U8 sessionId;
         tpEsePEContext pEseContext = NULL;

         if(pMsg->bodyptr == NULL)
         {
            limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
            return;
         }
         pBcnReport = (tpSirBeaconReportXmitInd )pMsg->bodyptr;
         if((psessionEntry = peFindSessionByBssid(pMac, pBcnReport->bssId,&sessionId))== NULL)
         {
            limLog(pMac, LOGE, "Session Does not exist for given bssId");
            return;
         }

         pEseContext = &psessionEntry->eseContext;

         if (psessionEntry->isESEconnection && pEseContext->curMeasReq.isValid)
             eseProcessBeaconReportXmit( pMac, pMsg->bodyptr);
         else
#endif
             rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr );
        }
        break;
      default:
        limLog(pMac, LOGE, FL("Invalid msg type:%d"), pMsg->type);
   }
#endif
}

#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_VOWIFI)
// --------------------------------------------------------------------
/**
 * limSendSetMaxTxPowerReq
 *
 * FUNCTION:  Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power.
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param txPower txPower to be set.
 * @param pSessionEntry session entry.
 * @return None
 */
tSirRetStatus
limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry )
{
   tpMaxTxPowerParams pMaxTxParams = NULL;
   tSirRetStatus  retCode = eSIR_SUCCESS;
   tSirMsgQ       msgQ;

   if( pSessionEntry == NULL )
   {
      PELOGE(limLog(pMac, LOGE, "%s:%d: Inavalid parameters", __func__, __LINE__ );)
      return eSIR_FAILURE;
   }

   pMaxTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams));
   if ( NULL == pMaxTxParams )
   {
      limLog( pMac, LOGP, "%s:%d:Unable to allocate memory for pMaxTxParams ", __func__, __LINE__);
      return eSIR_MEM_ALLOC_FAILED;

   }
#if defined(WLAN_VOWIFI_DEBUG) || defined(FEATURE_WLAN_ESE)
   PELOG1(limLog( pMac, LOG1, "%s:%d: Allocated memory for pMaxTxParams...will be freed in other module", __func__, __LINE__ );)
#endif
   if( pMaxTxParams == NULL )
   {
      limLog( pMac, LOGE, "%s:%d: pMaxTxParams is NULL", __func__, __LINE__);
      return eSIR_FAILURE;
   }
   pMaxTxParams->power = txPower;
   vos_mem_copy( pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
   vos_mem_copy( pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) );

   msgQ.type = WDA_SET_MAX_TX_POWER_REQ;
   msgQ.bodyptr = pMaxTxParams;
   msgQ.bodyval = 0;
   PELOG1(limLog(pMac, LOG1, FL("Posting WDA_SET_MAX_TX_POWER_REQ to WDA"));)
   MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, msgQ.type));
   retCode = wdaPostCtrlMsg(pMac, &msgQ);
   if (eSIR_SUCCESS != retCode)
   {
      PELOGE(limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));)
      vos_mem_free(pMaxTxParams);
   }
   return retCode;
}
#endif

/**
 * __limProcessSmeAddStaSelfReq()
 *
 *FUNCTION:
 * This function is called to process SME_ADD_STA_SELF_REQ message
 * from SME. It sends a SIR_HAL_ADD_STA_SELF_REQ message to HAL.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeAddStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
   tSirMsgQ msg;
   tpAddStaSelfParams pAddStaSelfParams;
   tpSirSmeAddStaSelfReq pSmeReq = (tpSirSmeAddStaSelfReq) pMsgBuf;

   pAddStaSelfParams = vos_mem_malloc(sizeof(tAddStaSelfParams));
   if ( NULL == pAddStaSelfParams )
   {
      limLog( pMac, LOGP, FL("Unable to allocate memory for tAddSelfStaParams") );
      return;
   }

   vos_mem_copy( pAddStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) );
   pAddStaSelfParams->currDeviceMode = pSmeReq->currDeviceMode;
   pAddStaSelfParams->sessionId = pSmeReq->sessionId;
   pAddStaSelfParams->type = pSmeReq->type;
   pAddStaSelfParams->subType = pSmeReq->subType;
   pAddStaSelfParams->pkt_err_disconn_th = pSmeReq->pkt_err_disconn_th;
   pAddStaSelfParams->nss_2g = pSmeReq->nss_2g;
   pAddStaSelfParams->nss_5g = pSmeReq->nss_5g;
   pAddStaSelfParams->tx_aggregation_size = pSmeReq->tx_aggregation_size;
   pAddStaSelfParams->rx_aggregation_size = pSmeReq->rx_aggregation_size;
   pAddStaSelfParams->tx_aggr_sw_retry_threshhold_be =
                      pSmeReq->tx_aggr_sw_retry_threshhold_be;
   pAddStaSelfParams->tx_aggr_sw_retry_threshhold_bk =
                      pSmeReq->tx_aggr_sw_retry_threshhold_bk;
   pAddStaSelfParams->tx_aggr_sw_retry_threshhold_vi =
                      pSmeReq->tx_aggr_sw_retry_threshhold_vi;
   pAddStaSelfParams->tx_aggr_sw_retry_threshhold_vo =
                      pSmeReq->tx_aggr_sw_retry_threshhold_vo;
   pAddStaSelfParams->tx_non_aggr_sw_retry_threshhold_be =
                      pSmeReq->tx_non_aggr_sw_retry_threshhold_be;
   pAddStaSelfParams->tx_non_aggr_sw_retry_threshhold_bk =
                      pSmeReq->tx_non_aggr_sw_retry_threshhold_bk;
   pAddStaSelfParams->tx_non_aggr_sw_retry_threshhold_vi =
                      pSmeReq->tx_non_aggr_sw_retry_threshhold_vi;
   pAddStaSelfParams->tx_non_aggr_sw_retry_threshhold_vo =
                      pSmeReq->tx_non_aggr_sw_retry_threshhold_vo;

   msg.type = SIR_HAL_ADD_STA_SELF_REQ;
   msg.reserved = 0;
   msg.bodyptr =  pAddStaSelfParams;
   msg.bodyval = 0;

   PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_ADD_STA_SELF_REQ msg to HAL"));)
      MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

   if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
   {
      limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed"));
   }
   return;
} /*** end __limProcessAddStaSelfReq() ***/


/**
 * __limProcessSmeDelStaSelfReq()
 *
 *FUNCTION:
 * This function is called to process SME_DEL_STA_SELF_REQ message
 * from SME. It sends a SIR_HAL_DEL_STA_SELF_REQ message to HAL.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */

static void
__limProcessSmeDelStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
   tSirMsgQ msg;
   tpDelStaSelfParams pDelStaSelfParams;
   tpSirSmeDelStaSelfReq pSmeReq = (tpSirSmeDelStaSelfReq) pMsgBuf;

   pDelStaSelfParams = vos_mem_malloc(sizeof( tDelStaSelfParams));
   if ( NULL == pDelStaSelfParams )
   {
      limLog( pMac, LOGP, FL("Unable to allocate memory for tDelStaSelfParams") );
      return;
   }

   vos_mem_copy( pDelStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) );

   pDelStaSelfParams->sessionId = pSmeReq->sessionId;
   msg.type = SIR_HAL_DEL_STA_SELF_REQ;
   msg.reserved = 0;
   msg.bodyptr =  pDelStaSelfParams;
   msg.bodyval = 0;

   PELOGW(limLog(pMac, LOG1,
          FL("sending SIR_HAL_DEL_STA_SELF_REQ msg to HAL"));)
   MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

   if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
   {
      limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed"));
      vos_mem_free(pDelStaSelfParams);
   }
   return;
} /*** end __limProcessSmeDelStaSelfReq() ***/


/**
 * __limProcessSmeRegisterMgmtFrameReq()
 *
 *FUNCTION:
 * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message
 * from SME. It Register this information within PE.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return None
 */
static void
__limProcessSmeRegisterMgmtFrameReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    VOS_STATUS vosStatus;
    tpSirRegisterMgmtFrame pSmeReq = (tpSirRegisterMgmtFrame)pMsgBuf;
    tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL;
    tANI_BOOLEAN match = VOS_FALSE;
    PELOG1(limLog(pMac, LOG1,
           FL("registerFrame %d, frameType %d, matchLen %d"),
            pSmeReq->registerFrame, pSmeReq->frameType, pSmeReq->matchLen);)

    /* First check whether entry exists already*/

    vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
            (vos_list_node_t**)&pLimMgmtRegistration);

    while(pLimMgmtRegistration != NULL)
    {
        if (pLimMgmtRegistration->frameType == pSmeReq->frameType)
        {
            if(pSmeReq->matchLen)
            {
                if (pLimMgmtRegistration->matchLen == pSmeReq->matchLen)
                {
                    if (vos_mem_compare( pLimMgmtRegistration->matchData,
                                pSmeReq->matchData, pLimMgmtRegistration->matchLen))
                    {
                        /* found match! */
                        match = VOS_TRUE;
                        break;
                    }
                }
            }
            else
            {
                /* found match! */
                match = VOS_TRUE;
                break;
            }
        }
        vosStatus = vos_list_peek_next (
                &pMac->lim.gLimMgmtFrameRegistratinQueue,
                (vos_list_node_t*) pLimMgmtRegistration,
                (vos_list_node_t**) &pNext );

        pLimMgmtRegistration = pNext;
        pNext = NULL;

    }

    if (match)
    {
        vos_list_remove_node(&pMac->lim.gLimMgmtFrameRegistratinQueue,
                (vos_list_node_t*)pLimMgmtRegistration);
        vos_mem_free(pLimMgmtRegistration);
    }

    if(pSmeReq->registerFrame)
    {
        pLimMgmtRegistration = vos_mem_malloc(sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen);
        if ( pLimMgmtRegistration != NULL)
        {
            vos_mem_set((void*)pLimMgmtRegistration,
                         sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen, 0 );
            pLimMgmtRegistration->frameType = pSmeReq->frameType;
            pLimMgmtRegistration->matchLen  = pSmeReq->matchLen;
            pLimMgmtRegistration->sessionId = pSmeReq->sessionId;
            if(pSmeReq->matchLen)
            {
                vos_mem_copy(pLimMgmtRegistration->matchData,
                             pSmeReq->matchData, pSmeReq->matchLen);
            }
            vos_list_insert_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
                              &pLimMgmtRegistration->node);
        }
    }

    return;
} /*** end __limProcessSmeRegisterMgmtFrameReq() ***/

static tANI_BOOLEAN
__limInsertSingleShotNOAForScan(tpAniSirGlobal pMac, tANI_U32 noaDuration)
{
    tpP2pPsParams pMsgNoA;
    tSirMsgQ msg;

    pMsgNoA = vos_mem_malloc(sizeof( tP2pPsConfig ));
    if ( NULL == pMsgNoA )
    {
        limLog( pMac, LOGP,
                     FL( "Unable to allocate memory during NoA Update" ));
        goto error;
    }

    vos_mem_set((tANI_U8 *)pMsgNoA, sizeof(tP2pPsConfig), 0);
    /* Below params used for opp PS/periodic NOA and are don't care in this case - so initialized to 0 */
    pMsgNoA->opp_ps = 0;
    pMsgNoA->ctWindow = 0;
    pMsgNoA->duration = 0;
    pMsgNoA->interval = 0;
    pMsgNoA->count = 0;

    /* Below params used for Single Shot NOA - so assign proper values */
    pMsgNoA->psSelection = P2P_SINGLE_NOA;
    pMsgNoA->single_noa_duration = noaDuration;

    /* Start Insert NOA timer
     * If insert NOA req fails or NOA rsp fails or start NOA indication doesn't come from FW due to GO session deletion
     * or any other failure or reason, we still need to process the deferred SME req. The insert NOA
     * timer of 500 ms will ensure the stored SME req always gets processed
     */
    if (tx_timer_activate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer)
                                      == TX_TIMER_ERROR)
    {
        /// Could not activate Insert NOA timer.
        // Log error
        limLog(pMac, LOGP, FL("could not activate Insert Single Shot NOA during scan timer"));

        // send the scan response back with status failure and do not even call insert NOA
        limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_SCAN_FAILED, pMac->lim.gSmeSessionId, pMac->lim.gTransactionId);
        vos_mem_free(pMsgNoA);
        goto error;
    }

    MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_INSERT_SINGLESHOT_NOA_TIMER));

    msg.type = WDA_SET_P2P_GO_NOA_REQ;
    msg.reserved = 0;
    msg.bodyptr = pMsgNoA;
    msg.bodyval = 0;

    if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
    {
        /* In this failure case, timer is already started, so its expiration will take care of sending scan response */
        limLog(pMac, LOGP, FL("wdaPost Msg failed"));
        /* Deactivate the NOA timer in failure case */
        limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER);
        goto error;
    }
    return FALSE;

error:
    /* In any of the failure cases, just go ahead with the processing of registered deferred SME request without
     * worrying about the NOA
     */
    limProcessRegdDefdSmeReqAfterNOAStart(pMac);
    // msg buffer is consumed and freed in above function so return FALSE
    return FALSE;

}

static void __limRegisterDeferredSmeReqForNOAStart(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 *pMsgBuf)
{
    limLog(pMac, LOG1, FL("Reg msgType %d"), msgType) ;
    pMac->lim.gDeferMsgTypeForNOA = msgType;
    pMac->lim.gpDefdSmeMsgForNOA = pMsgBuf;
}

static void __limDeregisterDeferredSmeReqAfterNOAStart(tpAniSirGlobal pMac)
{
    limLog(pMac, LOG1, FL("Dereg msgType %d"), pMac->lim.gDeferMsgTypeForNOA) ;
    pMac->lim.gDeferMsgTypeForNOA = 0;
    if (pMac->lim.gpDefdSmeMsgForNOA != NULL)
    {
        /* __limProcessSmeScanReq consumed the buffer. We can free it. */
        vos_mem_free(pMac->lim.gpDefdSmeMsgForNOA);
        pMac->lim.gpDefdSmeMsgForNOA = NULL;
    }
}

static
tANI_U32 limCalculateNOADuration(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 *pMsgBuf)
{
    tANI_U32 noaDuration = 0;

    switch (msgType)
    {
        case eWNI_SME_SCAN_REQ:
        {
            tANI_U32 val;
            tANI_U8 i;
            tpSirSmeScanReq pScanReq = (tpSirSmeScanReq) pMsgBuf;
            if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS)
            {
                /*
                 * Could not get max channel value
                 * from CFG. Log error.
                 */
                limLog(pMac, LOGP, FL("could not retrieve passive max channel value"));

                /* use a default value of 110ms */
                val = DEFAULT_PASSIVE_MAX_CHANNEL_TIME;
            }

            for (i = 0; i < pScanReq->channelList.numChannels; i++) {
                tANI_U8 channelNum = pScanReq->channelList.channelNumber[i];

                if (limActiveScanAllowed(pMac, channelNum)) {
                    /* Use min + max channel time to calculate the total duration of scan */
                    noaDuration += pScanReq->minChannelTime + pScanReq->maxChannelTime;
                } else {
                    /* using the value from WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME as is done in
                     * void limContinuePostChannelScan(tpAniSirGlobal pMac)
                     */
                    noaDuration += val;
                }
            }

            /* Adding an overhead of 20ms to account for the scan messaging delays */
            noaDuration += SCAN_MESSAGING_OVERHEAD;
            noaDuration *= CONV_MS_TO_US;

            break;
        }

#ifdef FEATURE_OEM_DATA_SUPPORT
        case eWNI_SME_OEM_DATA_REQ:
            noaDuration = OEM_DATA_NOA_DURATION*CONV_MS_TO_US; // use 60 msec as default
            break;
#endif

        case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
        {
            tSirRemainOnChnReq *pRemainOnChnReq = (tSirRemainOnChnReq *) pMsgBuf;
            noaDuration = (pRemainOnChnReq->duration)*CONV_MS_TO_US;
            break;
        }

        case eWNI_SME_JOIN_REQ:
            noaDuration = JOIN_NOA_DURATION*CONV_MS_TO_US;
            break;

        default:
            noaDuration = 0;
            break;

    }
    limLog(pMac, LOGW, FL("msgType %d noa %d"), msgType, noaDuration);
    return noaDuration;
}

void limProcessRegdDefdSmeReqAfterNOAStart(tpAniSirGlobal pMac)
{
    tANI_BOOLEAN bufConsumed = TRUE;

    limLog(pMac, LOG1, FL("Process defd sme req %d"), pMac->lim.gDeferMsgTypeForNOA);
    if ( (pMac->lim.gDeferMsgTypeForNOA != 0) &&
         (pMac->lim.gpDefdSmeMsgForNOA != NULL) )
    {
        switch (pMac->lim.gDeferMsgTypeForNOA)
        {
            case eWNI_SME_SCAN_REQ:
                __limProcessSmeScanReq(pMac, pMac->lim.gpDefdSmeMsgForNOA);
                break;
#ifdef FEATURE_OEM_DATA_SUPPORT
            case eWNI_SME_OEM_DATA_REQ:
                __limProcessSmeOemDataReq(pMac, pMac->lim.gpDefdSmeMsgForNOA);
                break;
#endif
            case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
                bufConsumed = limProcessRemainOnChnlReq(pMac, pMac->lim.gpDefdSmeMsgForNOA);
                /* limProcessRemainOnChnlReq doesnt want us to free the buffer since
                 * it is freed in limRemainOnChnRsp. this change is to avoid "double free"
                 */
                if (FALSE == bufConsumed)
                {
                    pMac->lim.gpDefdSmeMsgForNOA = NULL;
                }
                break;
            case eWNI_SME_JOIN_REQ:
                __limProcessSmeJoinReq(pMac, pMac->lim.gpDefdSmeMsgForNOA);
                break;
            default:
                limLog(pMac, LOGE, FL("Unknown deferred msg type %d"), pMac->lim.gDeferMsgTypeForNOA);
                break;
        }
        __limDeregisterDeferredSmeReqAfterNOAStart(pMac);
    }
    else
    {
        limLog( pMac, LOGW, FL("start received from FW when no sme deferred msg pending. Do nothing."
            "It might happen sometime when NOA start ind and timeout happen at the same time"));
    }
}


static void
__limProcessSmeResetApCapsChange(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tpSirResetAPCapsChange pResetCapsChange;
    tpPESession             psessionEntry;
    tANI_U8  sessionId = 0;
    if (pMsgBuf == NULL)
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    pResetCapsChange = (tpSirResetAPCapsChange)pMsgBuf;
    psessionEntry = peFindSessionByBssid(pMac, pResetCapsChange->bssId, &sessionId);
    if (psessionEntry == NULL)
    {
        limLog(pMac, LOGE, FL("Session does not exist for given BSSID"));
        return;
    }

    psessionEntry->limSentCapsChangeNtf = false;
    return;
}

/**
 * lim_register_p2p_ack_ind_cb() - Save the p2p ack indication callback.
 * @mac_ctx: Mac pointer
 * @msg_buf: Msg pointer containing the callback
 *
 * This function is used to save the p2p ack indication callback in PE.
 *
 * Return: None
 */
static void lim_register_p2p_ack_ind_cb(tpAniSirGlobal mac_ctx,
				uint32_t *msg_buf)
{
	struct sir_sme_p2p_ack_ind_cb_req *sme_req =
		(struct sir_sme_p2p_ack_ind_cb_req *)msg_buf;

	if (NULL == msg_buf) {
		limLog(mac_ctx, LOGE, FL("msg_buf is null"));
		return;
	}
	if (sme_req->callback)
		mac_ctx->p2p_ack_ind_cb =
				sme_req->callback;
	else
		limLog(mac_ctx, LOGE, FL("sme_req->callback is null"));
}

/**
 * lim_register_mgmt_frame_ind_cb() - Save the Management frame
 * indication callback in PE.
 * @mac_ctx: Mac pointer
 * @msg_buf: Msg pointer containing the callback
 *
 * This function is used save the Management frame
 * indication callback in PE.
 *
 * Return: None
 */
static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal mac_ctx,
							uint32_t *msg_buf)
{
	struct sir_sme_mgmt_frame_cb_req *sme_req =
		(struct sir_sme_mgmt_frame_cb_req *)msg_buf;

	if (NULL == msg_buf) {
		limLog(mac_ctx, LOGE, FL("msg_buf is null"));
		return;
	}
	if (sme_req->callback)
		mac_ctx->mgmt_frame_ind_cb =
				sme_req->callback;
	else
		limLog(mac_ctx, LOGE, FL("sme_req->callback is null"));
}

/**
 *__lim_process_send_disassoc_frame: function processes disassoc frame
 * @mac_ctx: pointer to mac context
 * @msg_buf: message buffer
 *
 * function processes disassoc request received from SME
 *
 * return: none
 */
static void __lim_process_send_disassoc_frame(tpAniSirGlobal mac_ctx,
					uint32_t *msg_buf)
{
	struct sme_send_disassoc_frm_req sme_send_disassoc_frame_req;
	tSirRetStatus status;
	tpPESession session_entry = NULL;
	uint8_t sme_session_id;
	uint16_t sme_trans_id;

	if(msg_buf == NULL) {
		limLog(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	limGetSessionInfo(mac_ctx, (uint8_t *)msg_buf, &sme_session_id,
			&sme_trans_id);

	status = lim_send_disassoc_frm_req_ser_des(mac_ctx,
				&sme_send_disassoc_frame_req,
				(uint8_t *)msg_buf);

	if((eSIR_FAILURE == status) ||
		(limIsGroupAddr(sme_send_disassoc_frame_req.peer_mac) &&
		!limIsAddrBC(sme_send_disassoc_frame_req.peer_mac))) {
		PELOGE(limLog(mac_ctx, LOGE,
			FL("received invalid SME_DISASSOC_REQ message"));)
		return;
	}

	if((session_entry = pe_find_session_by_sme_session_id(
				mac_ctx, sme_session_id)) == NULL) {
		limLog(mac_ctx, LOGE,
			FL("session does not exist for given bssId "MAC_ADDRESS_STR),
			MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac));
		return;
	}

	limLog(mac_ctx, LOG1,
		FL("msg_type->%d len->%d sess_id->%d trans_id->%d mac->"MAC_ADDRESS_STR" reason->%d wait_for_ack->%d"),
		sme_send_disassoc_frame_req.msg_type,
		sme_send_disassoc_frame_req.length,
		sme_send_disassoc_frame_req.session_id,
		sme_send_disassoc_frame_req.trans_id,
		MAC_ADDR_ARRAY(sme_send_disassoc_frame_req.peer_mac),
		sme_send_disassoc_frame_req.reason,
		sme_send_disassoc_frame_req.wait_for_ack);

	limSendDisassocMgmtFrame(mac_ctx,
		sme_send_disassoc_frame_req.reason,
		sme_send_disassoc_frame_req.peer_mac,
		session_entry, sme_send_disassoc_frame_req.wait_for_ack);
}

/**
 * lim_process_sme_update_access_policy_vendor_ie: function updates vendor IE
 * access policy
 * @mac_ctx: pointer to mac context
 * @msg: message buffer
 *
 * function processes vendor IE and access policy from SME and updates PE
 * session entry
 *
 * return: none
 */
static void lim_process_sme_update_access_policy_vendor_ie(
					tpAniSirGlobal mac_ctx,
					uint32_t *msg)
{
	struct sme_update_access_policy_vendor_ie *update_vendor_ie;
	struct sPESession *pe_session_entry;
	uint8_t num_bytes;

	if (!msg) {
		limLog(mac_ctx, LOGE,FL("Buffer is Pointing to NULL"));
		return;
	}

	update_vendor_ie = (struct sme_update_access_policy_vendor_ie*) msg;

	pe_session_entry = pe_find_session_by_sme_session_id(mac_ctx,
			update_vendor_ie->sme_session_id);
	if (!pe_session_entry) {
		limLog(mac_ctx, LOGE,
				FL("Session does not exist for given sme session id(%hu)"),
				update_vendor_ie->sme_session_id);
		return;
	}

	if (pe_session_entry->access_policy_vendor_ie)
		vos_mem_free(pe_session_entry->access_policy_vendor_ie);

	num_bytes = update_vendor_ie->ie[1] + 2;
	pe_session_entry->access_policy_vendor_ie = vos_mem_malloc(num_bytes);

	if (!pe_session_entry->access_policy_vendor_ie) {
		limLog(mac_ctx, LOGE,
				FL("Failed to allocate memory for vendor ie"));
		return;
	}

	vos_mem_copy(pe_session_entry->access_policy_vendor_ie,
			&update_vendor_ie->ie[0], num_bytes);
	pe_session_entry->access_policy = update_vendor_ie->access_policy;

	return;
}

#ifdef FEATURE_WLAN_SUB_20_MHZ
/**
 * lim_process_sme_set_sub20_channelwidth() - update sub 20MHz channel width
 * @mac_ptr: Mac pointer
 * @msgbuf_ptr: Msg pointer containing the callback
 *
 * This function is used to save sub 20MHz channel width
 *
 * Return: None
 */
static void lim_process_sme_set_sub20_channelwidth(
	tpAniSirGlobal mac_ptr, uint32_t *msgbuf_ptr)
{
	struct sme_sub20_chan_width *msg;
	tpPESession	session_entry_ptr;

	if (msgbuf_ptr == NULL) {
		limLog(mac_ptr, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	msg = (struct sme_sub20_chan_width *)msgbuf_ptr;
	session_entry_ptr =
		 pe_find_session_by_sme_session_id(mac_ptr, msg->session_id);
	if (session_entry_ptr == NULL) {
		limLog(mac_ptr, LOGE, FL("Session not exist"));
		return;
	}

	session_entry_ptr->sub20_channelwidth = msg->channelwidth;
	limLog(mac_ptr, LOGE, "Set sub20 channel width %d\n",
	       session_entry_ptr->sub20_channelwidth);
	return;
}
#else
static void lim_process_sme_set_sub20_channelwidth(
	tpAniSirGlobal mac_ptr, uint32_t *msgbuf_ptr)
{
	limLog(mac_ptr, LOGE, FL("invalid event"));
	return;
}
#endif

void lim_process_sme_aid_set(tpAniSirGlobal mac, sir_aid_set_t *aid_set)
{
	tpPESession session;
	uint8_t session_id;
	aid_t *aid;

	if (!aid_set) {
		limLog(mac, LOGE, FL("invalid aid_set"));
		return;
	}

	session = peFindSessionByBssid(mac, aid_set->bssid, &session_id);
	if (!session) {
		limLog(mac, LOGE, FL("failed to find pe session"));
		return;
	}

	aid = &session->aid;
	mutex_lock(&aid->lock);
	if (aid->valid) {
		aid->aid = aid_set->aid;
		complete(&aid->timeout);
	}
	mutex_unlock(&aid->lock);

	return;
}

/**
 * limProcessSmeReqMessages()
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue(). This
 * function processes SME request messages from HDD or upper layer
 * application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  msgType   Indicates the SME message type
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed.
 *                   FALSE - if pMsgBuf is not to be freed.
 */

tANI_BOOLEAN
limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    tANI_BOOLEAN bufConsumed = TRUE; //Set this flag to false within case block of any following message, that doesnt want pMsgBuf to be freed.
    tANI_U32 *pMsgBuf = pMsg->bodyptr;
    tpSirSmeScanReq     pScanReq;
    PELOG1(limLog(pMac, LOG1, FL("LIM Received Global LimMlmState: %s(%d)"),
         limMlmStateStr(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState );)

    pScanReq = (tpSirSmeScanReq) pMsgBuf;
    /* Special handling of some SME Req msgs where we have an existing GO session and
     * want to insert NOA before processing those msgs. These msgs will be processed later when
     * start event happens
     */
    switch (pMsg->type)
    {
        case eWNI_SME_SCAN_REQ:
        case eWNI_SME_REMAIN_ON_CHANNEL_REQ:

            /* If scan is disabled return from here
             */
            if (pMac->lim.fScanDisabled)
            {
                if (pMsg->type == eWNI_SME_SCAN_REQ)
                {
                   limSendSmeScanRsp(pMac,
                                     offsetof(tSirSmeScanRsp,bssDescription[0]),
                                     eSIR_SME_INVALID_PARAMETERS,
                                     pScanReq->sessionId,
                                     pScanReq->transactionId);

                   bufConsumed = TRUE;
                }
                else if (pMsg->type == eWNI_SME_REMAIN_ON_CHANNEL_REQ)
                {
                    pMac->lim.gpDefdSmeMsgForNOA = NULL;
                    pMac->lim.gpLimRemainOnChanReq = (tpSirRemainOnChnReq )pMsgBuf;
                    limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL);

                    /*
                     * limRemainOnChnRsp will free the buffer this change is to
                     * avoid "double free"
                     */
                    bufConsumed = FALSE;
                }

                limLog(pMac, LOGE,
                      FL("Error: Scan Disabled."
                      " Return with error status for SME Message type(%d)"),
                      pMsg->type);

                return bufConsumed;
            }
            /*
             * Do not add BREAK here
             */
#ifdef FEATURE_OEM_DATA_SUPPORT
        case eWNI_SME_OEM_DATA_REQ:
#endif
        case eWNI_SME_JOIN_REQ:
            /* If we have an existing P2P GO session we need to insert NOA before actually process this SME Req */
            if (!pMac->fScanOffload && (limIsNOAInsertReqd(pMac) == TRUE) &&
                IS_FEATURE_SUPPORTED_BY_FW(P2P_GO_NOA_DECOUPLE_INIT_SCAN))
            {
                tANI_U32 noaDuration;
                __limRegisterDeferredSmeReqForNOAStart(pMac, pMsg->type, pMsgBuf);
                noaDuration = limCalculateNOADuration(pMac, pMsg->type, pMsgBuf);
                bufConsumed = __limInsertSingleShotNOAForScan(pMac, noaDuration);
                return bufConsumed;
            }
    }
    /* If no insert NOA required then execute the code below */

    switch (pMsg->type)
    {
        case eWNI_SME_START_REQ:
            __limProcessSmeStartReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_SYS_READY_IND:
            bufConsumed = __limProcessSmeSysReadyInd(pMac, pMsgBuf);
            break;

        case eWNI_SME_START_BSS_REQ:
            bufConsumed = __limProcessSmeStartBssReq(pMac, pMsg);
            break;

        case eWNI_SME_SCAN_REQ:
            __limProcessSmeScanReq(pMac, pMsgBuf);
            break;

#ifdef FEATURE_OEM_DATA_SUPPORT
        case eWNI_SME_OEM_DATA_REQ:
            __limProcessSmeOemDataReq(pMac, pMsgBuf);
            break;
#endif
        case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
            bufConsumed = limProcessRemainOnChnlReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_UPDATE_NOA:
            __limProcessSmeNoAUpdate(pMac, pMsgBuf);
            break;
        case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
            __limProcessClearDfsChannelList(pMac, pMsg);
            break;
        case eWNI_SME_CLEAR_LIM_SCAN_CACHE:
            limReInitScanResults(pMac);
            break;
        case eWNI_SME_JOIN_REQ:
            __limProcessSmeJoinReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_REASSOC_REQ:
            __limProcessSmeReassocReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_DISASSOC_REQ:
            __limProcessSmeDisassocReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_DISASSOC_CNF:
        case eWNI_SME_DEAUTH_CNF:
            __limProcessSmeDisassocCnf(pMac, pMsgBuf);
            break;

        case eWNI_SME_DEAUTH_REQ:
            __limProcessSmeDeauthReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_SEND_DISASSOC_FRAME:
            __lim_process_send_disassoc_frame(pMac, pMsgBuf);
            break;

        case eWNI_SME_SETCONTEXT_REQ:
            __limProcessSmeSetContextReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_REMOVEKEY_REQ:
            __limProcessSmeRemoveKeyReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_STOP_BSS_REQ:
            bufConsumed = __limProcessSmeStopBssReq(pMac, pMsg);
            break;

        case eWNI_SME_ASSOC_CNF:
        case eWNI_SME_REASSOC_CNF:
            if (pMsg->type == eWNI_SME_ASSOC_CNF)
                PELOG1(limLog(pMac, LOG1, FL("Received ASSOC_CNF message"));)
            else
                PELOG1(limLog(pMac, LOG1, FL("Received REASSOC_CNF message"));)

#ifdef SAP_AUTH_OFFLOAD
            if (pMac->sap_auth_offload) {
                __lim_process_sme_assoc_offload_cnf(pMac, pMsg->type, pMsgBuf);
            } else {
                __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
            }
#else
            __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
#endif /* SAP_AUTH_OFFLOAD */
            break;

        case eWNI_SME_ADDTS_REQ:
            PELOG1(limLog(pMac, LOG1, FL("Received ADDTS_REQ message"));)
            __limProcessSmeAddtsReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_DELTS_REQ:
            PELOG1(limLog(pMac, LOG1, FL("Received DELTS_REQ message"));)
            __limProcessSmeDeltsReq(pMac, pMsgBuf);
            break;

        case SIR_LIM_ADDTS_RSP_TIMEOUT:
            PELOG1(limLog(pMac, LOG1, FL("Received SIR_LIM_ADDTS_RSP_TIMEOUT message "));)
            limProcessSmeAddtsRspTimeout(pMac, pMsg->bodyval);
            break;

        case eWNI_SME_STA_STAT_REQ:
        case eWNI_SME_AGGR_STAT_REQ:
        case eWNI_SME_GLOBAL_STAT_REQ:
        case eWNI_SME_STAT_SUMM_REQ:
            __limProcessSmeStatsRequest( pMac, pMsgBuf);
            //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false.
            bufConsumed = FALSE;
            break;
        case eWNI_SME_GET_STATISTICS_REQ:
            __limProcessSmeGetStatisticsRequest( pMac, pMsgBuf);
            //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false.
            bufConsumed = FALSE;
            break;
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
        case eWNI_SME_GET_TSM_STATS_REQ:
            __limProcessSmeGetTsmStatsRequest( pMac, pMsgBuf);
            bufConsumed = FALSE;
            break;
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
        case eWNI_SME_GET_SCANNED_CHANNEL_REQ:
            limProcessSmeGetScanChannelInfo(pMac, pMsgBuf);
            break;
        case eWNI_SME_GET_ASSOC_STAS_REQ:
            limProcessSmeGetAssocSTAsInfo(pMac, pMsgBuf);
            break;
        case eWNI_SME_TKIP_CNTR_MEAS_REQ:
            limProcessTkipCounterMeasures(pMac, pMsgBuf);
            break;
        case eWNI_SME_EXT_CHANGE_CHANNEL:
            lim_process_ext_change_channel(pMac, pMsgBuf);
            break;
       case eWNI_SME_HIDE_SSID_REQ:
            __limProcessSmeHideSSID(pMac, pMsgBuf);
            break;
       case eWNI_SME_ROAM_SCAN_OFFLOAD_REQ:
            __lim_process_roam_scan_offload_req(pMac, pMsgBuf);
            break;
       case eWNI_SME_UPDATE_APWPSIE_REQ:
            __limProcessSmeUpdateAPWPSIEs(pMac, pMsgBuf);
            break;
        case eWNI_SME_GET_WPSPBC_SESSION_REQ:
             limProcessSmeGetWPSPBCSessions(pMac, pMsgBuf);
             break;

        case eWNI_SME_SET_APWPARSNIEs_REQ:
              __limProcessSmeSetWPARSNIEs(pMac, pMsgBuf);
              break;

        case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
             //Update the beaconInterval
             __limProcessSmeChangeBI(pMac, pMsgBuf );
             break;

#ifdef QCA_HT_2040_COEX
        case eWNI_SME_SET_HT_2040_MODE:
             __limProcessSmeSetHT2040Mode(pMac, pMsgBuf);
             break;
#endif

#if defined WLAN_FEATURE_VOWIFI
        case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
        case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
            __limProcessReportMessage(pMac, pMsg);
            break;
#endif

#if defined WLAN_FEATURE_VOWIFI_11R
       case eWNI_SME_FT_PRE_AUTH_REQ:
            bufConsumed = (tANI_BOOLEAN)limProcessFTPreAuthReq(pMac, pMsg);
            break;
       case eWNI_SME_FT_UPDATE_KEY:
            limProcessFTUpdateKey(pMac, pMsgBuf);
            break;

       case eWNI_SME_FT_AGGR_QOS_REQ:
            limProcessFTAggrQosReq(pMac, pMsgBuf);
            break;
#endif

#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
       case eWNI_SME_ESE_ADJACENT_AP_REPORT:
            limProcessAdjacentAPRepMsg ( pMac, pMsgBuf );
            break;
#endif
       case eWNI_SME_ADD_STA_SELF_REQ:
            __limProcessSmeAddStaSelfReq( pMac, pMsgBuf );
            break;
        case eWNI_SME_DEL_STA_SELF_REQ:
            __limProcessSmeDelStaSelfReq( pMac, pMsgBuf );
            break;

        case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
            __limProcessSmeRegisterMgmtFrameReq( pMac, pMsgBuf );
            break;
#ifdef FEATURE_WLAN_TDLS
        case eWNI_SME_TDLS_SEND_MGMT_REQ:
            limProcessSmeTdlsMgmtSendReq(pMac, pMsgBuf);
            break;
        case eWNI_SME_TDLS_ADD_STA_REQ:
            limProcessSmeTdlsAddStaReq(pMac, pMsgBuf);
            break;
        case eWNI_SME_TDLS_DEL_STA_REQ:
            limProcessSmeTdlsDelStaReq(pMac, pMsgBuf);
            break;
        case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
            limProcesSmeTdlsLinkEstablishReq(pMac, pMsgBuf);
            break;
#endif
        case eWNI_SME_RESET_AP_CAPS_CHANGED:
            __limProcessSmeResetApCapsChange(pMac, pMsgBuf);
            break;

        case eWNI_SME_SET_TX_POWER_REQ:
            limSendSetTxPowerReq(pMac,  pMsgBuf);
            break ;

        case eWNI_SME_CHANNEL_CHANGE_REQ:
            limProcessSmeChannelChangeRequest(pMac, pMsgBuf);
            break;

        case eWNI_SME_START_BEACON_REQ:
            limProcessSmeStartBeaconReq(pMac, pMsgBuf);
            break;

        case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
            limProcessSmeDfsCsaIeRequest(pMac, pMsgBuf);
            break;

        case eWNI_SME_UPDATE_ADDITIONAL_IES:
            limProcessUpdateAddIEs(pMac, pMsgBuf);
            break;

        case eWNI_SME_MODIFY_ADDITIONAL_IES:
            limProcessModifyAddIEs(pMac, pMsgBuf);
            break;

        case eWNI_SME_PDEV_SET_HT_VHT_IE:
            lim_process_set_pdev_IEs(pMac, pMsgBuf);
            break;
        case eWNI_SME_REGISTER_MGMT_FRAME_CB:
            lim_register_mgmt_frame_ind_cb(pMac, pMsgBuf);
            break;
        case eWNI_SME_NDP_INITIATOR_REQ:
        case eWNI_SME_NDP_RESPONDER_REQ:
        case eWNI_SME_NDP_END_REQ:
            lim_handle_ndp_request_message(pMac, pMsg);
            break;
        case eWNI_SME_REGISTER_P2P_ACK_CB:
            lim_register_p2p_ack_ind_cb(pMac, pMsgBuf);
            break;
        case eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE:
            lim_process_sme_update_access_policy_vendor_ie(pMac, pMsgBuf);
            break;
        case eWNI_SME_SET_SUB20_CH_WIDTH:
            lim_process_sme_set_sub20_channelwidth(pMac, pMsgBuf);
            break;
        default:
            vos_mem_free((v_VOID_t*)pMsg->bodyptr);
            pMsg->bodyptr = NULL;
            break;
    } // switch (msgType)

    return bufConsumed;
} /*** end limProcessSmeReqMessages() ***/

/**
 * limProcessSmeStartBeaconReq()
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue(). This
 * function processes SME request messages from HDD or upper layer
 * application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  msgType   Indicates the SME message type
 * @param  *pMsgBuf  A pointer to the SME message buffer
 * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed.
 *                   FALSE - if pMsgBuf is not to be freed.
 */
static void
limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, tANI_U32 * pMsg)
{
    tpSirStartBeaconIndication pBeaconStartInd;
    tpPESession                psessionEntry;
    tANI_U8                    sessionId;  //PE sessionID

    if( pMsg == NULL )
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    pBeaconStartInd = (tpSirStartBeaconIndication)pMsg;
    if((psessionEntry =
              peFindSessionByBssid(pMac, pBeaconStartInd->bssid, &sessionId))
                  == NULL)
    {
        limPrintMacAddr(pMac,  pBeaconStartInd->bssid, LOGE);
        PELOGE(limLog(pMac, LOGE,
               "%s[%d]: Session does not exist for given bssId",
               __func__, __LINE__ );)
        return;
    }

    if (pBeaconStartInd->beaconStartStatus == VOS_TRUE)
    {
        /*
         * Currently this Indication comes from SAP
         * to start Beacon Tx on a DFS channel
         * since beaconing has to be done on DFS
         * channel only after CAC WAIT is completed.
         * On a DFS Channel LIM does not start beacon
         * Tx right after the WDA_ADD_BSS_RSP.
         */
        limApplyConfiguration(pMac,psessionEntry);
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
               FL("Start Beacon with ssid %s Ch %d"),
               psessionEntry->ssId.ssId,
               psessionEntry->currentOperChannel);
        limSendBeaconInd(pMac, psessionEntry);
    }
    else
    {
        limLog(pMac, LOGE,FL("Invalid Beacon Start Indication"));
        return;
    }
}

static void
limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg)
{
    tpSirChanChangeRequest pChannelChangeReq;
    tpPESession             psessionEntry;
    tANI_U8                 sessionId;  //PE sessionID
    tPowerdBm               maxTxPwr;
    u_int32_t val = 0;
#ifdef WLAN_FEATURE_11AC
    tANI_U32 centerChan;
    tANI_U32 chanWidth;
#endif
    if( pMsg == NULL )
    {
        limLog(pMac, LOGE,FL("pMsg is NULL"));
        return;
    }
    pChannelChangeReq = (tpSirChanChangeRequest)pMsg;

    if((psessionEntry =
              peFindSessionByBssid(pMac, pChannelChangeReq->bssid, &sessionId))
                  == NULL)
    {
        limPrintMacAddr(pMac,  pChannelChangeReq->bssid, LOGE);
        PELOGE(limLog(pMac, LOGE,
               "%s[%d]: Session does not exist for given bssId",
               __func__, __LINE__ );)
        return;
    }

    if (LIM_IS_AP_ROLE(psessionEntry))
       psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_SAP_DFS;
    else
       psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;

    maxTxPwr = cfgGetRegulatoryMaxTransmitPower( pMac,
                            pChannelChangeReq->targetChannel );

    if (pChannelChangeReq->messageType == eWNI_SME_CHANNEL_CHANGE_REQ
                                              &&
                                     maxTxPwr != WDA_MAX_TXPOWER_INVALID)
    {

        /* Store the New Channel Params in psessionEntry */
        if (psessionEntry->currentOperChannel !=
            pChannelChangeReq->targetChannel ||
            psessionEntry->sub20_channelwidth !=
            pChannelChangeReq->sub20_channelwidth ||
            ((VOS_MONITOR_MODE == vos_get_conparam()) &&
            (pChannelChangeReq->vht_channel_width !=
             psessionEntry->vht_channel_width))) {
                limLog(pMac, LOGE,
                       FL("switch old chn %d --> new chn %d CH width - %d"),
                       psessionEntry->currentOperChannel,
                       pChannelChangeReq->targetChannel,
                       pChannelChangeReq->vht_channel_width);


#ifdef WLAN_FEATURE_11AC
            if(psessionEntry->vhtCapability)
            {

                chanWidth = pChannelChangeReq->vht_channel_width;

                if(chanWidth == eHT_CHANNEL_WIDTH_20MHZ || chanWidth == eHT_CHANNEL_WIDTH_40MHZ)
                {
                    psessionEntry->vhtTxChannelWidthSet =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                    psessionEntry->apChanWidth =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                    /*
                     * In case of DFS operation, If AP falls back to lower
                     * bandwidth [< 80Mhz] then there is no need of
                     * Center freq segment. So reset it to zero.
                     */
                    if (cfgSetInt(pMac,
                                  WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1,
                                  0)
                                  != eSIR_SUCCESS)
                    {
                        limLog(pMac, LOGP,
                        FL("couldn't reset center freq seg 0 in beacon"));
                    }
                    psessionEntry->apCenterChan = 0;
                }
                if (chanWidth == eHT_CHANNEL_WIDTH_80MHZ)
                {
                    psessionEntry->vhtTxChannelWidthSet =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
                    psessionEntry->apChanWidth =
                                           WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;

                    centerChan = limGetCenterChannel(pMac, pChannelChangeReq->targetChannel,
                                    pChannelChangeReq->cbMode,WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ);
                    if(centerChan != eSIR_CFG_INVALID_ID)
                    {
                        limLog(pMac, LOGW, FL("***Center Channel for 80MHZ channel width = %d"),centerChan);
                        psessionEntry->apCenterChan = centerChan;
                        if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, centerChan)
                                                                     != eSIR_SUCCESS)
                        {
                            limLog(pMac, LOGP, FL("could not set  WNI_CFG_CHANNEL_BONDING_MODE at CFG"));
                        }
                    }
                }

            }
            psessionEntry->htSecondaryChannelOffset = limGetHTCBState(pChannelChangeReq->cbMode);
            psessionEntry->htSupportedChannelWidthSet = (pChannelChangeReq->cbMode ? 1 : 0);

            psessionEntry->htRecommendedTxWidthSet =
                                  psessionEntry->htSupportedChannelWidthSet;
            psessionEntry->currentOperChannel =
                                  pChannelChangeReq->targetChannel;
            psessionEntry->limRFBand =
                                limGetRFBand(psessionEntry->currentOperChannel);

            /* Update sub 20MHz channel width */
            psessionEntry->sub20_channelwidth =
                 pChannelChangeReq->sub20_channelwidth;
            psessionEntry->vht_channel_width =
                 pChannelChangeReq->vht_channel_width;
            // Initialize 11h Enable Flag
            if (CHAN_HOP_ALL_BANDS_ENABLE ||
                SIR_BAND_5_GHZ == psessionEntry->limRFBand) {
                    if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) !=
                        eSIR_SUCCESS)
                            limLog(pMac, LOGP,
                                   FL("Fail to get WNI_CFG_11H_ENABLED "));
            }

            psessionEntry->lim11hEnable = val;
            psessionEntry->dot11mode = pChannelChangeReq->dot11mode;

            vos_mem_copy((void*)&psessionEntry->rateSet,
                                (void*)&pChannelChangeReq->operational_rateset,
                                sizeof(tSirMacRateSet));
            vos_mem_copy((void*)&psessionEntry->extRateSet,
                                (void*)&pChannelChangeReq->extended_rateset,
                                sizeof(tSirMacRateSet));

            limSetChannel(pMac, pChannelChangeReq->targetChannel,
                          psessionEntry->htSecondaryChannelOffset,
                          maxTxPwr,
                          psessionEntry->peSessionId);
#endif
        }

    }
    else
    {
        limLog(pMac, LOGE,FL("Invalid Request/maxTxPwr"));
    }
}

/******************************************************************************
 * limStartBssUpdateAddIEBuffer()
 *
 *FUNCTION:
 * This function checks the src buffer and its length and then malloc for
 * dst buffer update the same
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  **pDstData_buff  A pointer to pointer of  tANI_U8 dst buffer
 * @param  *pDstDataLen  A pointer to pointer of  tANI_U16 dst buffer length
 * @param  *pSrcData_buff  A pointer of  tANI_U8  src buffer
 * @param  srcDataLen  src buffer length
******************************************************************************/

static void
limStartBssUpdateAddIEBuffer(tpAniSirGlobal pMac,
                             tANI_U8 **pDstData_buff,
                             tANI_U16 *pDstDataLen,
                             tANI_U8 *pSrcData_buff,
                             tANI_U16 srcDataLen)
{

    if (srcDataLen > 0 && pSrcData_buff != NULL)
    {
        *pDstDataLen = srcDataLen;

        *pDstData_buff = vos_mem_malloc(*pDstDataLen);

       if (NULL == *pDstData_buff)
       {
            PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for "
                "pDstData_buff"));)
            return;
       }
       vos_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
    }
    else
    {
         *pDstData_buff = NULL;
         *pDstDataLen = 0;
    }
}
/******************************************************************************
 * limUpdateAddIEBuffer()
 *
 *FUNCTION:
 * This function checks the src buffer and length if src buffer length more
 * than dst buffer length then free the dst buffer and malloc for the new src
 * length, and update the dst buffer and length. But if dst buffer is bigger
 * than src buffer length then it just update the dst buffer and length
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  **pDstData_buff  A pointer to pointer of  tANI_U8 dst buffer
 * @param  *pDstDataLen  A pointer to pointer of  tANI_U16 dst buffer length
 * @param  *pSrcData_buff  A pointer of  tANI_U8  src buffer
 * @param  srcDataLen  src buffer length
******************************************************************************/

static void
limUpdateAddIEBuffer(tpAniSirGlobal pMac,
                             tANI_U8 **pDstData_buff,
                             tANI_U16 *pDstDataLen,
                             tANI_U8 *pSrcData_buff,
                             tANI_U16 srcDataLen)
{

    if (NULL == pSrcData_buff)
    {
        limLog(pMac, LOGE, FL("src buffer is null."));
        return;
    }

    if (srcDataLen > *pDstDataLen)
    {
        *pDstDataLen = srcDataLen;
        /* free old buffer */
        vos_mem_free(*pDstData_buff);
        /* allocate a new */
        *pDstData_buff = vos_mem_malloc(*pDstDataLen);

        if (NULL == *pDstData_buff)
        {
            limLog(pMac, LOGE, FL("Memory allocation failed."));
            *pDstDataLen = 0;
            return;
        }
    }

    /* copy the content of buffer into dst buffer
    */
    *pDstDataLen = srcDataLen;
    vos_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);

}

/**
 * limUpdateIBssPropAddIEs() - update IBSS prop IE
 * @pMac          : Pointer to Global MAC structure
 * @pDstData_buff : A pointer to pointer of  tANI_U8 dst buffer
 * @pDstDataLen  :  A pointer to pointer of  tANI_U16 dst buffer length
 * @pModifyIE    :  A pointer to tSirModifyIE
 *
 * This function replaces previous ibss prop_ie with new ibss prop_ie.
 *
 * Return:
 *  True or false depending upon whether IE is updated or not
 */
static tANI_BOOLEAN
limUpdateIBssPropAddIEs(tpAniSirGlobal pMac, tANI_U8 **pDstData_buff,
                        tANI_U16 *pDstDataLen, tSirModifyIE *pModifyIE)
{
    int32_t oui_length;
    uint8_t *ibss_ie = NULL;
    uint8_t *vendor_ie;
    #define MAC_VENDOR_OUI  "\x00\x16\x32"
    #define MAC_VENDOR_SIZE 3

    ibss_ie = pModifyIE->pIEBuffer;
    oui_length = pModifyIE->oui_length;

    if ((0 == oui_length) || (NULL == ibss_ie)) {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  FL("Invalid set IBSS vendor IE comamnd length %d ibss_ie %pK"),
                  oui_length, ibss_ie);
        return FALSE;
    }
    /*
     * Why replace only beacon OUI data here:
     * 1. other ie (such as wpa) shall not be overwritten here.
     * 2. per spec, beacon oui ie might be set twice and original one
     * shall be updated.
     */
    vendor_ie = cfg_get_vendor_ie_ptr_from_oui(pMac, MAC_VENDOR_OUI,
                 MAC_VENDOR_SIZE, *pDstData_buff, *pDstDataLen);

    if (vendor_ie) {
        VOS_ASSERT((vendor_ie[1] + 2) == pModifyIE->ieBufferlength);
        vos_mem_copy(vendor_ie, pModifyIE->pIEBuffer,
                     pModifyIE->ieBufferlength);
    } else {
	uint8_t *new_ptr;
	uint16_t new_length;

	if (USHRT_MAX - pModifyIE->ieBufferlength < *pDstDataLen) {
			limLog(pMac,LOGE,FL("U16 overflow due to %d + %d"),
				pModifyIE->ieBufferlength, *pDstDataLen);
			return false;
		}

        new_length = pModifyIE->ieBufferlength + *pDstDataLen;
        new_ptr = vos_mem_malloc(new_length);

        if (NULL == new_ptr) {
            limLog(pMac, LOGE, FL("Memory allocation failed."));
            return FALSE;
        }
        vos_mem_copy(new_ptr, *pDstData_buff, *pDstDataLen);
        vos_mem_copy(&new_ptr[*pDstDataLen], pModifyIE->pIEBuffer,
                     pModifyIE->ieBufferlength);
        vos_mem_free(*pDstData_buff);
        *pDstDataLen = new_length;
        *pDstData_buff = new_ptr;
    }
    return TRUE;
}

/******************************************************************************
 * limProcessModifyAddIEs()
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue(). This
 * function update the PE buffers for additional IEs.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
******************************************************************************/
static void
limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg)
{
    tpSirModifyIEsInd pModifyAddIEs = (tpSirModifyIEsInd)pMsg;
    tANI_U8           sessionId;
    tANI_BOOLEAN      ret = FALSE;

    /* Incoming message has smeSession, use BSSID to find PE session*/
    tpPESession  psessionEntry = peFindSessionByBssid(pMac,
                                           pModifyAddIEs->modifyIE.bssid,
                                           &sessionId);

    if (NULL != psessionEntry)
    {
        if ((0 != pModifyAddIEs->modifyIE.ieBufferlength) &&
            (0 != pModifyAddIEs->modifyIE.ieIDLen) &&
            (NULL != pModifyAddIEs->modifyIE.pIEBuffer))
        {

            switch (pModifyAddIEs->updateType)
            {
            case eUPDATE_IE_PROBE_RESP:
            {
                /* Probe resp */
                if (LIM_IS_IBSS_ROLE(psessionEntry)) {
                    limUpdateIBssPropAddIEs(pMac,
                        &psessionEntry->addIeParams.probeRespData_buff,
                        &psessionEntry->addIeParams.probeRespDataLen,
                        &pModifyAddIEs->modifyIE);
                }
                break;
            }
            case eUPDATE_IE_ASSOC_RESP:
                /* assoc resp IE */
                if (psessionEntry->addIeParams.assocRespDataLen == 0)
                {
                    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                              FL("assoc resp add ie not present %d"),
                              psessionEntry->addIeParams.assocRespDataLen);
                }
                /* search through the buffer and modify the IE */
                break;
            case eUPDATE_IE_PROBE_BCN:
            {
                /*probe beacon IE*/
                if (LIM_IS_IBSS_ROLE(psessionEntry)) {
                    ret = limUpdateIBssPropAddIEs(pMac,
                        &psessionEntry->addIeParams.probeRespBCNData_buff,
                        &psessionEntry->addIeParams.probeRespBCNDataLen,
                        &pModifyAddIEs->modifyIE);
                }
                if (ret == TRUE && pModifyAddIEs->modifyIE.notify)
                {
                    limHandleParamUpdate(pMac, pModifyAddIEs->updateType);
                }
                break;
            }
            default:
                limLog(pMac, LOGE, FL("unhandled buffer type %d."),
                    pModifyAddIEs->updateType);
                break;
            }
        }
        else
        {
            limLog(pMac, LOGE, FL("Invalid request pIEBuffer %pK ieBufferlength"
                            " %d ieIDLen %d ieID %d. update Type %d"),
                            pModifyAddIEs->modifyIE.pIEBuffer,
                            pModifyAddIEs->modifyIE.ieBufferlength,
                            pModifyAddIEs->modifyIE.ieID,
                            pModifyAddIEs->modifyIE.ieIDLen,
                            pModifyAddIEs->updateType);
        }
    }
    else
    {
        limLog(pMac, LOGE, FL("Session not found for given bssid. "
            MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pModifyAddIEs->modifyIE.bssid));
    }
    vos_mem_free(pModifyAddIEs->modifyIE.pIEBuffer);
    pModifyAddIEs->modifyIE.pIEBuffer = NULL;

}

/**
 * lim_process_set_pdev_IEs() - process the set pdev IE req
 *
 * @mac_ctx: Pointer to Global MAC structure
 * @msg_buf: Pointer to the SME message buffer
 *
 * This function is called by limProcessMessageQueue(). This
 * function sets the PDEV IEs to the FW.
 *
 * Return: None
 */
static void lim_process_set_pdev_IEs(tpAniSirGlobal mac_ctx, tANI_U32 *msg_buf)
{
	struct sir_set_ht_vht_cfg *ht_vht_cfg;

	ht_vht_cfg = (struct sir_set_ht_vht_cfg*)msg_buf;

	if (NULL == ht_vht_cfg) {
		limLog(mac_ctx, LOGE, FL("NULL ht_vht_cfg"));
		return;
	}

	limLog(mac_ctx, LOG1, FL("rcvd set pdev ht vht ie req with nss = %d"),
				ht_vht_cfg->nss);
	lim_set_pdev_ht_ie(mac_ctx, ht_vht_cfg->pdev_id, ht_vht_cfg->nss);

	if (IS_DOT11_MODE_VHT(ht_vht_cfg->dot11mode))
		lim_set_pdev_vht_ie(mac_ctx, ht_vht_cfg->pdev_id,
				ht_vht_cfg->nss);
}

/**
 * lim_set_pdev_ht_ie() - sends the set HT IE req to FW
 *
 * @mac_ctx: Pointer to Global MAC structure
 * @pdev_id: pdev id to set the IE.
 * @nss: Nss values to prepare the HT IE.
 *
 * Prepares the HT IE with self capabilities for different
 * Nss values and sends the set HT IE req to FW.
 *
 * Return: None
 */
static void lim_set_pdev_ht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
		tANI_U8 nss)
{
	struct set_ie_param *ie_params;
	tSirMsgQ msg;
	tSirRetStatus rc = eSIR_SUCCESS;
	v_U8_t *p_ie = NULL;
	tHtCaps *p_ht_cap;
	int i;

	for (i = nss; i > 0; i--) {
		ie_params = vos_mem_malloc(sizeof(*ie_params));
		if (NULL == ie_params) {
			limLog(mac_ctx, LOGE, FL("mem alloc failed"));
			return;
		}
		ie_params->nss = i;
		ie_params->pdev_id = pdev_id;
		ie_params->ie_type = DOT11_HT_IE;
		/* 2 for IE len and EID */
		ie_params->ie_len = 2 + sizeof(tHtCaps);
		ie_params->ie_ptr = vos_mem_malloc(ie_params->ie_len);
		if (NULL == ie_params->ie_ptr) {
			vos_mem_free(ie_params);
			limLog(mac_ctx, LOGE, FL("mem alloc failed"));
			return;
		}
		*ie_params->ie_ptr = SIR_MAC_HT_CAPABILITIES_EID;
		*(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
		lim_set_ht_caps(mac_ctx, NULL, ie_params->ie_ptr,
				ie_params->ie_len);

		if (1 == i) {
			p_ie = limGetIEPtr(mac_ctx, ie_params->ie_ptr,
					ie_params->ie_len,
					DOT11F_EID_HTCAPS, ONE_BYTE);
			if (NULL == p_ie) {
				vos_mem_free(ie_params->ie_ptr);
				vos_mem_free(ie_params);
				limLog(mac_ctx, LOGE, FL(
						"failed to get IE ptr"));
				return;
			}
			p_ht_cap = (tHtCaps *)&p_ie[2];
			p_ht_cap->supportedMCSSet[1] = 0;
			p_ht_cap->txSTBC = 0;
		}

		msg.type = WDA_SET_PDEV_IE_REQ;
		msg.bodyptr = ie_params;
		msg.bodyval = 0;

		rc = wdaPostCtrlMsg(mac_ctx, &msg);
		if (rc != eSIR_SUCCESS) {
			limLog(mac_ctx, LOGE, FL(
				"wdaPostCtrlMsg() return failure"));
			vos_mem_free(ie_params->ie_ptr);
			vos_mem_free(ie_params);
			return;
		}
	}
}

/**
 * lim_set_pdev_vht_ie() - sends the set VHT IE to req FW
 *
 * @mac_ctx: Pointer to Global MAC structure
 * @pdev_id: pdev id to set the IE.
 * @nss: Nss values to prepare the VHT IE.
 *
 * Prepares the VHT IE with self capabilities for different
 * Nss values and sends the set VHT IE req to FW.
 *
 * Return: None
 */
static void lim_set_pdev_vht_ie(tpAniSirGlobal mac_ctx, tANI_U8 pdev_id,
		tANI_U8 nss)
{
	struct set_ie_param *ie_params;
	tSirMsgQ msg;
	tSirRetStatus rc = eSIR_SUCCESS;
	v_U8_t *p_ie = NULL;
	tSirMacVHTCapabilityInfo *vht_cap;
	int i;
	tSirVhtMcsInfo *vht_mcs;

	for (i = nss; i > 0; i--) {
		ie_params = vos_mem_malloc(sizeof(*ie_params));
		if (NULL == ie_params) {
			limLog(mac_ctx, LOGE, FL("mem alloc failed"));
			return;
		}
		ie_params->nss = i;
		ie_params->pdev_id = pdev_id;
		ie_params->ie_type = DOT11_VHT_IE;
		/* 2 for IE len and EID */
		ie_params->ie_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
			sizeof(tSirVhtMcsInfo);
		ie_params->ie_ptr = vos_mem_malloc(ie_params->ie_len);
		if (NULL == ie_params->ie_ptr) {
			vos_mem_free(ie_params);
			limLog(mac_ctx, LOGE, FL("mem alloc failed"));
			return;
		}
		*ie_params->ie_ptr = SIR_MAC_VHT_CAPABILITIES_EID;
		*(ie_params->ie_ptr + 1) = ie_params->ie_len - 2;
		lim_set_vht_caps(mac_ctx, NULL, ie_params->ie_ptr,
				ie_params->ie_len);

		if (1 == i) {
			p_ie = limGetIEPtr(mac_ctx, ie_params->ie_ptr,
					ie_params->ie_len,
					DOT11F_EID_VHTCAPS, ONE_BYTE);
			if (NULL == p_ie) {
				vos_mem_free(ie_params->ie_ptr);
				vos_mem_free(ie_params);
				limLog(mac_ctx, LOGE, FL(
						"failed to get IE ptr"));
				return;
			}
			vht_cap = (tSirMacVHTCapabilityInfo *)&p_ie[2];
			vht_cap->txSTBC = 0;
			vht_mcs =
				(tSirVhtMcsInfo *)&p_ie[2 +
				sizeof(tSirMacVHTCapabilityInfo)];
			vht_mcs->rxMcsMap |= DISABLE_NSS2_MCS;
			vht_mcs->rxHighest =
				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
			vht_mcs->txMcsMap |= DISABLE_NSS2_MCS;
			vht_mcs->txHighest =
				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
		}
		msg.type = WDA_SET_PDEV_IE_REQ;
		msg.bodyptr = ie_params;
		msg.bodyval = 0;

		rc = wdaPostCtrlMsg(mac_ctx, &msg);
		if (rc != eSIR_SUCCESS) {
			limLog(mac_ctx, LOGE, FL(
					"wdaPostCtrlMsg() return failure"));
			vos_mem_free(ie_params->ie_ptr);
			vos_mem_free(ie_params);
			return;
		}
	}
}
/******************************************************************************
 * limProcessUpdateAddIEs()
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue(). This
 * function update the PE buffers for additional IEs.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
******************************************************************************/
static void
limProcessUpdateAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg)
{
    tpSirUpdateIEsInd pUpdateAddIEs = (tpSirUpdateIEsInd)pMsg;
    tANI_U8      sessionId;
    /* incoming message has smeSession, use BSSID to find PE session*/
    tpPESession  psessionEntry = peFindSessionByBssid(pMac,
                                     pUpdateAddIEs->updateIE.bssid,
                                     &sessionId);

    if (NULL != psessionEntry)
    {
        /* if len is 0, upper layer requested freeing of buffer */
        if (0 == pUpdateAddIEs->updateIE.ieBufferlength)
        {
            switch (pUpdateAddIEs->updateType)
            {
            case eUPDATE_IE_PROBE_RESP:
                vos_mem_free(psessionEntry->addIeParams.probeRespData_buff);
                psessionEntry->addIeParams.probeRespData_buff = NULL;
                psessionEntry->addIeParams.probeRespDataLen = 0;
                break;
            case eUPDATE_IE_ASSOC_RESP:
                vos_mem_free(psessionEntry->addIeParams.assocRespData_buff);
                psessionEntry->addIeParams.assocRespData_buff = NULL;
                psessionEntry->addIeParams.assocRespDataLen = 0;
                break;
            case eUPDATE_IE_PROBE_BCN:
                vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
                psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
                psessionEntry->addIeParams.probeRespBCNDataLen = 0;

                if (pUpdateAddIEs->updateIE.notify)
                {
                    limHandleParamUpdate(pMac, pUpdateAddIEs->updateType);
                }
                break;
            default:
               break;
            }
            return;
        }

        switch (pUpdateAddIEs->updateType)
        {
        case eUPDATE_IE_PROBE_RESP:
        {
            if (pUpdateAddIEs->updateIE.append)
            {
                /* In case of append, allocate new memory with combined length */
                tANI_U16 new_length = pUpdateAddIEs->updateIE.ieBufferlength +
                                psessionEntry->addIeParams.probeRespDataLen;
                tANI_U8 *new_ptr;
                /* Multiple back to back append commands
                 * can lead to a huge length.So, check
                 * for the validity of the length.
                 */
                if (psessionEntry->addIeParams.probeRespDataLen >
                     (USHRT_MAX - pUpdateAddIEs->updateIE.ieBufferlength))
                {
                    limLog(pMac, LOGE,
                           FL("IE Length overflow, curr:%d, new:%d."),
                           psessionEntry->addIeParams.probeRespDataLen,
                           pUpdateAddIEs->updateIE.ieBufferlength);
                    vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer);
                    pUpdateAddIEs->updateIE.pAdditionIEBuffer = NULL;
                    return;
                }

                new_ptr = vos_mem_malloc(new_length);
                if (NULL == new_ptr)
                {
                    limLog(pMac, LOGE, FL("Memory allocation failed."));
                    /* free incoming buffer in message */
                    vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer);
                    return;
                }
                /* append buffer to end of local buffers */
                vos_mem_copy(new_ptr,
                             psessionEntry->addIeParams.probeRespData_buff,
                             psessionEntry->addIeParams.probeRespDataLen);
                vos_mem_copy(&new_ptr[psessionEntry->addIeParams.probeRespDataLen],
                             pUpdateAddIEs->updateIE.pAdditionIEBuffer,
                             pUpdateAddIEs->updateIE.ieBufferlength);
                /* free old memory*/
                vos_mem_free(psessionEntry->addIeParams.probeRespData_buff);
                /* adjust length accordingly */
                psessionEntry->addIeParams.probeRespDataLen = new_length;
                /* save refernece of local buffer in PE session */
                psessionEntry->addIeParams.probeRespData_buff = new_ptr;
                /* free incoming buffer in message */
                vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer);
                return;
            }
            limUpdateAddIEBuffer(pMac,
                &psessionEntry->addIeParams.probeRespData_buff,
                &psessionEntry->addIeParams.probeRespDataLen,
                pUpdateAddIEs->updateIE.pAdditionIEBuffer,
                pUpdateAddIEs->updateIE.ieBufferlength);
            break;
        }
        case eUPDATE_IE_ASSOC_RESP:
              /*assoc resp IE*/
            limUpdateAddIEBuffer(pMac,
                &psessionEntry->addIeParams.assocRespData_buff,
                &psessionEntry->addIeParams.assocRespDataLen,
                pUpdateAddIEs->updateIE.pAdditionIEBuffer,
                pUpdateAddIEs->updateIE.ieBufferlength);
            break;
        case eUPDATE_IE_PROBE_BCN:
              /*probe resp Bcn IE*/
            limUpdateAddIEBuffer(pMac,
                &psessionEntry->addIeParams.probeRespBCNData_buff,
                &psessionEntry->addIeParams.probeRespBCNDataLen,
                pUpdateAddIEs->updateIE.pAdditionIEBuffer,
                pUpdateAddIEs->updateIE.ieBufferlength);
            if (pUpdateAddIEs->updateIE.notify)
            {
                limHandleParamUpdate(pMac, pUpdateAddIEs->updateType);
            }
            break;
        default:
            limLog(pMac, LOGE, FL("unhandled buffer type %d."),
                pUpdateAddIEs->updateType);
            break;
        }
    }
    else
    {
        limLog(pMac, LOGE, FL("Session not found for given bssid. "
            MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pUpdateAddIEs->updateIE.bssid));
    }
    vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer);
    pUpdateAddIEs->updateIE.pAdditionIEBuffer = NULL;

}

/**
 * send_extended_chan_switch_action_frame()- function to send ECSA
 * action frame for each sta connected to SAP/GO and AP in case of
 * STA .
 * @mac_ctx: pointer to global mac structure
 * @new_channel: new channel to switch to.
 * @ch_bandwidth: BW of channel to calculate op_class
 * @session_entry: pe session
 *
 * This function is called to send ECSA frame for STA/CLI and SAP/GO.
 *
 * Return: void
 */

static void send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
				uint16_t new_channel, uint8_t ch_bandwidth,
						tpPESession session_entry)
{
	uint16_t op_class;
	uint8_t switch_mode = 0, i;
	tpDphHashNode psta;
	uint8_t switch_count;


	op_class = regdm_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				new_channel,
				ch_bandwidth);

	if (LIM_IS_AP_ROLE(session_entry) &&
		(mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == VOS_FALSE))
	        switch_mode = session_entry->gLimChannelSwitch.switchMode;

	switch_count = session_entry->gLimChannelSwitch.switchCount;

	if (LIM_IS_AP_ROLE(session_entry)) {
		/* first node in hash table not used */
		for (i = 0; i < (mac_ctx->lim.maxStation + 1); i++) {
			psta =
			  session_entry->dph.dphHashTable.pDphNodeArray + i;
			if (psta && psta->added) {
				lim_send_extended_chan_switch_action_frame(
					mac_ctx,
					psta->staAddr,
					switch_mode, op_class, new_channel,
					switch_count, session_entry);
			}
		}
	} else if (LIM_IS_STA_ROLE(session_entry)) {
		lim_send_extended_chan_switch_action_frame(mac_ctx,
					session_entry->bssId,
					switch_mode, op_class, new_channel,
					switch_count, session_entry);
	}

}

/**
 * lim_send_chan_switch_action_frame()- Send an action frame
 * containing CSA IE or ECSA IE depending on the connected
 * sta capability.
 *
 * @mac_ctx: pointer to global mac structure
 * @new_channel: new channel to switch to.
 * @ch_bandwidth: BW of channel to calculate op_class
 * @session_entry: pe session
 *
 * Return: void
 */
void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
				       uint16_t new_channel,
				       uint8_t ch_bandwidth,
				       tpPESession session_entry)
{
	uint16_t op_class;
	uint8_t switch_mode = 0, i;
	uint8_t switch_count;
	tpDphHashNode psta;
	tpDphHashNode dph_node_array_ptr;

	dph_node_array_ptr = session_entry->dph.dphHashTable.pDphNodeArray;

	op_class = regdm_get_opclass_from_channel(
			mac_ctx->scan.countryCodeCurrent,
			new_channel, ch_bandwidth);

	if (LIM_IS_AP_ROLE(session_entry) &&
	    mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == VOS_FALSE)
		switch_mode = session_entry->gLimChannelSwitch.switchMode;

	switch_count = session_entry->gLimChannelSwitch.switchCount;

	if (LIM_IS_AP_ROLE(session_entry)) {
		for (i = 0; i < mac_ctx->lim.maxStation; i++) {
			psta = dph_node_array_ptr + i;
			if (!(psta && psta->added))
				continue;
			if (session_entry->lim_non_ecsa_cap_num == 0)
			    lim_send_extended_chan_switch_action_frame
				(mac_ctx, psta->staAddr, switch_mode,
				 op_class, new_channel, switch_count,
				 session_entry);
			else
			    limSendChannelSwitchMgmtFrame
				(mac_ctx, psta->staAddr, switch_mode,
				 new_channel, switch_count,
				 session_entry);
		}
	} else if (LIM_IS_STA_ROLE(session_entry)) {
		lim_send_extended_chan_switch_action_frame
			(mac_ctx, session_entry->bssId, switch_mode, op_class,
			 new_channel, switch_count, session_entry);
	}
}

/**
 * limProcessSmeDfsCsaIeRequest()
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue(). This
 * function processes SME request messages from HDD or upper layer
 * application.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the SME message buffer
 */
static void
limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg)
{

    tpSirDfsCsaIeRequest  pDfsCsaIeRequest = (tSirDfsCsaIeRequest *)pMsg;
    tpPESession           psessionEntry = NULL;
    tANI_U32 chanWidth = 0;
    tANI_U8               sessionId;
    uint8_t target_channel;

    if ( pMsg == NULL )
    {
        limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
        return;
    }

    if ((psessionEntry =
         peFindSessionByBssid(pMac,
                              pDfsCsaIeRequest->bssid,
                              &sessionId)) == NULL)
    {
        limLog(pMac, LOGE,
               FL("Session not found for given BSSID" MAC_ADDRESS_STR),
               MAC_ADDR_ARRAY(pDfsCsaIeRequest->bssid));
        return;
    }

    if (psessionEntry->valid && !LIM_IS_AP_ROLE(psessionEntry)) {
        limLog(pMac, LOGE, FL("Invalid SystemRole %d"),
               GET_LIM_SYSTEM_ROLE(psessionEntry));
        return;
    }

    target_channel = pDfsCsaIeRequest->targetChannel;

    if ( psessionEntry )
    {
        /* target channel */
        psessionEntry->gLimChannelSwitch.primaryChannel = target_channel;

        /* Channel switch announcement needs to be included in beacon */
        psessionEntry->dfsIncludeChanSwIe = VOS_TRUE;

        psessionEntry->gLimChannelSwitch.switchCount =
            pDfsCsaIeRequest->ch_switch_beacon_cnt;


        if (pDfsCsaIeRequest->dfs_ch_switch_disable == VOS_FALSE)
                psessionEntry->gLimChannelSwitch.switchMode =
                    pDfsCsaIeRequest->ch_switch_mode;


        psessionEntry->gLimChannelSwitch.secondarySubBand =
                                         pDfsCsaIeRequest->ch_bandwidth;

        /* Sub 20MHz channel width changing request */
        psessionEntry->lim_sub20_channel_switch_bandwidth =
                 pDfsCsaIeRequest->sub20_channelwidth;

        /* Validate if SAP is operating HT or VHT
         * mode and set the Channel Switch Wrapper
         * element with the Wide Band Switch
         * subelement..
         */
#ifdef WLAN_FEATURE_11AC
        if (VOS_TRUE == psessionEntry->vhtCapability)
        {
            if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ ==
                                        psessionEntry->vhtTxChannelWidthSet)
            {
                chanWidth = eHT_CHANNEL_WIDTH_80MHZ;
            }
            else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ ==
                                        psessionEntry->vhtTxChannelWidthSet)
            {
                chanWidth = psessionEntry->htSupportedChannelWidthSet;
            }

            /*
             * Now encode the Wider Channel BW element
             * depending on the chanWidth.
             */
            switch(chanWidth)
            {
                case eHT_CHANNEL_WIDTH_20MHZ:
                    /*
                     * Wide channel BW sublement in channel
                     * wrapper element is not required in case
                     * of 20 Mhz operation. Currently It is set
                     * only set in case of 40/80 Mhz Operation.
                     */
                    psessionEntry->dfsIncludeChanWrapperIe = VOS_FALSE;
                    psessionEntry->gLimWiderBWChannelSwitch.newChanWidth =
                                            WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                    break;
                case eHT_CHANNEL_WIDTH_40MHZ:
                    psessionEntry->dfsIncludeChanWrapperIe = VOS_TRUE;
                    psessionEntry->gLimWiderBWChannelSwitch.newChanWidth =
                                            WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                    break;
                case eHT_CHANNEL_WIDTH_80MHZ:
                    psessionEntry->dfsIncludeChanWrapperIe = VOS_TRUE;
                    psessionEntry->gLimWiderBWChannelSwitch.newChanWidth =
                                            WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
                    break;
                case eHT_CHANNEL_WIDTH_160MHZ:
                    psessionEntry->dfsIncludeChanWrapperIe = VOS_TRUE;
                    psessionEntry->gLimWiderBWChannelSwitch.newChanWidth =
                                            WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
                    break;
                default:
                    psessionEntry->dfsIncludeChanWrapperIe = VOS_FALSE;
                    /* Need to handle 80+80 Mhz Scenario
                     * When 80+80 is supported set the
                     * gLimWiderBWChannelSwitch.newChanWidth
                     * to 3
                     */
                    PELOGE(limLog(pMac, LOGE, FL("Invalid Channel Width"));)
                    break;
            }
            /*
             * Fetch the center channel based on the channel width
             */
            psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
                    limGetCenterChannel(
                        pMac, target_channel,
                        psessionEntry->htSecondaryChannelOffset,
                        psessionEntry->gLimWiderBWChannelSwitch.newChanWidth);
            /*
             * This is not applicable for 20/40/80 Mhz.
             * Only used when we support 80+80 Mhz
             * operation. In case of 80+80 Mhz, this
             * parameter indicates center channel
             * frequency index of 80 Mhz channel
             * of frequency segment 1.
             */
            psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = 0;
        }
#endif
        /* Send CSA IE request from here */
        if (schSetFixedBeaconFields(pMac, psessionEntry) != eSIR_SUCCESS)
        {
            PELOGE(limLog(pMac, LOGE, FL("Unable to set CSA IE in beacon"));)
            return;
        }

        /* First beacon update request is sent here, the remaining updates are
         * done when the FW responds back after sending the first beacon after
         * the template update
         */
        limSendBeaconInd(pMac, psessionEntry);
        limLog(pMac, LOG1,
                   FL(" Updated CSA IE, IE COUNT = %d"),
                       psessionEntry->gLimChannelSwitch.switchCount );
        /**
         * Send Action frame after updating the beacon
         * Action frame is not required if sub20 enabled
         */
        if (pDfsCsaIeRequest->sub20_switch_mode == 0) {
            if (CHAN_HOP_ALL_BANDS_ENABLE)
                lim_send_chan_switch_action_frame
                    (pMac, psessionEntry->gLimChannelSwitch.primaryChannel,
                     psessionEntry->gLimChannelSwitch.secondarySubBand,
                     psessionEntry);
            else
                send_extended_chan_switch_action_frame
                    (pMac, psessionEntry->gLimChannelSwitch.primaryChannel,
                     psessionEntry->gLimChannelSwitch.secondarySubBand,
                     psessionEntry);
        }
    }
    return;
}

/**
 * lim_process_ext_change_channel()- function to send ECSA
 * action frame for STA/CLI .
 * @mac_ctx: pointer to global mac structure
 * @msg: params from sme for new channel.
 *
 * This function is called to send ECSA frame for STA/CLI.
 *
 * Return: void
 */

static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
							uint32_t *msg)
{
	struct sir_sme_ext_cng_chan_req *ext_chng_channel =
				(struct sir_sme_ext_cng_chan_req *) msg;
	tpPESession session_entry = NULL;

	if (NULL == msg) {
		limLog(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}
	session_entry =
		pe_find_session_by_sme_session_id(mac_ctx,
						ext_chng_channel->session_id);
	if (NULL == session_entry) {
		limLog(mac_ctx, LOGE,
			FL("Session not found for given session %d"),
			ext_chng_channel->session_id);
		return;
	}
	if (LIM_IS_AP_ROLE(session_entry)) {
		limLog(mac_ctx, LOGE,
			FL("not an STA/CLI session"));
		return;
	}
	send_extended_chan_switch_action_frame(mac_ctx,
			ext_chng_channel->new_channel,
				0, session_entry);
}
