/*
 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 limAssocUtils.cc contains the utility functions
 * LIM uses while processing (Re) Association messages.
 * Author:        Chandra Modumudi
 * Date:          02/13/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 * 05/26/10       js             WPA handling in (Re)Assoc frames
 *
 */

#include "palTypes.h"
#include "aniGlobal.h"
#include "wniApi.h"
#include "sirCommon.h"

#include "wni_cfg.h"
#include "pmmApi.h"
#include "cfgApi.h"

#include "schApi.h"
#include "utilsApi.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limSecurityUtils.h"
#include "limSerDesUtils.h"
#include "limStaHashApi.h"
#include "limAdmitControl.h"
#include "limSendMessages.h"
#include "limIbssPeerMgmt.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include "limFTDefs.h"
#endif
#include "limSession.h"

#include "vos_types.h"
#include "wlan_qct_wda.h"
#include "ieee80211_common.h"

/*
 * fill up the rate info properly based on what is actually supported by the peer
 * TBD TBD TBD
 */
void
limFillSupportedRatesInfo(
    tpAniSirGlobal          pMac,
    tpDphHashNode           pSta,
    tpSirSupportedRates   pRates,
    tpPESession           psessionEntry)
{
    //pSta will be NULL for self entry, so get the opRateMode based on the self mode.
    //For the peer entry get it from the peer Capabilities present in hash table
    if(pSta == NULL)
        pRates->opRateMode = limGetStaRateMode((tANI_U8)psessionEntry->dot11mode);
    else
        pRates->opRateMode = limGetStaPeerType(pMac, pSta, psessionEntry);

}


/**
 * limCmpSSid()
 *
 *FUNCTION:
 * This function is called in various places within LIM code
 * to determine whether received SSid is same as SSID in use.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  *prxSSid - pointer to SSID structure
 *
 * @return status - true for SSID match else false.
 */

tANI_U8
limCmpSSid(tpAniSirGlobal pMac, tSirMacSSid *prxSSid,tpPESession psessionEntry)
{

    if (vos_mem_compare((tANI_U8* ) prxSSid, (tANI_U8 *) &psessionEntry->ssId,
                       (tANI_U8) (psessionEntry->ssId.length + 1)))
        return true;
    else
        return false;

} /****** end limCmpSSid() ******/



/**
 * limCompareCapabilities()
 *
 *FUNCTION:
 * This function is called during Association/Reassociation
 * frame handling to determine whether received capabilities
 * match with local capabilities or not.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac         - Pointer to Global MAC structure
 * @param  pAssocReq    - Pointer to received Assoc Req frame
 * @param  pLocalCapabs - Pointer to local capabilities
 *
 * @return status - true for Capabilitity match else false.
 */

tANI_U8
limCompareCapabilities(tpAniSirGlobal pMac,
                       tSirAssocReq *pAssocReq,
                       tSirMacCapabilityInfo *pLocalCapabs,tpPESession psessionEntry)
{
    tANI_U32   val;

    if ((LIM_IS_AP_ROLE(psessionEntry)||
         LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
         (pAssocReq->capabilityInfo.ibss)) {
        // Requesting STA asserting IBSS capability.
        limLog(pMac, LOG1,FL("Requesting STA asserting IBSS capability"));
        return false;
    }

    // Compare CF capabilities
    if (pAssocReq->capabilityInfo.cfPollable ||
        pAssocReq->capabilityInfo.cfPollReq)
    {
        // AP does not support PCF functionality
        limLog(pMac, LOG1,FL(" AP does not support PCF functionality"));
        return false;
    }

    // Compare short preamble capability
    if (pAssocReq->capabilityInfo.shortPreamble &&
        (pAssocReq->capabilityInfo.shortPreamble !=
         pLocalCapabs->shortPreamble))
    {
        // Allowing a STA requesting short preamble while
        // AP does not support it
    }


    limLog(pMac, LOG1, "QoS in AssocReq: %d, local capabs qos: %d",
              pAssocReq->capabilityInfo.qos,
              pLocalCapabs->qos);

    // Compare QoS capability
    if (pAssocReq->capabilityInfo.qos &&
        (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos))
    {
        /*Temporary hack for UPF to skip 11e capability check in order to interop with
          CSR - proper fix needs to be put in place*/
        if ( 0 != vos_get_skip_11e_check())
        {
            limLog(pMac, LOG1,
                   FL("Received unmatched QOS but cfg to suppress - continuing"));
        }
        else
        {
        // AP does not support QoS capability
            limLog(pMac, LOG1, FL("AP does not support QoS capability"));
            return false;
        }
    }


    /*
     * If AP supports shortSlot and if apple user has
     * enforced association only from shortSlot station,
     * then AP must reject any station that does not support
     * shortSlot
     */
    if ((LIM_IS_AP_ROLE(psessionEntry) ||
         LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
         (pLocalCapabs->shortSlotTime == 1)) {
        if (wlan_cfgGetInt(pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY, &val) != eSIR_SUCCESS)
        {
            limLog(pMac, LOGP, FL("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY "));
            return false;
        }
        if(val)
        {
            if (pAssocReq->capabilityInfo.shortSlotTime != pLocalCapabs->shortSlotTime)
            {
                limLog(pMac, LOGE,
                       FL("AP rejects association as station doesnt support shortslot time"));
                return false;
            }
            return false;
        }
    }

    return true;
} /****** end limCompareCapabilities() ******/


/**
 * limCheckRxBasicRates()
 *
 *FUNCTION:
 * This function is called during Association/Reassociation
 * frame handling to determine whether received rates in
 * Assoc/Reassoc request frames include all BSS basic rates
 * or not.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  rxRateSet - pointer to SSID structure
 *
 * @return status - true if ALL BSS basic rates are present in the
 *                  received rateset else false.
 */

tANI_U8
limCheckRxBasicRates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,tpPESession psessionEntry)
{
    tSirMacRateSet    *pRateSet, basicRate;
    tANI_U8    i, j, k, match;

    pRateSet = vos_mem_malloc(sizeof(tSirMacRateSet));
    if (NULL == pRateSet)
    {
        limLog(pMac, LOGP, FL("call to AllocateMemory failed for RATESET"));

        return false;
    }

    /* Copy operational rate set from session Entry */
    vos_mem_copy(pRateSet->rate, (psessionEntry->rateSet.rate),
                 psessionEntry->rateSet.numRates);

    pRateSet->numRates = psessionEntry->rateSet.numRates;

    // Extract BSS basic rateset from operational rateset
    for (i = 0, j = 0; ((i < pRateSet->numRates) && (i < SIR_MAC_RATESET_EID_MAX)) ; i++)
    {
        if ((pRateSet->rate[i] & 0x80) == 0x80)
        {
            // msb is set, so this is a basic rate
            basicRate.rate[j++] = pRateSet->rate[i];
        }
    }

    /*
     * For each BSS basic rate, find if it is present in the
     * received rateset.
     */
    for (k = 0; k < j; k++)
    {
        match = 0;
        for (i = 0; ((i < rxRateSet.numRates) && (i < SIR_MAC_RATESET_EID_MAX)); i++)
        {
            if ((rxRateSet.rate[i] | 0x80) ==    basicRate.rate[k])
                match = 1;
        }

        if (!match)
        {
            // Free up memory allocated for rateset
            vos_mem_free((tANI_U8 *)pRateSet);

            return false;
        }
    }

    // Free up memory allocated for rateset
    vos_mem_free((tANI_U8 *)pRateSet);

    return true;
} /****** end limCheckRxBasicRates() ******/



/**
 * limCheckMCSSet()
 *
 *FUNCTION:
 * This function is called during Association/Reassociation
 * frame handling to determine whether received MCS rates in
 * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  supportedMCSSet - pointer to Supported MCS Rate Set
 *
 * @return status - true if ALL MCS Basic Rate Set rates are present in the
 *                  received rateset else false.
 */

tANI_U8
limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet)
{
    tANI_U8 basicMCSSet[SIZE_OF_BASIC_MCS_SET] = {0};
    tANI_U32   cfgLen = 0;
    tANI_U8 i;
    tANI_U8 validBytes;
    tANI_U8 lastByteMCSMask = 0x1f;


    cfgLen = WNI_CFG_BASIC_MCS_SET_LEN;
    if (wlan_cfgGetStr(pMac, WNI_CFG_BASIC_MCS_SET,
                  (tANI_U8 *) basicMCSSet,
                  (tANI_U32 *) &cfgLen) != eSIR_SUCCESS)
    {
        /// Could not get Basic MCS rateset from CFG. Log error.
        limLog(pMac, LOGP, FL("could not retrieve Basic MCS rateset"));
        return false;
    }

    validBytes = VALID_MCS_SIZE/8;

    //check if all the Basic MCS Bits are set in supported MCS bitmap
    for (i=0; i<validBytes; i++)
    {
        if ((basicMCSSet[i] & supportedMCSSet[i]) != basicMCSSet[i])
        {
            //Log is avaiable in calling function in file limProcessAssocReqFrame.c
            limLog(pMac, LOGW,
                   FL("One of Basic MCS Set Rates is not supported by the Station."));
            return false;
        }
    }

    //check the last 5 bits of the valid MCS bitmap
    if (((basicMCSSet[i] & lastByteMCSMask) &
         (supportedMCSSet[i] & lastByteMCSMask)) !=
         (basicMCSSet[i] & lastByteMCSMask))
    {
        limLog(pMac, LOGW,
               FL("One of Basic MCS Set Rates is not supported by the Station."));
        return false;
    }

    return true;
}


#define SECURITY_SUITE_TYPE_MASK 0xFF
#define SECURITY_SUITE_TYPE_WEP40 0x1
#define SECURITY_SUITE_TYPE_TKIP 0x2
#define SECURITY_SUITE_TYPE_CCMP 0x4
#define SECURITY_SUITE_TYPE_WEP104 0x4

/**
 * limCheckRxRSNIeMatch()
 *
 *FUNCTION:
 * This function is called during Association/Reassociation
 * frame handling to determine whether received RSN in
 * Assoc/Reassoc request frames include supported cipher suites or not.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  rxRSNIe - received RSN IE in (Re)Assco req
 *
 * @return status - true if ALL BSS basic rates are present in the
 *                  received rateset else false.
 */

tANI_U8
limCheckRxRSNIeMatch(tpAniSirGlobal pMac, tDot11fIERSN rxRSNIe,tpPESession pSessionEntry,
                     tANI_U8 staIsHT, tANI_BOOLEAN *pmfConnection)
{
    tDot11fIERSN    *pRSNIe;
    tANI_U8         i, j, match = 0, onlyNonHtCipher = 1;
#ifdef WLAN_FEATURE_11W
    tANI_BOOLEAN weArePMFCapable;
    tANI_BOOLEAN weRequirePMF;
    tANI_BOOLEAN theyArePMFCapable;
    tANI_BOOLEAN theyRequirePMF;
#endif


    //RSN IE should be received from PE
    pRSNIe = &pSessionEntry->gStartBssRSNIe;

    /* We should have only one AKM in assoc/reassoc request */
    if (rxRSNIe.akm_suite_cnt != 1) {
        limLog(pMac, LOG3, FL("Invalid RX akm_suite_cnt %d"),
               rxRSNIe.akm_suite_cnt);
        return eSIR_MAC_INVALID_AKMP_STATUS;
    }
    /* Check if we support the received AKM */
    for (i = 0; i < pRSNIe->akm_suite_cnt; i++) {
        if (vos_mem_compare(&rxRSNIe.akm_suite[0],
                            &pRSNIe->akm_suite[i],
                            sizeof(pRSNIe->akm_suite[i]))) {
            match = 1;
            break;
        }
    }
    if (!match) {
        limLog(pMac, LOG3, FL("Invalid RX akm_suite"));
        return eSIR_MAC_INVALID_AKMP_STATUS;
    }
    // Check groupwise cipher suite
    for (i = 0; i < sizeof(rxRSNIe.gp_cipher_suite); i++)
    {
        if (pRSNIe->gp_cipher_suite[i] != rxRSNIe.gp_cipher_suite[i])
        {
            limLog(pMac, LOG3, FL("Invalid groupwise cipher suite"));
            return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
        }
    }

    /*
     * For each Pairwise cipher suite check whether we support
     * received pairwise
     */
    match = 0;
    for (i = 0; i < rxRSNIe.pwise_cipher_suite_count; i++)
    {
        for(j = 0; j < pRSNIe->pwise_cipher_suite_count; j++)
        {
            if (vos_mem_compare(&rxRSNIe.pwise_cipher_suites[i],
                                &pRSNIe->pwise_cipher_suites[j],
                                sizeof(pRSNIe->pwise_cipher_suites[j])))
            {
                match = 1;
                break;
            }
        }

        if ((staIsHT)
#ifdef ANI_LITTLE_BYTE_ENDIAN
            &&( (rxRSNIe.pwise_cipher_suites[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
#else
            &&( (rxRSNIe.pwise_cipher_suites[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
#endif
        {
             onlyNonHtCipher=0;
        }

    }

    if ((!match) || ((staIsHT) && onlyNonHtCipher))
    {
        limLog(pMac, LOG1, FL("Invalid pairwise cipher suite"));
        return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS;
    }
    /* Check RSN capabilities
     * Bit 0 of First Byte - PreAuthentication Capability
     */
    if(((rxRSNIe.RSN_Cap[0] >> 0) & 0x1) == true) //this is supported by AP only
    {
        limLog(pMac, LOG1, FL("Invalid RSN information element capabilities"));
        return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS;
    }

    *pmfConnection = eANI_BOOLEAN_FALSE;

#ifdef WLAN_FEATURE_11W
    weArePMFCapable = pSessionEntry->pLimStartBssReq->pmfCapable;
    weRequirePMF = pSessionEntry->pLimStartBssReq->pmfRequired;
    theyArePMFCapable = (rxRSNIe.RSN_Cap[0] >> 7) & 0x1;
    theyRequirePMF = (rxRSNIe.RSN_Cap[0] >> 6) & 0x1;

    if ((theyRequirePMF && theyArePMFCapable && !weArePMFCapable) ||
        (weRequirePMF && !theyArePMFCapable))
    {
        limLog(pMac, LOG1, FL("Association fail, robust management frames "
        "policy violation theyRequirePMF =%d theyArePMFCapable %d "
        "weArePMFCapable %d weRequirePMF %d theyArePMFCapable %d"),
        theyRequirePMF,theyArePMFCapable,weArePMFCapable,weRequirePMF,
        theyArePMFCapable);
        return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION;
    }

    if(theyArePMFCapable && weArePMFCapable)
        *pmfConnection = eANI_BOOLEAN_TRUE;

    limLog(pMac, LOG1, FL("weAreCapable %d, weRequire %d, theyAreCapable %d, "
                          "theyRequire %d, PMFconnection %d"),
           weArePMFCapable, weRequirePMF, theyArePMFCapable, theyRequirePMF, *pmfConnection);
#endif

    return eSIR_SUCCESS;
} /****** end limCheckRxRSNIeMatch() ******/

/**
 * limCheckRxWPAIeMatch()
 *
 *FUNCTION:
 * This function is called during Association/Reassociation
 * frame handling to determine whether received RSN in
 * Assoc/Reassoc request frames include supported cipher suites or not.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  rxWPAIe - Received WPA IE in (Re)Assco req
 *
 * @return status - true if ALL BSS basic rates are present in the
 *                  received rateset else false.
 */

tANI_U8
limCheckRxWPAIeMatch(tpAniSirGlobal pMac, tDot11fIEWPA rxWPAIe,tpPESession pSessionEntry, tANI_U8 staIsHT)
{
    tDot11fIEWPA    *pWPAIe;
    tANI_U8         i, j, match = 0, onlyNonHtCipher = 1;

    // WPA IE should be received from PE
    pWPAIe = &pSessionEntry->gStartBssWPAIe;

    /* We should have only one AKM in assoc/reassoc request */
    if (rxWPAIe.auth_suite_count != 1) {
        limLog(pMac, LOG1, FL("Invalid RX auth_suite_count %d"),
               rxWPAIe.auth_suite_count);
        return eSIR_MAC_INVALID_AKMP_STATUS;
    }
    /* Check if we support the received AKM */
    for (i = 0; i < pWPAIe->auth_suite_count; i++) {
        if (vos_mem_compare(&rxWPAIe.auth_suites[0],
                            &pWPAIe->auth_suites[i],
                            sizeof(pWPAIe->auth_suites[i]))) {
            match = 1;
            break;
        }
    }
    if (!match) {
        limLog(pMac, LOG1, FL("Invalid RX auth_suites"));
        return eSIR_MAC_INVALID_AKMP_STATUS;
    }

    // Check groupwise cipher suite
    for (i = 0; i < 4; i++)
    {
        if (pWPAIe->multicast_cipher[i] != rxWPAIe.multicast_cipher[i])
        {
            limLog(pMac, LOG1, FL("Invalid groupwise cipher suite"));
            return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
        }
    }

    /*
     * For each Pairwise cipher suite check whether we support
     * received pairwise
     */
    match = 0;
    for (i = 0; i < rxWPAIe.unicast_cipher_count; i++)
    {
        for(j = 0; j < pWPAIe->unicast_cipher_count; j++)
        {
            if (vos_mem_compare(rxWPAIe.unicast_ciphers[i],
                               pWPAIe->unicast_ciphers[j],
                               4))
            {
                match = 1;
                break;
            }
        }

        if ((staIsHT)
#ifdef ANI_LITTLE_BYTE_ENDIAN
            &&( (rxWPAIe.unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
#else
            &&( (rxWPAIe.unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
#endif
        {
             onlyNonHtCipher=0;
        }

    }

    if ((!match) || ((staIsHT) && onlyNonHtCipher))
    {
        limLog(pMac, LOG1, FL("Invalid pairwise cipher suite"));
        return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS;
    }

    return eSIR_SUCCESS;
} /****** end limCheckRxWPAIeMatch() ******/


/**
 * limCleanupRxPath()
 *
 *FUNCTION:
 * This function is called to cleanup STA state at SP & RFP.
 *
 *LOGIC:
 * To circumvent RFP's handling of dummy packet when it does not
 * have an incomplete packet for the STA to be deleted, a packet
 * with 'more framgents' bit set will be queued to RFP's WQ before
 * queuing 'dummy packet'.
 * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010
 * (Disassociation frame) and routing flags in BD set to eCPU's
 * Low Priority WQ.
 * RFP cleans up its local context for the STA id mentioned in the
 * BD and then pushes BD to eCPU's low priority WQ.
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param pMac    Pointer to Global MAC structure
 * @param pStaDs  Pointer to the per STA data structure
 *                initialized by LIM and maintained at DPH
 *
 * @return None
 */

tSirRetStatus
limCleanupRxPath(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry)
{
    tSirRetStatus       retCode = eSIR_SUCCESS;


    limLog( pMac, LOG1, FL("Cleanup Rx Path for AID : %d"
                  "psessionEntry->limSmeState : %d, mlmState : %d"),
                  pStaDs->assocId, psessionEntry->limSmeState,
                  pStaDs->mlmStaContext.mlmState);

    limAbortBackgroundScan( pMac );
    psessionEntry->isCiscoVendorAP = FALSE;

    if (pMac->lim.gLimAddtsSent)
    {
        MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER));
        tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer);
    }

    if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE)
    {
        limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER,
                                                pStaDs->assocId);

        if (!pStaDs->mlmStaContext.updateContext)
        {
            /**
             * There is no context to delete.
             * Release our assigned AID back to the free pool
             */
            if (LIM_IS_AP_ROLE(psessionEntry) ||
                LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
                limDelSta(pMac, pStaDs, false, psessionEntry);
                limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry);
            }
            limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry);
            return retCode;
        }
    }

    //delete all tspecs associated with this sta.
    limAdmitControlDeleteSta(pMac, pStaDs->assocId);


    /**
     * Make STA hash entry invalid at eCPU so that DPH
     * does not process any more data packets and
     * releases those BDs
     */
    pStaDs->valid                    = 0;
    pStaDs->mlmStaContext.mlmState   = eLIM_MLM_WT_DEL_STA_RSP_STATE;

    if (LIM_IS_STA_ROLE(psessionEntry) ||
        LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
        psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
        /* Deactivating probe after heart beat timer */
        limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
        limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);
        limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
        limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER);
        pMac->lim.gLastBeaconDtimCount = 0;
        pMac->lim.gLastBeaconDtimPeriod = 0;

#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

        /**
         * Update the status for PMM module
         */
        pmmResetPmmState(pMac);
    }
#ifdef WLAN_DEBUG
    // increment a debug count
    pMac->lim.gLimNumRxCleanup++;
#endif
    /* Do DEL BSS or DEL STA only if ADD BSS was success */
    if (!psessionEntry->add_bss_failed) {
        if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) {
            retCode = limDelBss( pMac, pStaDs,
                              psessionEntry->bssIdx, psessionEntry);
        } else
            retCode = limDelSta( pMac, pStaDs, true, psessionEntry);
    }

    return retCode;

} /*** end limCleanupRxPath() ***/


/**
 * limSendDelStaCnf()
 *
 *FUNCTION:
 * This function is called to  send appropriate CNF message to SME
 *
 *LOGIC:
 *
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param pMac    Pointer to Global MAC structure
 * @param tpAniSirGlobal pMac,
 * @param tSirMacAddr staDsAddr,
 * @param tANI_U16 staDsAssocId,
 * @param tLimMlmStaContext mlmStaContext,
 * @param tSirResultCodes statusCode
 *
 * @return None
 */

void
limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr,
       tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry)
{

    tLimMlmDisassocCnf mlmDisassocCnf;
    tLimMlmDeauthCnf   mlmDeauthCnf;
    tLimMlmPurgeStaInd mlmPurgeStaInd;

    limLog(pMac, LOG1, FL("Sessionid: %d staDsAssocId: %d Trigger: %d "
          "statusCode: %d staDsAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId,
           staDsAssocId, mlmStaContext.cleanupTrigger, statusCode,
           MAC_ADDR_ARRAY(staDsAddr));

    if (LIM_IS_STA_ROLE(psessionEntry) ||
        LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
        // Set BSSID at CFG to null
        tSirMacAddr nullAddr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

        sirCopyMacAddr(nullAddr,psessionEntry->bssId);

        // Free up buffer allocated for JoinReq held by
        // MLM state machine
        if (psessionEntry->pLimMlmJoinReq)
        {
            vos_mem_free(psessionEntry->pLimMlmJoinReq);
            psessionEntry->pLimMlmJoinReq = NULL;
        }

        psessionEntry->limAID = 0;
    }

    if ((mlmStaContext.cleanupTrigger ==
                                      eLIM_HOST_DISASSOC) ||
        (mlmStaContext.cleanupTrigger ==
                                      eLIM_PROMISCUOUS_MODE_DISASSOC) ||
        (mlmStaContext.cleanupTrigger ==
                                      eLIM_LINK_MONITORING_DISASSOC))
    {
        /**
         * Host or LMM driven Disassociation.
         * Issue Disassoc Confirm to SME.
         */
           limLog( pMac, LOGW, FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %d"),
                                   mlmStaContext.cleanupTrigger);


        vos_mem_copy((tANI_U8 *) &mlmDisassocCnf.peerMacAddr,
                     (tANI_U8 *) staDsAddr,
                      sizeof(tSirMacAddr));
        mlmDisassocCnf.resultCode = statusCode;
        mlmDisassocCnf.disassocTrigger =
                                   mlmStaContext.cleanupTrigger;
        /* Update PE session Id*/
        mlmDisassocCnf.sessionId = psessionEntry->peSessionId;

        limPostSmeMessage(pMac,
                          LIM_MLM_DISASSOC_CNF,
                          (tANI_U32 *) &mlmDisassocCnf);
    }
    else if ((mlmStaContext.cleanupTrigger == eLIM_HOST_DEAUTH) ||
             (mlmStaContext.cleanupTrigger == eLIM_LINK_MONITORING_DEAUTH))
    {
        /**
         * Host or LMM driven Deauthentication.
         * Issue Deauth Confirm to SME.
         */
        limLog( pMac, LOGW, FL("Lim Posting DEAUTH_CNF to Sme. Trigger: %d"),
                                mlmStaContext.cleanupTrigger);
        vos_mem_copy((tANI_U8 *) &mlmDeauthCnf.peerMacAddr,
                     (tANI_U8 *) staDsAddr,
                      sizeof(tSirMacAddr));
        mlmDeauthCnf.resultCode    = statusCode;
        mlmDeauthCnf.deauthTrigger =
                                   mlmStaContext.cleanupTrigger;
        /* PE session Id */
        mlmDeauthCnf.sessionId = psessionEntry->peSessionId;

        limPostSmeMessage(pMac,
                          LIM_MLM_DEAUTH_CNF,
                          (tANI_U32 *) &mlmDeauthCnf);
    }
    else if ((mlmStaContext.cleanupTrigger ==
                                          eLIM_PEER_ENTITY_DISASSOC) ||
             (mlmStaContext.cleanupTrigger ==
                                           eLIM_PEER_ENTITY_DEAUTH))
    {
        /**
         * Received Disassociation/Deauthentication from peer.
         * Issue Purge Ind to SME.
         */
        limLog( pMac, LOGW, FL("Lim Posting PURGE_STA_IND to Sme. Trigger: %d"),
                                mlmStaContext.cleanupTrigger) ;
        vos_mem_copy((tANI_U8 *) &mlmPurgeStaInd.peerMacAddr,
                     (tANI_U8 *) staDsAddr,
                     sizeof(tSirMacAddr));
        mlmPurgeStaInd.reasonCode   = (tANI_U8) mlmStaContext.disassocReason;
        mlmPurgeStaInd.aid          = staDsAssocId;
        mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger;
        mlmPurgeStaInd.sessionId = psessionEntry->peSessionId;

        limPostSmeMessage(pMac,
                          LIM_MLM_PURGE_STA_IND,
                          (tANI_U32 *) &mlmPurgeStaInd);
    }
    else if(mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE)
    {
        //PE setup the peer entry in HW upfront, right after join is completed.
        //If there is a failure during rest of the assoc sequence, this context needs to be cleaned up.
        tANI_U8         smesessionId;
        tANI_U16        smetransactionId;
        tLimSmeStates   tempLimSmeState = eLIM_SME_IDLE_STATE;

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

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

        //if it is a reassoc failure to join new AP
        //eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA result code is used
        //during assoc and reassoc, so sme state req to distinguish them
        if((mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE) ||
           (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE) ||
           (mlmStaContext.resultCode == eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE) ||
           (mlmStaContext.resultCode == eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA &&
            tempLimSmeState == eLIM_SME_WT_REASSOC_STATE)
          )
        {
            limLog( pMac, LOG1, FL("Lim Posting eWNI_SME_REASSOC_RSP to SME"
                                   "resultCode: %d, statusCode: %d,"
                                   "sessionId: %d"),
                                    mlmStaContext.resultCode,
                                    mlmStaContext.protStatusCode,
                                    psessionEntry->peSessionId);

            limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP,
                               mlmStaContext.resultCode, mlmStaContext.protStatusCode, psessionEntry,
                               smesessionId, smetransactionId);
            if(mlmStaContext.resultCode != eSIR_SME_SUCCESS )
            {
                peDeleteSession(pMac, psessionEntry);
                psessionEntry = NULL;
            }
        }
        else
        {
            vos_mem_free(psessionEntry->pLimJoinReq);
            psessionEntry->pLimJoinReq = NULL;

            limLog( pMac, LOG1, FL("Lim Posting eWNI_SME_JOIN_RSP to SME."
                                    "resultCode: %d,statusCode: %d,"
                                    "sessionId: %d"),
                                    mlmStaContext.resultCode,
                                    mlmStaContext.protStatusCode,
                                    psessionEntry->peSessionId);


            limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP,
                                     mlmStaContext.resultCode,
                                     mlmStaContext.protStatusCode,
                                     psessionEntry, smesessionId,
                                     smetransactionId);
            if(mlmStaContext.resultCode != eSIR_SME_SUCCESS)
            {
                peDeleteSession(pMac,psessionEntry);
                psessionEntry = NULL;
            }
        }

    }

    if ((NULL != psessionEntry) && (!LIM_IS_AP_ROLE(psessionEntry))) {
        peDeleteSession(pMac, psessionEntry);
        psessionEntry = NULL;
    }
}

/**
 * limRejectAssociation()
 *
 *FUNCTION:
 * This function is called whenever Re/Association Request need
 * to be rejected due to failure in assigning an AID or failure
 * in adding STA context reject by applications.
 *
 *LOGIC:
 * Resources allocated if any are freedup and (Re) Association
 * Response frame is sent to requesting STA. Pre-Auth context
 * will be added for this STA if it does not exist already
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  *pBd    - A pointer to Buffer descriptor + associated PDUs
 * @param  subType - Indicates whether it is Association Request (=0) or
 *                   Reassociation Request (=1) frame
 * @param  addPreAuthContext - Indicates whether pre-auth context
 *                             to be added for this STA
 * @param  authType - Indicates auth type to be added
 * @param  staId    - Indicates staId of the STA being rejected
 *                    association
 * @param  deleteSta - Indicates whether to delete STA context
 * @param  rCode    - Indicates what reasonCode to be sent in
 *                    Re/Assoc response to STA
 *
 * @return None
 */

void
limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType,
                     tANI_U8 addPreAuthContext, tAniAuthType authType,
                     tANI_U16 staId, tANI_U8 deleteSta, tSirResultCodes rCode, tpPESession psessionEntry )
{
    tpDphHashNode       pStaDs;

    limLog(pMac, LOG1, FL("Sessionid: %d authType: %d subType: %d "
           "addPreAuthContext: %d staId: %d deleteSta: %d rCode : %d "
           "peerAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId,
           authType, subType, addPreAuthContext, staId, deleteSta, rCode,
           MAC_ADDR_ARRAY(peerAddr));

    if (addPreAuthContext)
    {
        // Create entry for this STA in pre-auth list
        struct tLimPreAuthNode *pAuthNode;

        pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);

        if (pAuthNode)
        {
            vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                          peerAddr,
                          sizeof(tSirMacAddr));
            pAuthNode->fTimerStarted = 0;
            pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
            pAuthNode->authType = (tAniAuthType) authType;
            pAuthNode->timestamp = vos_timer_get_system_ticks();
            limAddPreAuthNode(pMac, pAuthNode);
        }
    }

    if (deleteSta == true)
    {
        pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable);

        if (pStaDs == NULL)
        {
            limLog(pMac, LOGW,
                   FL("No STA context, yet rejecting Association"));

            return;
        }

        /**
         * Trigger cleanup.
         */
        pStaDs->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;

        // Receive path cleanup
        limCleanupRxPath(pMac, pStaDs, psessionEntry);

        // Send Re/Association Response with
        // status code to requesting STA.
        limSendAssocRspMgmtFrame(pMac,
                                 rCode,
                                 0,
                                 peerAddr,
                                 subType, 0,psessionEntry);

        if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL)
        {
            // Assoction confirmation is complete, free the copy of association request frame
            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;
        }
    }
    else
    {
        limSendAssocRspMgmtFrame(pMac,
                                 eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
                                 1,
                                 peerAddr,
                                 subType, 0,psessionEntry);
        // Log error
        limLog(pMac, LOGW,
           FL("received Re/Assoc req when max associated STAs reached from "));
        limPrintMacAddr(pMac, peerAddr, LOGW);
        limSendSmeMaxAssocExceededNtf(pMac, peerAddr, psessionEntry->smeSessionId);
    }
} /*** end limRejectAssociation() ***/


/** -------------------------------------------------------------
\fn limDecideApProtectionOnHt20Delete
\brief protection related function while HT20 station is getting deleted.
\param      tpAniSirGlobal    pMac
\param      tpDphHashNode pStaDs
\param      tpUpdateBeaconParams pBeaconParams
\return      None
  -------------------------------------------------------------*/
static void
limDecideApProtectionOnHt20Delete(tpAniSirGlobal pMac,
      tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
{
    tANI_U32 i = 0;
   PELOG1( limLog(pMac, LOG1, FL("(%d) A HT 20 STA is disassociated. Addr is "),
           psessionEntry->gLimHt20Params.numSta);
    limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
    if (psessionEntry->gLimHt20Params.numSta > 0)
    {
        for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
        {
            if (psessionEntry->protStaCache[i].active)
            {
                if (vos_mem_compare(psessionEntry->protStaCache[i].addr,
                        pStaDs->staAddr, sizeof(tSirMacAddr)))
                {
                    psessionEntry->gLimHt20Params.numSta--;
                    psessionEntry->protStaCache[i].active = false;
                    break;
                }
            }
        }
    }

    if (psessionEntry->gLimHt20Params.numSta == 0)
    {
        // disable protection
        limLog(pMac, LOG1, FL("No 11B STA exists, PESessionID %d"),
                               psessionEntry->peSessionId);
        limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry);
    }
}
/** -------------------------------------------------------------
\fn limDecideApProtectionOnDelete
\brief Decides about protection related settings when a station is getting deleted.
\param      tpAniSirGlobal    pMac
\param      tpDphHashNode pStaDs
\param      tpUpdateBeaconParams pBeaconParams
\return      None
  -------------------------------------------------------------*/
void
limDecideApProtectionOnDelete(tpAniSirGlobal pMac,
      tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
{
    tANI_U32 phyMode;
    tHalBitVal erpEnabled = eHAL_CLEAR;
    tSirRFBand rfBand = SIR_BAND_UNKNOWN;
    tANI_U32 i;

    if(NULL == pStaDs)
      return;

    limGetRfBand(pMac, &rfBand, psessionEntry);
    if(SIR_BAND_5_GHZ == rfBand)
    {
        //we are HT. if we are 11A, then protection is not required.
        if(true == psessionEntry->htCapability)
        {
            //we are HT and 11A station is leaving.
            //protection consideration required.
            //HT station leaving ==> this case is commonly handled between both the bands below.
            if((psessionEntry->beaconParams.llaCoexist) &&
              (false == pStaDs->mlmStaContext.htCapability))
            {
                PELOG1(limLog(pMac, LOG1, FL("(%d) A 11A STA is disassociated. Addr is "),
                       psessionEntry->gLim11aParams.numSta);
                limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
                if (psessionEntry->gLim11aParams.numSta > 0)
                {
                    for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
                    {
                        if (psessionEntry->protStaCache[i].active)
                        {
                            if (vos_mem_compare( psessionEntry->protStaCache[i].addr,
                                    pStaDs->staAddr, sizeof(tSirMacAddr)))
                            {
                                psessionEntry->gLim11aParams.numSta--;
                                break;
                            }
                        }
                    }
                }

                if(psessionEntry->gLim11aParams.numSta == 0)
                {
                    // disable protection
                      limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry);
                }
            }
        }
    }
    else if(SIR_BAND_2_4_GHZ == rfBand)
    {
        limGetPhyMode(pMac, &phyMode, psessionEntry);

        erpEnabled = pStaDs->erpEnabled;
        //we are HT or 11G and 11B station is getting deleted.
        if (((phyMode == WNI_CFG_PHY_MODE_11G) ||
              psessionEntry->htCapability) &&
              (erpEnabled == eHAL_CLEAR))
        {
            PELOG1(limLog(pMac, LOG1, FL("(%d) A legacy STA is disassociated. Addr is "),
                   psessionEntry->gLim11bParams.numSta);
            limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
            if (psessionEntry->gLim11bParams.numSta > 0)
            {
                for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
                {
                    if (psessionEntry->protStaCache[i].active)
                    {
                        if (vos_mem_compare( psessionEntry->protStaCache[i].addr,
                                pStaDs->staAddr, sizeof(tSirMacAddr)))
                        {
                            psessionEntry->gLim11bParams.numSta--;
                            psessionEntry->protStaCache[i].active = false;
                            break;
                        }
                    }
                }
            }

            if (psessionEntry->gLim11bParams.numSta == 0)
            {
                // disable protection
                limEnable11gProtection(pMac, false, false, pBeaconParams,psessionEntry);
            }
        }
        //(non-11B station is leaving) or (we are not 11G or HT AP)
        else if(psessionEntry->htCapability)
        { //we are HT AP and non-11B station is leaving.

            //11g station is leaving
            if(!pStaDs->mlmStaContext.htCapability)
            {
                PELOG1(limLog(pMac, LOG1, FL("(%d) A 11g STA is disassociated. Addr is "),
                       psessionEntry->gLim11bParams.numSta);
                limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
                if (psessionEntry->gLim11gParams.numSta > 0)
                {
                    for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
                    {
                        if (psessionEntry->protStaCache[i].active)
                        {
                            if (vos_mem_compare( psessionEntry->protStaCache[i].addr,
                                    pStaDs->staAddr, sizeof(tSirMacAddr)))
                            {
                                psessionEntry->gLim11gParams.numSta--;
                                psessionEntry->protStaCache[i].active = false;
                                break;
                            }
                        }
                    }
                }

                if (psessionEntry->gLim11gParams.numSta == 0)
                {
                    // disable protection
                      limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry);
                  }
            }
        }
    }

    //LSIG TXOP not supporting staiton leaving. applies to 2.4 as well as 5 GHZ.
    if((true == psessionEntry->htCapability) &&
        (true == pStaDs->mlmStaContext.htCapability))
    {
        //HT non-GF leaving
        if(!pStaDs->htGreenfield)
        {
            PELOG1(limLog(pMac, LOG1, FL("(%d) A non-GF STA is disassociated. Addr is "),
                   psessionEntry->gLimNonGfParams.numSta);
            limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
            if (psessionEntry->gLimNonGfParams.numSta > 0)
            {
                for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
                {
                    if (psessionEntry->protStaCache[i].active)
                    {
                        if (vos_mem_compare( psessionEntry->protStaCache[i].addr,
                                pStaDs->staAddr, sizeof(tSirMacAddr)))
                        {
                            psessionEntry->gLimNonGfParams.numSta--;
                            break;
                        }
                    }
                }
            }

            if (psessionEntry->gLimNonGfParams.numSta == 0)
            {
                // disable protection
                limEnableHTNonGfProtection(pMac, false, false, pBeaconParams,psessionEntry);
            }
        }
        //HT 20Mhz station leaving.
        if(psessionEntry->beaconParams.ht20Coexist &&
                (eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet))
        {
            limDecideApProtectionOnHt20Delete(pMac, pStaDs, pBeaconParams,psessionEntry);
        }

        if(false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport &&
                (false == pStaDs->htLsigTXOPProtection))
        {
           PELOG1( limLog(pMac, LOG1, FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is "),
                   psessionEntry->gLimLsigTxopParams.numSta);
            limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
            if (psessionEntry->gLimLsigTxopParams.numSta > 0)
            {
                for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
                {
                    if (psessionEntry->protStaCache[i].active)
                    {
                        if (vos_mem_compare( psessionEntry->protStaCache[i].addr,
                                pStaDs->staAddr, sizeof(tSirMacAddr)))
                        {
                            psessionEntry->gLimLsigTxopParams.numSta--;
                            break;
                        }
                    }
                }
            }

            if (psessionEntry->gLimLsigTxopParams.numSta == 0)
            {
                // disable protection
                limEnableHTLsigTxopProtection(pMac, true, false, pBeaconParams,psessionEntry);
            }
        }
    }
}



/** -------------------------------------------------------------
\fn limDecideShortPreamble
\brief Decides about any short preamble reated change because of new station joining.
\param      tpAniSirGlobal    pMac
\param      tpDphHashNode pStaDs
\param      tpUpdateBeaconParams pBeaconParams
\return      None
  -------------------------------------------------------------*/
void limDecideShortPreamble(tpAniSirGlobal pMac,
          tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry )
{
   tANI_U32 i;

   if (pStaDs->shortPreambleEnabled == eHAL_CLEAR)
   {
      PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short preamble STA is disassociated. Addr is "),
             psessionEntry->gLimNoShortParams.numNonShortPreambleSta);
      limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
      if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta > 0)
      {
          for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
          {
             if (psessionEntry->gLimNoShortParams.staNoShortCache[i].active)
             {
                if (vos_mem_compare( psessionEntry->gLimNoShortParams.staNoShortCache[i].addr,
                                   pStaDs->staAddr, sizeof(tSirMacAddr)))
                {
                    psessionEntry->gLimNoShortParams.numNonShortPreambleSta--;
                    psessionEntry->gLimNoShortParams.staNoShortCache[i].active = false;
                    break;
                }
             }
          }
      }

      if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta == 0)
      {
         // enable short preamble
         //reset the cache
         vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortParams,
                      sizeof(tLimNoShortParams), 0);
         if (limEnableShortPreamble(pMac, true, pBeaconParams, psessionEntry) != eSIR_SUCCESS)
             PELOGE(limLog(pMac, LOGE, FL("Cannot enable short preamble"));)
      }
   }
}

/** -------------------------------------------------------------
\fn limDecideShortSlot
\brief Decides about any short slot time related change because of station leaving the BSS.
\param      tpAniSirGlobal    pMac
\param      tpDphHashNode pStaDs
\return      None
  -------------------------------------------------------------*/

void
limDecideShortSlot(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
                   tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
{
  tANI_U32 i, val;
  if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR)
  {
    PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short slottime STA is disassociated. Addr is "),
       pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta);
       limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)

    if (LIM_IS_AP_ROLE(psessionEntry) &&
        psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta > 0) {
          for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
          {
             if (psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active)
             {
                if (vos_mem_compare(psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
                    pStaDs->staAddr, sizeof(tSirMacAddr)))
                    {
                        psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta--;
                        psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = false;
                        break;
                    }
             }
          }
       } else {
           if (pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta> 0)
           {
             for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
             {
               if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active)
               {
                  if (vos_mem_compare(pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
                      pStaDs->staAddr, sizeof(tSirMacAddr)))
                  {
                      pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta--;
                      pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = false;
                      break;
                  }
               }
             }
           }
         }

      wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val);

      if (LIM_IS_AP_ROLE(psessionEntry) &&
         (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta == 0)) {
         // enable short slot time
         //reset the cache
         vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortSlotParams,
                     sizeof(tLimNoShortSlotParams), 0);
         // in case of AP set SHORT_SLOT_TIME to enable
         pBeaconParams->fShortSlotTime = true;
         pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
         psessionEntry->shortSlotTimeSupported = true;
      } else {
         if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta == 0) {
            // enable short slot time
            //reset the cache
            vos_mem_set((tANI_U8 *)&pMac->lim.gLimNoShortSlotParams,
                        sizeof(tLimNoShortSlotParams), 0);
            // in case of AP set SHORT_SLOT_TIME to enable
            if (LIM_IS_AP_ROLE(psessionEntry)) {
               pBeaconParams->fShortSlotTime = true;
               pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
               psessionEntry->shortSlotTimeSupported = true;
            }
          }
       }
   }
}

void
limPostReassocFailure(tpAniSirGlobal pMac,
                      tSirResultCodes resultCode,
                      tANI_U16 protStatusCode,tpPESession psessionEntry)
{
    tLimMlmReassocCnf   mlmReassocCnf;

    psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE));

    // 'Change' timer for future activations
    limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);

    mlmReassocCnf.resultCode = resultCode;
    mlmReassocCnf.protStatusCode = protStatusCode;
    /* Update PE session Id */
    mlmReassocCnf.sessionId = psessionEntry->peSessionId;
    limPostSmeMessage(pMac,
                      LIM_MLM_REASSOC_CNF,
                      (tANI_U32 *) &mlmReassocCnf);
} /*** end limPostReassocFailure() ***/

/**
 * limRestorePreReassocState()
 *
 *FUNCTION:
 * This function is called on STA role whenever Reasociation
 * Response with a reject code is received from AP.
 *
 *LOGIC:
 * Reassociation failure timer is stopped, Old (or current) AP's
 * context is restored at software
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac       - Pointer to Global MAC structure
 * @param  resultCode - Result code that specifies why Reassociation
 *                      attemp failed
 *
 * @return None
 */

void
limRestorePreReassocState(tpAniSirGlobal pMac,
                          tSirResultCodes resultCode,
                          tANI_U16 protStatusCode,tpPESession psessionEntry)
{
    tANI_U8             chanNum, secChanOffset;
    tLimMlmReassocCnf   mlmReassocCnf;

    limLog(pMac, LOG1, FL("sessionid: %d protStatusCode: %d resultCode: %d"),
    psessionEntry->smeSessionId, protStatusCode, resultCode);

    psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE));

    // 'Change' timer for future activations
    limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);

   /*  To support BT-AMP */
   chanNum = psessionEntry->currentOperChannel;
   secChanOffset = psessionEntry->htSecondaryChannelOffset;

    limSetChannel(pMac, chanNum, secChanOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId);

    /** @ToDo : Need to Integrate the STOP the DataTransfer to the AP from 11H code */

    mlmReassocCnf.resultCode = resultCode;
    mlmReassocCnf.protStatusCode = protStatusCode;
    /* Update PE session Id */
    mlmReassocCnf.sessionId = psessionEntry->peSessionId;
    limPostSmeMessage(pMac,
                      LIM_MLM_REASSOC_CNF,
                      (tANI_U32 *) &mlmReassocCnf);
} /*** end limRestorePreReassocState() ***/



/**
 * limIsReassocInProgress()
 *
 *FUNCTION:
 * This function is called to see if STA is in wt-reassoc-rsp state.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac    - Pointer to Global MAC structure
 *
 * @return eANI_BOOLEAN_TRUE  When STA is waiting for Reassoc response from AP \n
 *         else eANI_BOOLEAN_FALSE
 */

eAniBoolean
limIsReassocInProgress(tpAniSirGlobal pMac,tpPESession psessionEntry)
{
    if (psessionEntry == NULL)
    {
        return eANI_BOOLEAN_FALSE;
    }
    if ((LIM_IS_STA_ROLE(psessionEntry) ||
         LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
        ((psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) ||
        (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_LINK_FAIL_STATE)))
        return eANI_BOOLEAN_TRUE;

    return eANI_BOOLEAN_FALSE;
} /*** end limIsReassocInProgress() ***/

#ifdef WLAN_FEATURE_11AC
tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac,
                                  tpSirSupportedRates pRates,
                                  tDot11fIEVHTCaps *pPeerVHTCaps,
                                  tpPESession psessionEntry,
                                  uint8_t nss)
{
    tANI_U32 val;
    tANI_U32 selfStaDot11Mode=0;
    wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode);

    if (IS_DOT11_MODE_VHT(selfStaDot11Mode))
    {
        if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_MCS_MAP,&val) !=
            eSIR_SUCCESS )
        {
            PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX MCS MAP"));)
            goto error;
        }
        pRates->vhtRxMCSMap = (tANI_U16)val;

        if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_MCS_MAP,&val ) !=
            eSIR_SUCCESS )
        {
            PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT TX MCS MAP"));)
            goto error;
        }
        pRates->vhtTxMCSMap = (tANI_U16)val;

        if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,&val ) !=
            eSIR_SUCCESS )
        {
            PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));)
            goto error;
        }
        pRates->vhtRxHighestDataRate = (tANI_U16)val;

        if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,&val ) !=
            eSIR_SUCCESS )
        {
            PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));)
            goto error;
        }
        pRates->vhtTxHighestDataRate = (tANI_U16)val;

        if (NSS_1x1_MODE == nss) {
            pRates->vhtRxMCSMap |= VHT_MCS_1x1;
            pRates->vhtTxMCSMap |= VHT_MCS_1x1;
            pRates->vhtTxHighestDataRate =
                    VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
            pRates->vhtRxHighestDataRate =
                    VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
        }

        if( pPeerVHTCaps != NULL)
        {
            tANI_U16 mcsMapMask = MCSMAPMASK1x1;
            tANI_U16 mcsMapMask2x2 = 0;
            pRates->vhtTxHighestDataRate = SIR_MIN(pRates->vhtTxHighestDataRate, pPeerVHTCaps->txSupDataRate);
            pRates->vhtRxHighestDataRate = SIR_MIN(pRates->vhtRxHighestDataRate, pPeerVHTCaps->rxHighSupDataRate);

            if (!pMac->per_band_chainmask_supp) {
                if (pMac->roam.configParam.enable2x2) {
                    if (psessionEntry) {
                        if ((pMac->lteCoexAntShare) && (IS_24G_CH(
                                        psessionEntry->currentOperChannel))) {
                            if (IS_2X2_CHAIN(psessionEntry->chainMask))
                                mcsMapMask2x2 = MCSMAPMASK2x2;
                            else
                                limLog(pMac, LOGE,FL(
                                                "2x2 not enabled %d"),
                                                psessionEntry->chainMask);
                        } else {
                            mcsMapMask2x2 = MCSMAPMASK2x2;
                        }
                    } else {
                        mcsMapMask2x2 = MCSMAPMASK2x2;
                    }
                }
            } else {
                if (psessionEntry && (psessionEntry->vdev_nss == NSS_2x2_MODE))
                    mcsMapMask2x2 = MCSMAPMASK2x2;
            }

            if ((pPeerVHTCaps->txMCSMap & mcsMapMask) < (pRates->vhtRxMCSMap & mcsMapMask)) {
                pRates->vhtRxMCSMap &= ~(mcsMapMask);
                pRates->vhtRxMCSMap |= (pPeerVHTCaps->txMCSMap & mcsMapMask);
            }
            if ((pPeerVHTCaps->rxMCSMap & mcsMapMask) < (pRates->vhtTxMCSMap & mcsMapMask)) {
                pRates->vhtTxMCSMap &= ~(mcsMapMask);
                pRates->vhtTxMCSMap |= (pPeerVHTCaps->rxMCSMap & mcsMapMask);
            }

            if (mcsMapMask2x2) {

                tANI_U16 peerMcsMap, selfMcsMap;

                peerMcsMap = pPeerVHTCaps->txMCSMap & mcsMapMask2x2;
                selfMcsMap = pRates->vhtRxMCSMap & mcsMapMask2x2;

                if ((selfMcsMap != mcsMapMask2x2) &&
                        ((peerMcsMap == mcsMapMask2x2) ||
                            (peerMcsMap < selfMcsMap))) {
                    pRates->vhtRxMCSMap &= ~mcsMapMask2x2;
                    pRates->vhtRxMCSMap |= peerMcsMap;
                }

                peerMcsMap = (pPeerVHTCaps->rxMCSMap & mcsMapMask2x2);
                selfMcsMap = (pRates->vhtTxMCSMap & mcsMapMask2x2);

                if ((selfMcsMap != mcsMapMask2x2) &&
                        ((peerMcsMap == mcsMapMask2x2) ||
                            (peerMcsMap < selfMcsMap))) {
                    pRates->vhtTxMCSMap &= ~mcsMapMask2x2;
                    pRates->vhtTxMCSMap |= peerMcsMap;
                }
            }

            limLog(pMac, LOG1, FL(
                        "enable2x2 %d nss %d vhtRxMCSMap %x vhtTxMCSMap %x\n"),
                        pMac->roam.configParam.enable2x2, nss,
                        pRates->vhtRxMCSMap, pRates->vhtTxMCSMap);

            /* Check if VHT caps present to determine session NSS */
            if ((psessionEntry) && (pPeerVHTCaps->present)) {
                    psessionEntry->supported_nss_1x1 =
                        ((pRates->vhtTxMCSMap & VHT_MCS_1x1) ==
                         VHT_MCS_1x1) ? true : false;
                    limLog(pMac, LOG1, FL("VHT supported nss 1x1 : %d "),
                           psessionEntry->supported_nss_1x1);
            }
        }
    }
    return eSIR_SUCCESS;
error:

    return eSIR_FAILURE;

}
#endif

/**
 * limPopulateOwnRateSet
 *
 * FUNCTION:
 * This function is called by limProcessAssocRsp() or
 * limAddStaInIBSS()
 * - It creates a combined rate set of 12 rates max which
 *   comprises the basic and extended rates read from CFG
 * - It sorts the combined rate Set and copy it in the
 *   rate array of the pSTA descriptor
 * - It sets the erpEnabled bit of the STA descriptor
 *
 * NOTE:
 * ERP bit is set iff the dph PHY mode is 11G and there is at least
 * an A rate in the supported or extended rate sets
 *
 * @param  pMac      - Pointer to Global MAC structure
 * @param  basicOnly - When passed value is true, only basic
 *                     rates are copied to DPH node else
 *                     all supported rates are copied
 * @return eSIR_SUCCESS or eSIR_FAILURE
 *
 */
#ifdef WLAN_FEATURE_11AC
tSirRetStatus
limPopulateOwnRateSet(tpAniSirGlobal pMac,
                      tpSirSupportedRates pRates,
                      tANI_U8* pSupportedMCSSet,
                      tANI_U8 basicOnly,
                      tpPESession psessionEntry,
                      tDot11fIEVHTCaps *pVHTCaps)
#else
tSirRetStatus
limPopulateOwnRateSet(tpAniSirGlobal pMac,
                      tpSirSupportedRates pRates,
                      tANI_U8* pSupportedMCSSet,
                      tANI_U8 basicOnly,
                      tpPESession psessionEntry)
#endif

{
    tSirMacRateSet          tempRateSet;
    tSirMacRateSet          tempRateSet2;
    tANI_U32                i,j,val,min,isArate;
    tANI_U32 phyMode = 0;
    tANI_U32 selfStaDot11Mode=0;

    isArate = 0;

    wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
    limGetPhyMode(pMac, &phyMode, psessionEntry);

    /* Include 11b rates only when the device configured in
           auto, 11a/b/g or 11b_only */
    if ( (selfStaDot11Mode == WNI_CFG_DOT11_MODE_ALL) ||
         (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11A) ||
         (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11AC) ||
         (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11N) ||
         (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11G) ||
         (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11B) )
    {
        val = WNI_CFG_SUPPORTED_RATES_11B_LEN;
        wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11B,
                       (tANI_U8 *)&tempRateSet.rate, &val );
        tempRateSet.numRates = (tANI_U8) val;
    }
    else
        tempRateSet.numRates = 0;

     /* Include 11a rates when the device configured in non-11b mode */
    if (!IS_DOT11_MODE_11B(selfStaDot11Mode))
    {
        val = WNI_CFG_SUPPORTED_RATES_11A_LEN;
        wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11A,
                (tANI_U8 *)&tempRateSet2.rate, &val );
        tempRateSet2.numRates = (tANI_U8) val;
    }
    else
         tempRateSet2.numRates = 0;

    if ((tempRateSet.numRates + tempRateSet2.numRates) > 12)
    {
        //we are in big trouble
        limLog(pMac, LOGP, FL("more than 12 rates in CFG"));
        //panic
        goto error;
    }

    //copy all rates in tempRateSet, there are 12 rates max
    for (i = 0;i < tempRateSet2.numRates; i++)
      tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i];
    tempRateSet.numRates += tempRateSet2.numRates;

    /**
     * Sort rates in tempRateSet (they are likely to be already sorted)
     * put the result in pSupportedRates
     */
    {
        tANI_U8 aRateIndex = 0;
        tANI_U8 bRateIndex = 0;

        vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0);
        for(i = 0;i < tempRateSet.numRates; i++)
        {
            min = 0;
            val = 0xff;
            isArate = 0;
            for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++)
            {
                if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
                {
                     val = tempRateSet.rate[j] & 0x7f;
                     min = j;
                }
            }

            if (sirIsArate(tempRateSet.rate[min] & 0x7f))
                isArate = 1;

    /*
    * HAL needs to know whether the rate is basic rate or not, as it needs to
    * update the response rate table accordingly. e.g. if one of the 11a rates is
    * basic rate, then that rate can be used for sending control frames.
    * HAL updates the response rate table whenever basic rate set is changed.
    */
            if (basicOnly)
            {
                if (tempRateSet.rate[min] & 0x80)
                {
                    if (isArate)
                        pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
                    else
                        pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
                }
            }
            else
            {
                if (isArate)
                    pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
                else
                    pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
            }
            tempRateSet.rate[min] = 0xff;
        }

    }

    if (IS_DOT11_MODE_HT(selfStaDot11Mode))
    {
        val = SIZE_OF_SUPPORTED_MCS_SET;
        if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
                      pRates->supportedMCSSet,
                      &val) != eSIR_SUCCESS)
        {
            /// Could not get rateset from CFG. Log error.
            PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));)
            goto error;
        }

        if (psessionEntry->vdev_nss == NSS_1x1_MODE)
            pRates->supportedMCSSet[1] = 0;

        //if supported MCS Set of the peer is passed in, then do the intersection
        //else use the MCS set from local CFG.

        if(pSupportedMCSSet != NULL)
        {
            for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
                    pRates->supportedMCSSet[i] &= pSupportedMCSSet[i];

        }

        PELOG2(limLog(pMac, LOG2, FL("MCS Rate Set Bitmap: "));)
        for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
            PELOG2(limLog(pMac, LOG2,FL("%x ") , pRates->supportedMCSSet[i]);)
    }

#ifdef WLAN_FEATURE_11AC
    limPopulateVhtMcsSet(pMac, pRates , pVHTCaps, psessionEntry,
                        psessionEntry->vdev_nss);
#endif

    return eSIR_SUCCESS;

 error:

    return eSIR_FAILURE;
} /*** limPopulateOwnRateSet() ***/

/**
 * lim_remove_membership_selectors() - remove elements from rate set
 *
 * @rate_set: pointer to rate set
 *
 * Removes the BSS membership selector elements from the rate set, and keep
 * only the rates
 *
 * Return: none
 */
static void lim_remove_membership_selectors(tSirMacRateSet *rate_set)
{
	int i, selector_count = 0;

	for (i = 0; i < rate_set->numRates; i++) {
		if ((rate_set->rate[i] == (WLAN_BASIC_RATE_MASK |
				WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY)) ||
		    (rate_set->rate[i] == (WLAN_BASIC_RATE_MASK |
				WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) ||
		    (rate_set->rate[i] == (WLAN_BASIC_RATE_MASK |
				WLAN_BSS_MEMBERSHIP_SELECTOR_GLK)) ||
		    (rate_set->rate[i] == (WLAN_BASIC_RATE_MASK |
				WLAN_BSS_MEMBERSHIP_SELECTOR_EPD)) ||
		    (rate_set->rate[i] == (WLAN_BASIC_RATE_MASK |
				WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E)) ||
		    (rate_set->rate[i] == (WLAN_BASIC_RATE_MASK |
				WLAN_BSS_MEMBERSHIP_SELECTOR_HE_PHY)))
			selector_count++;

		if (i + selector_count < rate_set->numRates)
			rate_set->rate[i] = rate_set->rate[i + selector_count];
	}
	rate_set->numRates -= selector_count;
}

#ifdef WLAN_FEATURE_11AC
tSirRetStatus
limPopulatePeerRateSet(tpAniSirGlobal pMac,

                      tpSirSupportedRates pRates,
                      tANI_U8* pSupportedMCSSet,
                      tANI_U8 basicOnly,
                      tpPESession psessionEntry,
                      tDot11fIEVHTCaps *pVHTCaps)
#else
tSirRetStatus
limPopulatePeerRateSet(tpAniSirGlobal pMac,
                      tpSirSupportedRates pRates,
                      tANI_U8* pSupportedMCSSet,
                      tANI_U8 basicOnly,
                      tpPESession psessionEntry)
#endif
{
    tSirMacRateSet          tempRateSet;
    tSirMacRateSet          tempRateSet2;
    tANI_U32                     i,j,val,min,isArate;
    isArate = 0;

    /* copy operational rate set from psessionEntry */
    if ( psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX )
    {
        vos_mem_copy((tANI_U8 *)tempRateSet.rate,
                     (tANI_U8*)(psessionEntry->rateSet.rate),
                     psessionEntry->rateSet.numRates);
        tempRateSet.numRates = psessionEntry->rateSet.numRates;
    }
    else
    {
        limLog(pMac, LOGE, FL("more than SIR_MAC_RATESET_EID_MAX rates\n"));
        goto error;
    }
    if ((psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) ||
	(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11A) ||
	(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
	(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N))
    {

        if (psessionEntry->extRateSet.numRates <= SIR_MAC_RATESET_EID_MAX)
        {
            vos_mem_copy((tANI_U8 *)tempRateSet2.rate,
                         (tANI_U8*)(psessionEntry->extRateSet.rate),
                         psessionEntry->extRateSet.numRates);
            tempRateSet2.numRates = psessionEntry->extRateSet.numRates;
        }
        else {
           limLog(pMac, LOGE, FL("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates\n"));
           goto error;
        }
    }
    else
        tempRateSet2.numRates = 0;

    lim_remove_membership_selectors(&tempRateSet);
    lim_remove_membership_selectors(&tempRateSet2);

    if ((tempRateSet.numRates + tempRateSet2.numRates) > SIR_MAC_RATESET_EID_MAX)
    {
        //we are in big trouble
        limLog(pMac, LOGP, FL("more than 12 rates in CFG"));
        goto error;
    }


    //copy all rates in tempRateSet, there are 12 rates max
    for (i = 0;i < tempRateSet2.numRates; i++)
      tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i];
    tempRateSet.numRates += tempRateSet2.numRates;
    /**
     * Sort rates in tempRateSet (they are likely to be already sorted)
     * put the result in pSupportedRates
     */
    {
        tANI_U8 aRateIndex = 0;
        tANI_U8 bRateIndex = 0;
        vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0);
        for(i = 0;i < tempRateSet.numRates; i++)
        {
            min = 0;
            val = 0xff;
            isArate = 0;
            for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++)
            {
                if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
                {
                     val = tempRateSet.rate[j] & 0x7f;
                     min = j;
                }
            }
            if (sirIsArate(tempRateSet.rate[min] & 0x7f))
                isArate = 1;
    /*
    * HAL needs to know whether the rate is basic rate or not, as it needs to
    * update the response rate table accordingly. e.g. if one of the 11a rates is
    * basic rate, then that rate can be used for sending control frames.
    * HAL updates the response rate table whenever basic rate set is changed.
    */
            if (basicOnly)
            {
                if (tempRateSet.rate[min] & 0x80)
                {
                    if (isArate)
                        pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
                    else
                        pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
                }
            }
            else
            {
                if (isArate)
                    pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
                else
                    pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
            }
            tempRateSet.rate[min] = 0xff;
        }
    }


    if (IS_DOT11_MODE_HT(psessionEntry->dot11mode))
    {
        val = SIZE_OF_SUPPORTED_MCS_SET;
        if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
                      pRates->supportedMCSSet,
                      &val) != eSIR_SUCCESS)
        {
            /// Could not get rateset from CFG. Log error.
            PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));)
            goto error;
        }
        if (psessionEntry->vdev_nss == NSS_1x1_MODE)
            pRates->supportedMCSSet[1] = 0;

        //if supported MCS Set of the peer is passed in, then do the intersection
        //else use the MCS set from local CFG.
        if(pSupportedMCSSet != NULL)
        {
            for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
                    pRates->supportedMCSSet[i] &= pSupportedMCSSet[i];
        }

        PELOG2(limLog(pMac, LOG2, FL("MCS Rate Set Bitmap: "));)
        for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
            PELOG2(limLog(pMac, LOG2, FL("%x "), pRates->supportedMCSSet[i]);)

        psessionEntry->supported_nss_1x1 =
            ((pRates->supportedMCSSet[1] != 0) ? false : true);
        limLog(pMac, LOG1, FL("HT supported nss 1x1 : %d "),
                      psessionEntry->supported_nss_1x1);

    }
#ifdef WLAN_FEATURE_11AC
    limPopulateVhtMcsSet(pMac, pRates , pVHTCaps, psessionEntry,
                    psessionEntry->vdev_nss);
#endif
    return eSIR_SUCCESS;
 error:
    return eSIR_FAILURE;
} /*** limPopulatePeerRateSet() ***/

/**
 * limPopulateMatchingRateSet
 * FUNCTION:
 * This is called at the time of Association Request
 * processing on AP and while adding peer's context
 * in IBSS role to process the CFG rate sets and
 * the rate sets received in the Assoc request on AP
 * or Beacon/Probe Response from peer in IBSS.
 *
 * LOGIC:
 * 1. It makes the intersection between our own rate Sat
 *    and extemcded rate set and the ones received in the
 *    association request.
 * 2. It creates a combined rate set of 12 rates max which
 *    comprised the basic and extended rates
 * 3. It sorts the combined rate Set and copy it in the
 *    rate array of the pSTA descriptor
 *
 * ASSUMPTION:
 * The parser has already ensured unicity of the rates in the
 * association request structure
 *
 * @param: pMac         - Pointer to Global MAC structure
 *         pStaDs       - Pointer to DPH node
 *         pOperRateSet - Pointer to peer's supported rateset
 *         pExtRateSet  - Pointer to peer's extended rateset
 *
 * @return:  eSIR_SUCCESS or eSIR_FAILURE
 */
#ifdef WLAN_FEATURE_11AC
tSirRetStatus
limPopulateMatchingRateSet(tpAniSirGlobal pMac,
                           tpDphHashNode pStaDs,
                           tSirMacRateSet *pOperRateSet,
                           tSirMacRateSet *pExtRateSet,
                           tANI_U8* pSupportedMCSSet,
                           tpPESession  psessionEntry,
                           tDot11fIEVHTCaps *pVHTCaps)

#else
tSirRetStatus
limPopulateMatchingRateSet(tpAniSirGlobal pMac,
                           tpDphHashNode pStaDs,
                           tSirMacRateSet *pOperRateSet,
                           tSirMacRateSet *pExtRateSet,
                           tANI_U8* pSupportedMCSSet,
                           tpPESession  psessionEntry)
#endif
{
   tSirMacRateSet          tempRateSet;
   tSirMacRateSet          tempRateSet2;
   tANI_U32                i,j,val,min,isArate;
   tANI_U32 phyMode;
   tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET];

   isArate=0;

   limGetPhyMode(pMac, &phyMode, psessionEntry);

    /* copy operational rate set from psessionEntry */
    vos_mem_copy((tempRateSet.rate), (psessionEntry->rateSet.rate),
                 psessionEntry->rateSet.numRates);
    tempRateSet.numRates = (tANI_U8) psessionEntry->rateSet.numRates;

    if (phyMode == WNI_CFG_PHY_MODE_11G)
    {
        vos_mem_copy((tempRateSet2.rate), (psessionEntry->extRateSet.rate),
                     psessionEntry->extRateSet.numRates);
        tempRateSet2.numRates = (tANI_U8) psessionEntry->extRateSet.numRates;
    }
    else
        tempRateSet2.numRates = 0;

    lim_remove_membership_selectors(&tempRateSet);
    lim_remove_membership_selectors(&tempRateSet2);

    if ((tempRateSet.numRates + tempRateSet2.numRates) >
        SIR_MAC_MAX_NUMBER_OF_RATES)
    {
        PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG"));)
        goto error;
    }

    /**
     * Handling of the rate set IEs is the following:
     * - keep only rates that we support and that the station supports
     * - sort and the rates into the pSta->rate array
     */

    // Copy all rates in tempRateSet, there are 12 rates max
    for(i = 0; i < tempRateSet2.numRates; i++)
        tempRateSet.rate[i + tempRateSet.numRates] =
                                           tempRateSet2.rate[i];

    tempRateSet.numRates += tempRateSet2.numRates;

    /**
     * Sort rates in tempRateSet (they are likely to be already sorted)
     * put the result in tempRateSet2
     */
    tempRateSet2.numRates = 0;

    for(i = 0;i < tempRateSet.numRates; i++)
    {
        min = 0;
        val = 0xff;

        for(j = 0;j < tempRateSet.numRates; j++)
            if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
            {
                val = tempRateSet.rate[j] & 0x7f;
                min = j;
            }

        tempRateSet2.rate[tempRateSet2.numRates++] =
                                              tempRateSet.rate[min];
        tempRateSet.rate[min] = 0xff;
    }


    /**
     * Copy received rates in tempRateSet, the parser has ensured
     * unicity of the rates so there cannot be more than 12
     */
    for(i = 0; (i < pOperRateSet->numRates && i < SIR_MAC_RATESET_EID_MAX) ; i++)
    {
        tempRateSet.rate[i] = pOperRateSet->rate[i];
    }

    tempRateSet.numRates = pOperRateSet->numRates;

    if (pExtRateSet->numRates)
    {
      if((tempRateSet.numRates + pExtRateSet->numRates) > 12 )
      {
        limLog( pMac, LOG2,
            "Sum of SUPPORTED and EXTENDED Rate Set (%1d) exceeds 12!",
            tempRateSet.numRates + pExtRateSet->numRates );

        if( tempRateSet.numRates < 12 )
        {
         int found = 0;
         int tail = tempRateSet.numRates;

          for( i = 0; (i < pExtRateSet->numRates && i < SIR_MAC_RATESET_EID_MAX); i++ )
          {
            found = 0;
            for( j = 0; j < (tANI_U32) tail; j++ )
            {
              if((tempRateSet.rate[j] & 0x7F) ==
                  (pExtRateSet->rate[i] & 0x7F))
              {
                found = 1;
                break;
              }
            }

            if( !found )
            {
              tempRateSet.rate[tempRateSet.numRates++] =
                pExtRateSet->rate[i];

              if( tempRateSet.numRates >= 12 )
                break;
            }
          }
        }
        else
          limLog( pMac, LOG2,
              "Relying only on the SUPPORTED Rate Set IE..." );
      }
      else
      {
        for(j = 0; ((j < pExtRateSet->numRates) && (j < SIR_MAC_RATESET_EID_MAX) && ((i+j) < SIR_MAC_RATESET_EID_MAX)); j++)
            tempRateSet.rate[i+j] = pExtRateSet->rate[j];

        tempRateSet.numRates += pExtRateSet->numRates;
      }
    }

    {
        tpSirSupportedRates  rates = &pStaDs->supportedRates;
        tANI_U8 aRateIndex = 0;
        tANI_U8 bRateIndex = 0;
        vos_mem_set((tANI_U8 *) rates, sizeof(tSirSupportedRates), 0);
        for(i = 0;(i < tempRateSet2.numRates && i < SIR_MAC_RATESET_EID_MAX ); i++)
        {
            for(j = 0;(j < tempRateSet.numRates && j < SIR_MAC_RATESET_EID_MAX); j++)
            {
                if ((tempRateSet2.rate[i] & 0x7F) ==
                    (tempRateSet.rate[j] & 0x7F))
                {
                    if (sirIsArate(tempRateSet2.rate[i] & 0x7f))
                    {
                        isArate=1;
                        if (aRateIndex < SIR_NUM_11A_RATES)
                            rates->llaRates[aRateIndex++] = tempRateSet2.rate[i];
                    }
                    else
                    {
                        if (bRateIndex < SIR_NUM_11B_RATES)
                            rates->llbRates[bRateIndex++] = tempRateSet2.rate[i];
                    }
                    break;
                }
            }
        }
    }


    //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n
#ifdef FEATURE_WLAN_TDLS
    if(pStaDs->mlmStaContext.htCapability)
#else
    if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
      (pStaDs->mlmStaContext.htCapability))
#endif
    {
        val = SIZE_OF_SUPPORTED_MCS_SET;
        if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
                      mcsSet,
                      &val) != eSIR_SUCCESS)
        {
            /// Could not get rateset from CFG. Log error.
            limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet"));
            goto error;
        }
        if (psessionEntry->vdev_nss == NSS_1x1_MODE)
            mcsSet[1] = 0;

        for(i=0; i<val; i++)
           pStaDs->supportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i];

        PELOG2(limLog(pMac, LOG2, FL("limPopulateMatchingRateSet: MCS Rate Set Bitmap from  CFG and DPH : "));)
        for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
        {
            PELOG2(limLog(pMac, LOG2,FL("%x %x "), mcsSet[i], pStaDs->supportedRates.supportedMCSSet[i]);)
        }
    }

#ifdef WLAN_FEATURE_11AC
    limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps,
                    psessionEntry, psessionEntry->vdev_nss);
#endif
    /**
      * Set the erpEnabled bit iff the phy is in G mode and at least
      * one A rate is supported
      */
    if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate)
        pStaDs->erpEnabled = eHAL_SET;



    return eSIR_SUCCESS;

 error:

    return eSIR_FAILURE;
} /*** limPopulateMatchingRateSet() ***/



/**
 * limAddSta()
 *
 *FUNCTION:
 * This function is called to add an STA context at hardware
 * whenever a STA is (Re) Associated.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac    - Pointer to Global MAC structure
 * @param  pStaDs  - Pointer to the STA datastructure created by
 *                   LIM and maintained by DPH
 * @return retCode - Indicates success or failure return code
 */

tSirRetStatus
limAddSta(
    tpAniSirGlobal  pMac,
    tpDphHashNode   pStaDs, tANI_U8 updateEntry, tpPESession psessionEntry)
{
    tpAddStaParams pAddStaParams = NULL;
    tSirMsgQ msgQ;
    tSirRetStatus     retCode = eSIR_SUCCESS;
    tSirMacAddr     staMac, *pStaAddr;
    tANI_U8 i, nwType11b = 0;
    tpSirAssocReq   pAssocReq;
    tLimIbssPeerNode *pPeerNode; /* for IBSS mode */
    tDot11fIEVHTCaps vht_caps;   /* for IBSS mode */
    tANI_U8  *p2pIe = NULL;

    sirCopyMacAddr(staMac,psessionEntry->selfMacAddr);

    limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
                       psessionEntry->smeSessionId, updateEntry,
                       GET_LIM_SYSTEM_ROLE(psessionEntry));

    pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams));
    if (NULL == pAddStaParams)
    {
       limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" ));
       return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0);

    if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_IBSS_ROLE(psessionEntry) ||
        LIM_IS_BT_AMP_AP_ROLE(psessionEntry))
        pStaAddr = &pStaDs->staAddr;
#ifdef FEATURE_WLAN_TDLS
    /* SystemRole shouldn't be matter if staType is TDLS peer */
    else if(STA_ENTRY_TDLS_PEER == pStaDs->staType)
        pStaAddr = &pStaDs->staAddr ;
#endif
    else if (STA_ENTRY_NDI_PEER == pStaDs->staType)
        pStaAddr = &pStaDs->staAddr;
    else
        pStaAddr = &staMac;

    limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": Subtype(Assoc/Reassoc): %d "),
    MAC_ADDR_ARRAY(*pStaAddr), pStaDs->mlmStaContext.subType);

    vos_mem_copy((tANI_U8 *) pAddStaParams->staMac,
                 (tANI_U8 *) *pStaAddr, sizeof(tSirMacAddr));
    vos_mem_copy((tANI_U8 *) pAddStaParams->bssId,
                  psessionEntry->bssId, sizeof(tSirMacAddr));
    vos_mem_copy(&pAddStaParams->capab_info,
                 &pStaDs->mlmStaContext.capabilityInfo,
                 sizeof(pAddStaParams->capab_info));

    limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry);

    //Copy legacy rates
    vos_mem_copy ((tANI_U8*)&pAddStaParams->supportedRates,
                  (tANI_U8*)&pStaDs->supportedRates, sizeof(tSirSupportedRates));

    pAddStaParams->assocId = pStaDs->assocId;

    pAddStaParams->wmmEnabled = pStaDs->qosMode;
    pAddStaParams->listenInterval = pStaDs->mlmStaContext.listenInterval;
    pAddStaParams->shortPreambleSupported = pStaDs->shortPreambleEnabled;
    if (LIM_IS_AP_ROLE(psessionEntry) &&
       (pStaDs->mlmStaContext.subType == LIM_REASSOC)) {
        /* TBD - need to remove this REASSOC check after fixing rmmod issue */
        pAddStaParams->updateSta = pStaDs->mlmStaContext.updateContext;
    }
    pStaDs->valid                  = 0;
    pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;

    limLog(pMac, LOG2, FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d"
    " shortPreambleSupported: %d "), pAddStaParams->assocId,
    pAddStaParams->wmmEnabled, pAddStaParams->listenInterval,
    pAddStaParams->shortPreambleSupported);
    // This will indicate HAL to "allocate" a new STA index
#ifdef FEATURE_WLAN_TDLS
    /* As there is corner case in-between add_sta and change_sta,if del_sta for other staIdx happened,
     * firmware return wrong staIdx (recently removed staIdx). Until we get a confirmation from the
     * firmware team it is now return correct staIdx for same sta_mac_addr for update case, we want
     * to get around it by passing valid staIdx given by add_sta time.
     */
    if((STA_ENTRY_TDLS_PEER == pStaDs->staType) &&
      (true == updateEntry))
        pAddStaParams->staIdx = pStaDs->staIndex;
    else
#endif
        pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
    pAddStaParams->staType = pStaDs->staType;

    pAddStaParams->updateSta = updateEntry;

    pAddStaParams->status = eHAL_STATUS_SUCCESS;
    pAddStaParams->respReqd = 1;
    //Update HT Capability

    if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
        LIM_IS_IBSS_ROLE(psessionEntry)) {
        pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability;
#ifdef WLAN_FEATURE_11AC
        pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability;
#endif
    }
#ifdef FEATURE_WLAN_TDLS
    /* SystemRole shouldn't be matter if staType is TDLS peer */
    else if(STA_ENTRY_TDLS_PEER == pStaDs->staType)
    {
        pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability;
#ifdef WLAN_FEATURE_11AC
        pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability;
#endif
    }
#endif
    else
    {
        pAddStaParams->htCapable = psessionEntry->htCapability;
#ifdef WLAN_FEATURE_11AC
        pAddStaParams->vhtCapable = psessionEntry->vhtCapability;
#endif

    }
#ifdef WLAN_FEATURE_11AC
    limLog(pMac, LOG2, FL("vhtCapable: %d "),pAddStaParams->vhtCapable);
#endif
    limLog(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
    pAddStaParams->staIdx,pAddStaParams->updateSta,
    pAddStaParams->htCapable);

    pAddStaParams->greenFieldCapable = pStaDs->htGreenfield;
    pAddStaParams->maxAmpduDensity= pStaDs->htAMpduDensity;
    pAddStaParams->maxAmpduSize = pStaDs->htMaxRxAMpduFactor;
    pAddStaParams->fDsssCckMode40Mhz = pStaDs->htDsssCckRate40MHzSupport;
    pAddStaParams->fShortGI20Mhz = pStaDs->htShortGI20Mhz;
    pAddStaParams->fShortGI40Mhz = pStaDs->htShortGI40Mhz;
    pAddStaParams->lsigTxopProtection = pStaDs->htLsigTXOPProtection;
    pAddStaParams->maxAmsduSize = pStaDs->htMaxAmsduLength;
    pAddStaParams->txChannelWidthSet = pStaDs->htSupportedChannelWidthSet;
    pAddStaParams->mimoPS = pStaDs->htMIMOPSState;

    limLog(pMac, LOG2, FL(" greenFieldCapable: %d maxAmpduDensity = %d "
    "maxAmpduDensity = %d"), pAddStaParams->greenFieldCapable,
    pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize);

    limLog(pMac, LOG2, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d "
    "fShortGI40Mhz: %d"), pAddStaParams->fDsssCckMode40Mhz,
    pAddStaParams->fShortGI20Mhz, pAddStaParams->fShortGI40Mhz);

    limLog(pMac, LOG2, FL("lsigTxopProtection: %d maxAmsduSize: %d "
    "txChannelWidthSet: %d mimoPS: %d "), pAddStaParams->lsigTxopProtection,
    pAddStaParams->maxAmsduSize,pAddStaParams->txChannelWidthSet,
    pAddStaParams->mimoPS);

#ifdef WLAN_FEATURE_11AC
    if(pAddStaParams->vhtCapable)
    {
        pAddStaParams->vhtTxChannelWidthSet = pStaDs->vhtSupportedChannelWidthSet;
        pAddStaParams->vhtSupportedRxNss = pStaDs->vhtSupportedRxNss;
        pAddStaParams->vhtTxBFCapable =
#ifdef FEATURE_WLAN_TDLS
        (( STA_ENTRY_PEER == pStaDs->staType ) || (STA_ENTRY_TDLS_PEER == pStaDs->staType)) ?
                pStaDs->vhtBeamFormerCapable : psessionEntry->txBFIniFeatureEnabled ;
#else
        ( STA_ENTRY_PEER == pStaDs->staType ) ? pStaDs->vhtBeamFormerCapable :
                                psessionEntry->txBFIniFeatureEnabled ;
#endif
        limLog(pMac, LOG2, FL("vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"),
        pAddStaParams->vhtTxChannelWidthSet,pAddStaParams->vhtTxBFCapable);
    }
#endif

#ifdef FEATURE_WLAN_TDLS
    if((STA_ENTRY_PEER == pStaDs->staType) ||
            (STA_ENTRY_TDLS_PEER == pStaDs->staType))
#else
    if (STA_ENTRY_PEER == pStaDs->staType)
#endif
    {
        /* peer STA get the LDPC capability from pStaDs, which populated from
         * HT/VHT capability*/
        if(pAddStaParams->vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP)
        {
            pAddStaParams->htLdpcCapable = 0;
            pAddStaParams->vhtLdpcCapable = 0;
        }
        else
        {
            if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
                pAddStaParams->htLdpcCapable = pStaDs->htLdpcCapable;
            else
                pAddStaParams->htLdpcCapable = 0;
            if (psessionEntry->txLdpcIniFeatureEnabled & 0x2)
                pAddStaParams->vhtLdpcCapable = pStaDs->vhtLdpcCapable;
            else
                pAddStaParams->vhtLdpcCapable = 0;
        }
    }
    else if( STA_ENTRY_SELF == pStaDs->staType)
    {
        /* For Self STA get the LDPC capability from config.ini*/
        pAddStaParams->htLdpcCapable =
                          (psessionEntry->txLdpcIniFeatureEnabled & 0x01);
        pAddStaParams->vhtLdpcCapable =
                          ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01);
    }

    /* Update PE session ID*/
    pAddStaParams->sessionId = psessionEntry->peSessionId;

    /* Update SME session ID */
    pAddStaParams->smesessionId = psessionEntry->smeSessionId;

    pAddStaParams->maxTxPower = psessionEntry->maxTxPower;

    if (psessionEntry->parsedAssocReq != NULL)
    {
    // Get a copy of the already parsed Assoc Request
       pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId];
       if ( pAssocReq && pAssocReq->addIEPresent && pAssocReq->addIE.length ) {
           p2pIe = limGetP2pIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
       }
       pAddStaParams->p2pCapableSta = (p2pIe != NULL);
       if ( pAssocReq && pAddStaParams->htCapable ) {
           vos_mem_copy(&pAddStaParams->ht_caps, ((tANI_U8 *) &pAssocReq->HTCaps) + 1,
                        sizeof(pAddStaParams->ht_caps));
       }
       if ( pAssocReq && pAddStaParams->vhtCapable) {
           pAddStaParams->vht_caps =
            ((pAssocReq->VHTCaps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
             (pAssocReq->VHTCaps.supportedChannelWidthSet <<
                                      SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
             (pAssocReq->VHTCaps.ldpcCodingCap <<
                                      SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
             (pAssocReq->VHTCaps.shortGI80MHz <<
                                      SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
             (pAssocReq->VHTCaps.shortGI160and80plus80MHz <<
                                      SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
             (pAssocReq->VHTCaps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
             (pAssocReq->VHTCaps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
             (pAssocReq->VHTCaps.suBeamFormerCap <<
                                      SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
             (pAssocReq->VHTCaps.suBeamformeeCap <<
                                      SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
             (pAssocReq->VHTCaps.csnofBeamformerAntSup <<
                                  SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
             (pAssocReq->VHTCaps.numSoundingDim <<
                                       SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
             (pAssocReq->VHTCaps.muBeamformerCap <<
                                     SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)|
             (pAssocReq->VHTCaps.muBeamformeeCap <<
                                    SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
             (pAssocReq->VHTCaps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) |
             (pAssocReq->VHTCaps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) |
             (pAssocReq->VHTCaps.maxAMPDULenExp <<
                                SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
             (pAssocReq->VHTCaps.vhtLinkAdaptCap <<
                                   SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
             (pAssocReq->VHTCaps.rxAntPattern <<
                               SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
             (pAssocReq->VHTCaps.txAntPattern <<
                               SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
             (pAssocReq->VHTCaps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2));
       }
    } else if (LIM_IS_IBSS_ROLE(psessionEntry)) {
       /* in IBSS mode, use peer node as the source of ht_caps and vht_caps */
       pPeerNode = limIbssPeerFind(pMac, *pStaAddr);
       if (!pPeerNode) {
             limLog( pMac, LOGP, FL("Can't find IBSS peer node for ADD_STA"));
             vos_mem_free(pAddStaParams);
             return eSIR_HAL_STA_DOES_NOT_EXIST;
       }

       if (pPeerNode->atimIePresent)
       {
           pAddStaParams->atimIePresent = pPeerNode->atimIePresent;
           pAddStaParams->peerAtimWindowLength =
                                   pPeerNode->peerAtimWindowLength;
       }

       pAddStaParams->ht_caps =
             ( pPeerNode->htSupportedChannelWidthSet <<
                               SIR_MAC_HT_CAP_CHWIDTH40_S ) |
             ( pPeerNode->htGreenfield               <<
                               SIR_MAC_HT_CAP_GREENFIELD_S ) |
             ( pPeerNode->htShortGI20Mhz             <<
                               SIR_MAC_HT_CAP_SHORTGI20MHZ_S ) |
             ( pPeerNode->htShortGI40Mhz             <<
                               SIR_MAC_HT_CAP_SHORTGI40MHZ_S ) |
             ( SIR_MAC_TXSTBC                        <<
                               SIR_MAC_HT_CAP_TXSTBC_S ) |
             ( SIR_MAC_RXSTBC                        <<
                               SIR_MAC_HT_CAP_RXSTBC_S ) |
             ( pPeerNode->htMaxAmsduLength           <<
                               SIR_MAC_HT_CAP_MAXAMSDUSIZE_S ) |
             ( pPeerNode->htDsssCckRate40MHzSupport  <<
                               SIR_MAC_HT_CAP_DSSSCCK40_S );

       vht_caps = pPeerNode->VHTCaps;
       pAddStaParams->vht_caps =
            ((vht_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
             (vht_caps.supportedChannelWidthSet <<
                               SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
             (vht_caps.ldpcCodingCap <<
                               SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
             (vht_caps.shortGI80MHz <<
                               SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
             (vht_caps.shortGI160and80plus80MHz <<
                               SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
             (vht_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
             (vht_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
             (vht_caps.suBeamFormerCap <<
                               SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
             (vht_caps.suBeamformeeCap <<
                               SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
             (vht_caps.csnofBeamformerAntSup <<
                               SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
             (vht_caps.numSoundingDim <<
                               SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
             (vht_caps.muBeamformerCap <<
                               SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)|
             (vht_caps.muBeamformeeCap <<
                               SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
             (vht_caps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) |
             (vht_caps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) |
             (vht_caps.maxAMPDULenExp <<
                               SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
             (vht_caps.vhtLinkAdaptCap <<
                               SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
             (vht_caps.rxAntPattern <<
                               SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
             (vht_caps.txAntPattern <<
                               SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
             (vht_caps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2));
    }

#ifdef FEATURE_WLAN_TDLS
    if (STA_ENTRY_TDLS_PEER == pStaDs->staType)
    {
        pAddStaParams->ht_caps = pStaDs->ht_caps;
        pAddStaParams->vht_caps = pStaDs->vht_caps;

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                  "%s: Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x",
                  __func__, pAddStaParams->ht_caps, pAddStaParams->vht_caps);
    }
#endif

#ifdef FEATURE_WLAN_TDLS
    if(pStaDs->wmeEnabled &&
      (LIM_IS_AP_ROLE(psessionEntry) ||
      (STA_ENTRY_TDLS_PEER == pStaDs->staType)))
#else
    if (pStaDs->wmeEnabled && LIM_IS_AP_ROLE(psessionEntry))
#endif
    {
        pAddStaParams->uAPSD = 0;
        /* update UAPSD and send it to LIM to add STA */
        // bitmap MSB <- LSB MSB 4 bits are for
        // trigger enabled AC setting and LSB 4 bits
        // are for delivery enabled AC setting
        // 7   6    5    4    3    2    1    0
        // BE  BK   VI   VO   BE   BK   VI   VO
        pAddStaParams->uAPSD |= pStaDs->qos.capability.qosInfo.acvo_uapsd;
        pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acvi_uapsd << 1);
        pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbk_uapsd << 2);
        pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbe_uapsd << 3);
        //making delivery enabled and trigger enabled setting the same.
        pAddStaParams->uAPSD |= pAddStaParams->uAPSD << 4;

        pAddStaParams->maxSPLen = pStaDs->qos.capability.qosInfo.maxSpLen;
        limLog( pMac, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"),
            pAddStaParams->uAPSD, pAddStaParams->maxSPLen);
    }

#ifdef WLAN_FEATURE_11W
    pAddStaParams->rmfEnabled = pStaDs->rmfEnabled;
    limLog( pMac, LOG1, FL( "PMF enabled %d"), pAddStaParams->rmfEnabled);
#endif

    limLog(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
    "p2pCapableSta: %d"), pAddStaParams->htLdpcCapable,
    pAddStaParams->vhtLdpcCapable, pAddStaParams->p2pCapableSta);

    if (!pAddStaParams->htLdpcCapable)
            pAddStaParams->ht_caps &= ~(1 << SIR_MAC_HT_CAP_ADVCODING_S);

    if (!pAddStaParams->vhtLdpcCapable)
            pAddStaParams->vht_caps &= ~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP);
    //we need to defer the message until we get the response back from HAL.
    if (pAddStaParams->respReqd)
        SET_LIM_PROCESS_DEFD_MESGS(pMac, false);

    for (i = 0; i < SIR_NUM_11A_RATES; i++)
    {
        if (sirIsArate(pStaDs->supportedRates.llaRates[i] & 0x7F))
        {
            nwType11b = 0;
            break;
        }
        else
        {
            nwType11b = 1;
        }
    }
    if (nwType11b)
    {
        pAddStaParams->nwType = eSIR_11B_NW_TYPE;
    }
    else
    {
        pAddStaParams->nwType = psessionEntry->nwType;
    }

    msgQ.type = WDA_ADD_STA_REQ;

    msgQ.reserved = 0;
    msgQ.bodyptr = pAddStaParams;
    msgQ.bodyval = 0;

    limLog(pMac, LOG1, FL("Sending WDA_ADD_STA_REQ for assocId %d"),
            pStaDs->assocId);
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    retCode = wdaPostCtrlMsg( pMac, &msgQ );
    if( eSIR_SUCCESS != retCode)
    {
       if (pAddStaParams->respReqd)
          SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        limLog( pMac, LOGE, FL("ADD_STA_REQ for aId %d failed (reason %X)"),
                            pStaDs->assocId, retCode );
        vos_mem_free(pAddStaParams);
    }

  return retCode;
}


/**
 * limDelSta()
 *
 *FUNCTION:
 * This function is called to delete an STA context at hardware
 * whenever a STA is disassociated
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac    - Pointer to Global MAC structure
 * @param  pStaDs  - Pointer to the STA datastructure created by
 *                   LIM and maintained by DPH
 * @param  fRespReqd - flag to indicate whether the delete is synchronous (true)
 *                   or not (false)
 * @return retCode - Indicates success or failure return code
 */

tSirRetStatus
limDelSta(
    tpAniSirGlobal  pMac,
    tpDphHashNode   pStaDs,
    tANI_BOOLEAN    fRespReqd,
    tpPESession     psessionEntry)
{
    tpDeleteStaParams pDelStaParams = NULL;
    tSirMsgQ msgQ;
    tSirRetStatus     retCode = eSIR_SUCCESS;

    pDelStaParams = vos_mem_malloc(sizeof( tDeleteStaParams ));
    if (NULL == pDelStaParams)
    {
        limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" ));
        return eSIR_MEM_ALLOC_FAILED;
    }

    vos_mem_set((tANI_U8 *) pDelStaParams, sizeof(tDeleteStaParams), 0);

  //
  // DPH contains the STA index only for "peer" STA entries.
  // LIM global contains "self" STA index
  // Thus,
  //    if( STA role )
  //      get STA index from LIM global
  //    else
  //      get STA index from DPH
  //

#ifdef FEATURE_WLAN_TDLS
    if ((LIM_IS_STA_ROLE(psessionEntry) &&
        (pStaDs->staType !=  STA_ENTRY_TDLS_PEER)) ||
         LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
#else
    if (LIM_IS_STA_ROLE(psessionEntry) || LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
#endif
      pDelStaParams->staIdx= psessionEntry->staId;

    else
      pDelStaParams->staIdx= pStaDs->staIndex;

    pDelStaParams->assocId = pStaDs->assocId;
    pStaDs->valid             = 0;

    if (! fRespReqd)
        pDelStaParams->respReqd = 0;
    else
    {
        //when limDelSta is called from processSmeAssocCnf then mlmState is already set properly.
        if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs))
        {
            MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
            SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, eLIM_MLM_WT_DEL_STA_RSP_STATE);
        }
        if (LIM_IS_STA_ROLE(psessionEntry) ||
             LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
            MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));

            psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;

        }
        pDelStaParams->respReqd = 1;
        //we need to defer the message until we get the response back from HAL.
        SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
    }

    /* Update PE session ID*/
    pDelStaParams->sessionId = psessionEntry->peSessionId;
    pDelStaParams->smesessionId = psessionEntry->smeSessionId;

    pDelStaParams->staType = pStaDs->staType;
    vos_mem_copy((tANI_U8 *)pDelStaParams->staMac,
                 (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr));

    pDelStaParams->status  = eHAL_STATUS_SUCCESS;
    msgQ.type = WDA_DELETE_STA_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pDelStaParams;
    msgQ.bodyval = 0;

    limLog( pMac, LOG1, FL( "Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ "
    "for STAID: %X and AssocID: %d MAC : "MAC_ADDRESS_STR ),
    pDelStaParams->sessionId,
    pDelStaParams->staIdx, pDelStaParams->assocId,
    MAC_ADDR_ARRAY(pStaDs->staAddr));

    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    retCode = wdaPostCtrlMsg( pMac, &msgQ );
    if( eSIR_SUCCESS != retCode)
    {
        if(fRespReqd)
           SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        limLog( pMac, LOGE, FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"),
                        retCode );
        vos_mem_free(pDelStaParams);
    }

    return retCode;
}

#if defined WLAN_FEATURE_VOWIFI_11R
/*------------------------------------------------------------------------
 * limAddFTStaSelf()
 *
 * FUNCTION:
 *
 * This function is called to add a STA once we have connected with a new
 * AP, that we have performed an FT to.
 *
 * The Add STA Response is created and now after the ADD Bss Is Successful
 * we add the self sta. We update with the association id from the reassoc
 * response from the AP.
 *------------------------------------------------------------------------
 */
tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId, tpPESession psessionEntry)
{
    tpAddStaParams   pAddStaParams = NULL;
    tSirRetStatus    retCode       = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pAddStaParams = psessionEntry->ftPEContext.pAddStaReq;
    pAddStaParams->assocId = assocId;
    pAddStaParams->smesessionId = psessionEntry->smeSessionId;

    msgQ.type = WDA_ADD_STA_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pAddStaParams;
    msgQ.bodyval = 0;

#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
                  "%s: Sending WDA_ADD_STA_REQ (aid %d)",
                  __func__, pAddStaParams->assocId);
#endif
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
           eLIM_MLM_WT_ADD_STA_RSP_STATE));
    psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
    if (eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ))) {
        limLog(pMac, LOGE,
               FL("Posting WDA_ADD_STA_REQ to HAL failed, reason=%X"), retCode);
        vos_mem_free(pAddStaParams);
    }
    psessionEntry->ftPEContext.pAddStaReq = NULL;
    return retCode;
}

#endif /* WLAN_FEATURE_VOWIFI_11R */

/**
 * limAddStaSelf()
 *
 *FUNCTION:
 * This function is called to add an STA context at hardware
 * whenever a STA is (Re) Associated.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac    - Pointer to Global MAC structure
 * @param  pStaDs  - Pointer to the STA datastructure created by
 *                   LIM and maintained by DPH
 * @return retCode - Indicates success or failure return code
 */

tSirRetStatus
limAddStaSelf(tpAniSirGlobal pMac,tANI_U16 staIdx, tANI_U8 updateSta, tpPESession psessionEntry)
{
    tpAddStaParams pAddStaParams = NULL;
    tSirMsgQ msgQ;
    tSirRetStatus     retCode = eSIR_SUCCESS;
    tSirMacAddr staMac;
    tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
    tANI_U32 shortGi20MhzSupport;
    tANI_U32 shortGi40MhzSupport;
    tANI_U32 ampduLenExponent = 0;
    tANI_U32 val;
    /*This self Sta dot 11 mode comes from the cfg and the expectation here is
     * that cfg carries the systemwide capability that device under
     * consideration can support. This capability gets plumbed into the cfg
     * cache at system initialization time via the .dat and .ini file override
     * mechanisms and will not change. If it does change, it is the
     * responsibility of SME to evict the selfSta and reissue a new AddStaSelf
     * command.*/
    tANI_U32 selfStaDot11Mode=0, selfTxWidth=0;
    wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode);
    limLog( pMac, LOG1, FL("cfgDot11Mode %d"),(int)selfStaDot11Mode);
    wlan_cfgGetInt(pMac,WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,&selfTxWidth);
    limLog( pMac, LOG1, FL("SGI 20 %d"),(int)selfTxWidth);
    limLog( pMac, LOG1, FL("Roam Channel Bonding Mode %d"),(int)pMac->roam.configParam.uCfgDot11Mode);

    sirCopyMacAddr(staMac,psessionEntry->selfMacAddr);
    limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": "),MAC_ADDR_ARRAY(staMac));
    pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams));
    if (NULL == pAddStaParams)
    {
        limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0);

    /// Add STA context at MAC HW (BMU, RHP & TFP)
    vos_mem_copy((tANI_U8 *) pAddStaParams->staMac,
                 (tANI_U8 *) staMac, sizeof(tSirMacAddr));

    vos_mem_copy((tANI_U8 *) pAddStaParams->bssId,
                 psessionEntry->bssId, sizeof(tSirMacAddr));

    pAddStaParams->assocId = psessionEntry->limAID;
    pAddStaParams->staType = STA_ENTRY_SELF;
    pAddStaParams->status = eHAL_STATUS_SUCCESS;
    pAddStaParams->respReqd = 1;

    /* Update  PE session ID */
    pAddStaParams->sessionId = psessionEntry->peSessionId;

    /* Update SME session ID */
    pAddStaParams->smesessionId = psessionEntry->smeSessionId;

    pAddStaParams->maxTxPower = psessionEntry->maxTxPower;

  // This will indicate HAL to "allocate" a new STA index
    pAddStaParams->staIdx = staIdx;
    pAddStaParams->updateSta = updateSta;

	if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) !=
			eSIR_SUCCESS) {
           limLog(pMac, LOGP, FL("Couldn't get SHORT_PREAMBLE, set default"));
	   pAddStaParams->shortPreambleSupported = 1;
        }
	pAddStaParams->shortPreambleSupported = val;

#ifdef WLAN_FEATURE_11AC
    limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry,NULL);
#else
    limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry);
#endif
    if ( IS_DOT11_MODE_HT(selfStaDot11Mode) )
    {
        pAddStaParams->htCapable = TRUE ;
        {
            pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry);
            pAddStaParams->txChannelWidthSet =
                  pMac->roam.configParam.channelBondingMode5GHz;
            pAddStaParams->mimoPS             = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry );
            pAddStaParams->rifsMode           = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry );
            pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry );
            pAddStaParams->delBASupport       = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry );
            pAddStaParams->maxAmpduDensity    = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry );
            pAddStaParams->maxAmpduSize       = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry);
            pAddStaParams->maxAmsduSize       = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry );
            pAddStaParams->max_amsdu_num      = limGetHTCapability(pMac,
                                                        eHT_MAX_AMSDU_NUM,
                                                        psessionEntry);
            pAddStaParams->fDsssCckMode40Mhz  = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry);
            /*
             * We will read the gShortGI20Mhz from ini file, and if it is set
             * to 1 then we will tell Peer that we support 40Mhz short GI
             */
            if (HAL_STATUS_SUCCESS(ccmCfgGetInt
                                   (pMac, WNI_CFG_SHORT_GI_20MHZ,
                                   &shortGi20MhzSupport)))
            {
                if (VOS_TRUE == shortGi20MhzSupport)
                {
                    pAddStaParams->fShortGI20Mhz =
                       WNI_CFG_SHORT_GI_20MHZ_STAMAX;
                }
                else
                {
                    pAddStaParams->fShortGI20Mhz = VOS_FALSE;
                }
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz"
                                             "CFG,setting value to default"));)
                pAddStaParams->fShortGI20Mhz = WNI_CFG_SHORT_GI_20MHZ_STADEF;
            }

            /*
             * We will read the gShortGI40Mhz from ini file, and if it is set
             * to 1 then we will tell Peer that we support 40Mhz short GI
             */
            if (HAL_STATUS_SUCCESS(ccmCfgGetInt
                                   (pMac, WNI_CFG_SHORT_GI_40MHZ,
                                   &shortGi40MhzSupport)))
            {
                if (VOS_TRUE == shortGi40MhzSupport)
                {
                    pAddStaParams->fShortGI40Mhz =
                       WNI_CFG_SHORT_GI_40MHZ_STAMAX;
                }
                else
                {
                    pAddStaParams->fShortGI40Mhz = VOS_FALSE;
                }
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz"
                                             "CFG,setting value to default"));)
                pAddStaParams->fShortGI40Mhz = WNI_CFG_SHORT_GI_40MHZ_STADEF;
            }
            limLog(pMac, LOG2, FL(" greenFieldCapable: %d maxAmpduDensity = %d "
            "maxAmpduSize = %d"), pAddStaParams->greenFieldCapable,
            pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize);

            limLog(pMac, LOG2, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d "
            "fShortGI40Mhz: %d lsigTxopProtection: %d"),
            pAddStaParams->fDsssCckMode40Mhz, pAddStaParams->fShortGI20Mhz,
            pAddStaParams->fShortGI40Mhz, pAddStaParams->lsigTxopProtection);

            limLog(pMac, LOG2, FL(" maxAmsduSize: %d txChannelWidthSet: %d "
            "mimoPS: %d rifsMode %d delBASupport %d"),
            pAddStaParams->maxAmsduSize,
            pAddStaParams->txChannelWidthSet, pAddStaParams->mimoPS,
            pAddStaParams->rifsMode, pAddStaParams->delBASupport );
       }
    }
#ifdef WLAN_FEATURE_11AC
    pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode);
    if (pAddStaParams->vhtCapable){
        pAddStaParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet;
        limLog( pMac, LOG1, FL("VHT WIDTH SET %d"),pAddStaParams->vhtTxChannelWidthSet);
    }
    pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled;
    limLog(pMac, LOG2, FL("vhtCapable: %d vhtTxBFCapable %d "),
    pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable);

    // In 11ac mode, the hardware is capable of supporting 128K AMPDU size
    if ( IS_DOT11_MODE_VHT(selfStaDot11Mode) )
    {
        if(wlan_cfgGetInt(pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &ampduLenExponent)
            != eSIR_SUCCESS)
        {
           limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT"));
        }
        pAddStaParams->maxAmpduSize = (tANI_U8)ampduLenExponent;
    }
    pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee;
    pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid;
#endif
    pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs;
    pAddStaParams->enableHtSmps = (psessionEntry->enableHtSmps &&
                                   (!psessionEntry->supported_nss_1x1));
    pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue;

    /* For Self STA get the LDPC capability from session i.e config.ini*/
    pAddStaParams->htLdpcCapable =
                      (psessionEntry->txLdpcIniFeatureEnabled & 0x01);
    pAddStaParams->vhtLdpcCapable =
                      ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01);

    if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS)
       limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
    pAddStaParams->listenInterval = (tANI_U16)listenInterval;

    if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona)
    {
        pAddStaParams->p2pCapableSta = 1;
    }

    pAddStaParams->supportedRates.opRateMode =
                                   limGetStaRateMode((tANI_U8)selfStaDot11Mode);

    limLog(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
    pAddStaParams->staIdx,pAddStaParams->updateSta,
    pAddStaParams->htCapable);

    limLog(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
    "p2pCapableSta: %d"),
    pAddStaParams->htLdpcCapable,pAddStaParams->vhtLdpcCapable,
    pAddStaParams->p2pCapableSta);
    /* As part of HS2.0 certification need to send reassoc
     * to the same AP to which STA connected .in this case
     * we are not sending delsta but sending only addsta
     * which is causing target asssert. to fix this
     * set  pAddStaParams->nonRoamReassoc = 1 and using this
     * skip sending the addsta to firmware
     */
    if (psessionEntry->isNonRoamReassoc) {
        pAddStaParams->nonRoamReassoc = 1;
        psessionEntry->isNonRoamReassoc = 0;
    }
    limLog(pMac, LOG2, FL("sessionid: %d  Assoc ID: %d listenInterval = %d "
                    "shortPreambleSupported: %d"), psessionEntry->smeSessionId,
                    pAddStaParams->assocId, pAddStaParams->listenInterval,
                    pAddStaParams->shortPreambleSupported);

    msgQ.type = WDA_ADD_STA_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pAddStaParams;
    msgQ.bodyval = 0;

    limLog(pMac, LOG1, FL(MAC_ADDRESS_STR":Sessionid %d : "
                        "Sending WDA_ADD_STA_REQ. (aid %d)"),
                        MAC_ADDR_ARRAY(pAddStaParams->staMac),
                        pAddStaParams->sessionId,
                        pAddStaParams->assocId);
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    if (eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ))) {
        limLog(pMac, LOGE,
               FL("Posting WDA_ADD_STA_REQ to HAL failed, reason=%X"), retCode);
        vos_mem_free(pAddStaParams);
    }
      return retCode;
}


/**
 * limTeardownInfraBSS()
 *
 *FUNCTION:
 * This function is called by various LIM functions to teardown
 * an established Infrastructure BSS
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @return None
 */

void
limTeardownInfraBss(tpAniSirGlobal pMac,tpPESession psessionEntry)
{
    tSirMacAddr   bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        /**
         * Send Broadcast Disassociate frame with
         * 'leaving BSS' reason.
         */
        limSendDisassocMgmtFrame(pMac,
                                 eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
                                 bcAddr,psessionEntry, FALSE);
} /*** end limTeardownInfraBss() ***/


/**
 * limHandleCnfWaitTimeout()
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue to handle
 * various confirmation failure cases.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @param  pStaDs - Pointer to a sta descriptor
 * @return None
 */

void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId)
{
    tpDphHashNode       pStaDs;
    tpPESession psessionEntry = NULL;

    if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId))== NULL)
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID"));
        return;
    }
    pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable);

    if (pStaDs == NULL)
    {
        PELOGW(limLog(pMac, LOGW, FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT."));)
        return;
    }

    switch (pStaDs->mlmStaContext.mlmState) {
        case eLIM_MLM_WT_ASSOC_CNF_STATE:
            PELOGW(limLog(pMac, LOGW, FL("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d"), pStaDs->assocId);)
            limPrintMacAddr(pMac, pStaDs->staAddr, LOGW);

            if (LIM_IS_AP_ROLE(psessionEntry) ||
                LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
                limRejectAssociation(
                            pMac,
                            pStaDs->staAddr,
                            pStaDs->mlmStaContext.subType,
                            true,
                            pStaDs->mlmStaContext.authType,
                            pStaDs->assocId,
                            true,
                            (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
                            psessionEntry);
            }
            break;

        default:
            limLog(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d"),
                   pStaDs->mlmStaContext.mlmState);
    }
}

/**
 * limDeleteDphHashEntry()
 *
 *FUNCTION:
 * This function is called whenever we need to delete
 * the dph hash entry
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  tANI_U16       staId
 * @return None
 */

void
limDeleteDphHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId,tpPESession psessionEntry)
{
    tANI_U16              aid;
    tpDphHashNode    pStaDs;
    tUpdateBeaconParams beaconParams;

    vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
    beaconParams.paramChangeBitmap = 0;
    limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, staId);
    if (NULL == psessionEntry)
    {
        PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));)
        return;
    }
    beaconParams.bssIdx = psessionEntry->bssIdx;
    pStaDs = dphLookupHashEntry(pMac, staAddr, &aid, &psessionEntry->dph.dphHashTable);
    if (pStaDs != NULL)
    {
         PELOGW(limLog(pMac, LOGW, FL("Deleting DPH Hash entry for STAID: %X"), staId);)
        // update the station count and perform associated actions
        // do this before deleting the dph hash entry
        limUtilCountStaDel(pMac, pStaDs, psessionEntry);

        if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_IBSS_ROLE(psessionEntry)) {
            if (LIM_IS_AP_ROLE(psessionEntry)) {
                if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE){
                limDecideApProtectionOnDelete(pMac, pStaDs, &beaconParams,psessionEntry);
                }
            }

            if (pStaDs->non_ecsa_capable) {
                    if (psessionEntry->lim_non_ecsa_cap_num == 0) {
                            limLog(pMac, LOGE,
                                   FL("Non ECSA sta cnt 0, sta: %d is ecsa\n"),
                                   staId);
                    } else {
                            psessionEntry->lim_non_ecsa_cap_num--;
                            limLog(pMac, LOGE,
                                   FL("reducing the non ECSA num to %d"),
                                   psessionEntry->lim_non_ecsa_cap_num);
                    }
            }

            if (LIM_IS_IBSS_ROLE(psessionEntry))
                limIbssDecideProtectionOnDelete(pMac, pStaDs, &beaconParams, psessionEntry);

            limDecideShortPreamble(pMac, pStaDs, &beaconParams, psessionEntry);
            limDecideShortSlot(pMac, pStaDs, &beaconParams, psessionEntry);

            //Send message to HAL about beacon parameter change.
            PELOGW(limLog(pMac, LOGW, FL("param bitmap = %d "), beaconParams.paramChangeBitmap);)
            if((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)
                && beaconParams.paramChangeBitmap)
            {
                schSetFixedBeaconFields(pMac,psessionEntry);
                limSendBeaconParams(pMac, &beaconParams, psessionEntry );
            }

#ifdef WLAN_FEATURE_11W
            tx_timer_delete(&pStaDs->pmfSaQueryTimer);
#endif
        }
        if (dphDeleteHashEntry(pMac, staAddr, staId, &psessionEntry->dph.dphHashTable) != eSIR_SUCCESS)
           limLog(pMac, LOGP, FL("error deleting hash entry"));
#ifdef SAP_AUTH_OFFLOAD
        lim_pop_sap_deferred_msg(pMac, psessionEntry);
#endif
    }
}

/**
 * limCheckAndAnnounceJoinSuccess()
 *
 *FUNCTION:
 * This function is called upon receiving Beacon/Probe Response
 * frame in WT_JOIN_BEACON_STATE to check if the received
 * Beacon/Probe Response is from the BSS that we're attempting
 * to join.
 *
 *LOGIC:
 * If the Beacon/Probe Response is indeed from the BSS we're
 * attempting to join, join success is sent to SME.
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  pBPR      Pointer to received Beacon/Probe Response
 * @param  pHdr      Pointer to received Beacon/Probe Response
 *                   MAC header
 * @return None
 */

void
limCheckAndAnnounceJoinSuccess(tpAniSirGlobal pMac,
                               tSirProbeRespBeacon *pBPR,
                               tpSirMacMgmtHdr pHdr,tpPESession psessionEntry)
{
    tSirMacSSid          currentSSID;
    tLimMlmJoinCnf       mlmJoinCnf;
    tANI_U32             val = 0;
    tANI_U32             *noa1DurationFromBcn = NULL;
    tANI_U32             *noa2DurationFromBcn = NULL;
    tANI_U32             noa;
    tANI_U32             TotalNum_NoADesc = 0;

    vos_mem_copy(currentSSID.ssId,
                 psessionEntry->ssId.ssId,
                 psessionEntry->ssId.length);

    currentSSID.length = (tANI_U8)psessionEntry->ssId.length ;

    if (
        /* Check for SSID only in probe response. Beacons may not carry
           SSID information in hidden SSID case */
        ( (SIR_MAC_MGMT_FRAME  == pHdr->fc.type) &&
          (SIR_MAC_MGMT_PROBE_RSP == pHdr->fc.subType) ) &&
        currentSSID.length &&
        (!vos_mem_compare((tANI_U8 *) &pBPR->ssId,
                   (tANI_U8 *) &currentSSID,
                   (tANI_U8) (1 + currentSSID.length)) ))
    {
        /**
         * Received SSID does not match with the one we've.
         * Ignore received Beacon frame
         */
        PELOG1(limLog(pMac, LOG1, FL("SSID received in Beacon does not match"));)
#ifdef WLAN_DEBUG
        pMac->lim.gLimBcnSSIDMismatchCnt++;
#endif
        return;
    }

    if (LIM_IS_BT_AMP_STA_ROLE(psessionEntry) ||
              LIM_IS_STA_ROLE(psessionEntry)) {
        limLog(pMac, LOG1, FL("Received Beacon/PR with matching BSSID"
                               MAC_ADDRESS_STR "PESessionID %d"),
                               MAC_ADDR_ARRAY(psessionEntry->bssId),
                               psessionEntry->peSessionId );

        // Deactivate Join Failure timer
        limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);
        // Deactivate Periodic Join timer
        limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);

    if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona &&
                                   pBPR->P2PProbeRes.NoticeOfAbsence.present)
    {

        noa1DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + 1);

        if(pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc)
            TotalNum_NoADesc = pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc/SIZE_OF_NOA_DESCRIPTOR;

        noa = *noa1DurationFromBcn;

        if(TotalNum_NoADesc > 1)
        {
            noa2DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + SIZE_OF_NOA_DESCRIPTOR + 1);
            noa += *noa2DurationFromBcn;
        }

        /*If MAX Noa exceeds 3 secs we will consider only 3 secs to
        * avoid arbitary values in noa duration field
        */
        noa = noa >  MAX_NOA_PERIOD_IN_MICROSECS ? MAX_NOA_PERIOD_IN_MICROSECS : noa;
        noa = noa/1000; //Convert to ms

        if( wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,&val) == eSIR_SUCCESS )
        {
            psessionEntry->defaultAuthFailureTimeout = val;
            ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT ,val + noa, NULL, eANI_BOOLEAN_FALSE);
        }
    }
    else
    {
        psessionEntry->defaultAuthFailureTimeout = 0;
    }

        // Update Beacon Interval at CFG database

        if ( pBPR->HTCaps.present )
            limUpdateStaRunTimeHTCapability( pMac, &pBPR->HTCaps );
        if ( pBPR->HTInfo.present )
            limUpdateStaRunTimeHTInfo( pMac, &pBPR->HTInfo, psessionEntry);
        psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_JOINED_STATE));


        /*
         * update the capability info based on recently
         * received beacon/probe response frame
         */
        psessionEntry->limCurrentBssCaps =
                limGetU16((tANI_U8 *)&pBPR->capabilityInfo);

        /**
         * Announce join success by sending
         * Join confirm to SME.
         */
        mlmJoinCnf.resultCode = eSIR_SME_SUCCESS;
        mlmJoinCnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS;
        /* Update PE sessionId*/
        mlmJoinCnf.sessionId = psessionEntry->peSessionId;
        limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
    } // if ((pMac->lim.gLimSystemRole == IBSS....

    if (psessionEntry->vhtCapability && pBPR->vendor2_ie.VHTCaps.present) {
        psessionEntry->is_vendor_specific_vhtcaps = true;
        psessionEntry->vendor_specific_vht_ie_type =
            pBPR->vendor2_ie.type;
        psessionEntry->vendor_specific_vht_ie_sub_type =
            pBPR->vendor2_ie.sub_type;
        limLog(pMac, LOG1, FL(
                    "VHT caps are present in vendor specific IE"));
    }

    /* Update HS 2.0 Information Element */
    sir_copy_hs20_ie(&psessionEntry->hs20vendor_ie, &pBPR->hs20vendor_ie);
}

/**
 * limExtractApCapabilities()
 *
 *FUNCTION:
 * This function is called to extract all of the AP's capabilities
 * from the IEs received from it in Beacon/Probe Response frames
 *
 *LOGIC:
 * This routine mimics the limExtractApCapability() API. The difference here
 * is that this API returns the entire tSirProbeRespBeacon info as is. It is
 * left to the caller of this API to use this info as required
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param   pMac         Pointer to Global MAC structure
 * @param   pIE          Pointer to starting IE in Beacon/Probe Response
 * @param   ieLen        Length of all IEs combined
 * @param   beaconStruct A pointer to tSirProbeRespBeacon that needs to be
 *                       populated
 * @return  status       A status reporting eSIR_SUCCESS or eSIR_FAILURE
 */
tSirRetStatus limExtractApCapabilities( tpAniSirGlobal pMac,
    tANI_U8 *pIE,
    tANI_U16 ieLen,
    tpSirProbeRespBeacon beaconStruct )
{
  vos_mem_set((tANI_U8 *) beaconStruct, sizeof( tSirProbeRespBeacon ), 0);

  PELOG3(limLog( pMac, LOG3,
      FL( "In limExtractApCapabilities: The IE's being received are:" ));
  sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );)

  // Parse the Beacon IE's, Don't try to parse if we dont have anything in IE
  if (ieLen > 0) {
  if( eSIR_SUCCESS != sirParseBeaconIE( pMac, beaconStruct, pIE, (tANI_U32)ieLen ))
  {
    limLog( pMac, LOGE, FL("APCapExtract: Beacon parsing error!"));
    return eSIR_FAILURE;
  }
  }

  return eSIR_SUCCESS;
}


/**
 * limDelBss()
 *
 *FUNCTION:
 * This function is called to delete BSS context at hardware
 * whenever a STA is disassociated
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac    - Pointer to Global MAC structure
 * @param  pStaDs  - Pointer to the STA datastructure created by
 *                   LIM and maintained by DPH
 * @return retCode - Indicates success or failure return code
 */

tSirRetStatus
limDelBss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tANI_U16 bssIdx,tpPESession psessionEntry)
{
    tpDeleteBssParams pDelBssParams = NULL;
    tSirMsgQ msgQ;
    tSirRetStatus     retCode = eSIR_SUCCESS;

    pDelBssParams = vos_mem_malloc(sizeof(tDeleteBssParams));
    if (NULL == pDelBssParams)
    {
        limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_BSS" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_set((tANI_U8 *) pDelBssParams, sizeof(tDeleteBssParams), 0);


    pDelBssParams->sessionId = psessionEntry->peSessionId; //update PE session Id

    //DPH was storing the AssocID in staID field,
    //staID is actually assigned by HAL when AddSTA message is sent.
    if (pStaDs != NULL)
    {
        pDelBssParams->bssIdx= pStaDs->bssId;
        pStaDs->valid                  = 0;
        pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
    }
    else
        pDelBssParams->bssIdx          = bssIdx;
    psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE));

    if((psessionEntry->peSessionId == pMac->lim.limTimers.gLimJoinFailureTimer.sessionId) &&
       (VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer)))
    {
        limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);
    }

    pDelBssParams->status= eHAL_STATUS_SUCCESS;
    pDelBssParams->respReqd = 1;
    vos_mem_copy(pDelBssParams->bssid, psessionEntry->bssId, sizeof(tSirMacAddr));
    pDelBssParams->smesessionId = psessionEntry->smeSessionId;
    PELOGW(limLog( pMac, LOGW, FL("Sessionid %d : Sending HAL_DELETE_BSS_REQ "
    "for bss idx: %X BSSID:"MAC_ADDRESS_STR), pDelBssParams->sessionId,
    pDelBssParams->bssIdx,
    MAC_ADDR_ARRAY(psessionEntry->bssId));)

    //we need to defer the message until we get the response back from HAL.
    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);

    msgQ.type = WDA_DELETE_BSS_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pDelBssParams;
    msgQ.bodyval = 0;

    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        limLog( pMac, LOGE, FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), retCode );
        vos_mem_free(pDelBssParams);
    }

    return retCode;
}

 /* lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response.
 * @pMac Pointer to Global MAC structure
 * @add_bss_params: parameters required for add bss params.
 * @vht_caps: VHT capabilities.
 * @session_entry : session entry.
 *
 * Return : void
 */
void lim_update_vhtcaps_assoc_resp(tpAniSirGlobal pMac,
                tpAddBssParams add_bss_params,
                tDot11fIEVHTCaps *vht_caps, tpPESession session_entry)
{
	add_bss_params->currentExtChannel = limGet11ACPhyCBState(pMac,
					add_bss_params->currentOperChannel,
					add_bss_params->currentExtChannel,
					session_entry->apCenterChan,
					session_entry);

	add_bss_params->staContext.vht_caps =
		((vht_caps->maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
		 (vht_caps->supportedChannelWidthSet <<
		  SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
		 (vht_caps->ldpcCodingCap <<
		  SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
		 (vht_caps->shortGI80MHz <<
		  SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
		 (vht_caps->shortGI160and80plus80MHz <<
		  SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
		 (vht_caps->txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
		 (vht_caps->rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
		 (vht_caps->suBeamFormerCap <<
		  SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
		 (vht_caps->suBeamformeeCap <<
		  SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
		 (vht_caps->csnofBeamformerAntSup <<
		  SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
		 (vht_caps->numSoundingDim <<
		  SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
		 (vht_caps->muBeamformerCap <<
		  SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)|
		 (vht_caps->muBeamformeeCap <<
		  SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
		 (vht_caps->vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) |
		 (vht_caps->htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) |
		 (vht_caps->maxAMPDULenExp <<
		  SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
		 (vht_caps->vhtLinkAdaptCap <<
		  SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
		 (vht_caps->rxAntPattern <<
		  SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
		 (vht_caps->txAntPattern <<
		  SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
		 (vht_caps->reserved1 << SIR_MAC_VHT_CAP_RESERVED2));

	add_bss_params->staContext.maxAmpduSize =
		SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
				add_bss_params->staContext.vht_caps);

	limLog(pMac, LOG1,
			FL("Updating VHT Caps in assoc Response"));
}

/**
 * lim_update_vht_oper_assoc_resp : Update VHT Operations in assoc response.
 * @pMac Pointer to Global MAC structure
 * @add_bss_params: parameters required for add bss params.
 * @vht_oper: VHT Operations to update.
 * @session_entry : session entry.
 *
 * Return : void
 */
void lim_update_vht_oper_assoc_resp(tpAniSirGlobal pMac,
		tpAddBssParams add_bss_params,
		tDot11fIEVHTOperation *vht_oper, tpPESession session_entry)
{
	if (vht_oper->chanWidth)
		add_bss_params->vhtTxChannelWidthSet = vht_oper->chanWidth;
	limLog(pMac, LOG1,
			FL("Updating VHT Operation in assoc Response"));
}


/**
 * limSendAddBss()
 *
 *FUNCTION:
 *
 *LOGIC:
 * 1) LIM receives eWNI_SME_JOIN_REQ
 * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends
 * SIR_HAL_ADD_BSS_REQ to HAL
 *
 *ASSUMPTIONS:
 * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq
 * ADD BSS parameters can be obtained from two sources:
 * 1) pMac->lim.gLimMlmJoinReq
 * 2) beaconStruct, passed as paramter
 * So, if a reqd parameter is found in bssDescriptions
 * then it is given preference over beaconStruct
 *
 *NOTE:
 *
 * @param  pMac Pointer to Global MAC structure
 *              pAssocRsp    contains the structured assoc/reassoc Response got from AP
 *              beaconstruct        Has the ProbeRsp/Beacon structured details
 *              bssDescription      bssDescription passed to PE from the SME
 * @return None
 */

tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
    tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry,
    tpPESession psessionEntry)

{
    tSirMsgQ msgQ;
    tpAddBssParams pAddBssParams = NULL;
    tSirRetStatus retCode = eSIR_SUCCESS;
    tpDphHashNode pStaDs = NULL;
    tANI_U8 chanWidthSupp = 0;
    tANI_U8 isVHTCapInVendorIE = 0;
    tANI_U32 shortGi20MhzSupport;
    tANI_U32 shortGi40MhzSupport;
    tANI_U32 enableTxBF20MHz;
    tDot11fIEVHTCaps *vht_caps = NULL;
    tDot11fIEVHTOperation *vht_oper = NULL;


    // Package SIR_HAL_ADD_BSS_REQ message parameters
    pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams ));
    if (NULL == pAddBssParams)
    {
        limLog( pMac, LOGP,
                FL( "Unable to allocate memory during ADD_BSS" ));
        retCode = eSIR_MEM_ALLOC_FAILED;
        goto returnFailure;
    }
    else
        vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0);

    vos_mem_copy(pAddBssParams->bssId,bssDescription->bssId,
                 sizeof(tSirMacAddr));
    // Fill in tAddBssParams selfMacAddr
    vos_mem_copy(pAddBssParams->selfMacAddr,
                 psessionEntry->selfMacAddr,
                 sizeof(tSirMacAddr));

    limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
                       psessionEntry->smeSessionId, updateEntry,
                       GET_LIM_SYSTEM_ROLE(psessionEntry));

    limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR),
    MAC_ADDR_ARRAY(pAddBssParams->bssId));

    if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
    {
         pAddBssParams->bssType = eSIR_BTAMP_AP_MODE;
    }
    else
    {
        pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE;
    }

    pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;

    /* Update PE session ID */
    pAddBssParams->sessionId = psessionEntry->peSessionId;

    pAddBssParams->beaconInterval = bssDescription->beaconInterval;

    pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
    pAddBssParams->updateBss = updateEntry;


    pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
    pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod;
    pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration;
    pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining;

    pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates;
    vos_mem_copy(pAddBssParams->rateSet.rate,
                 pAssocRsp->supportedRates.rate, pAssocRsp->supportedRates.numRates);

    if (IS_DOT11_MODE_11B(psessionEntry->dot11mode) &&
        bssDescription->nwType != eSIR_11B_NW_TYPE) {
        pAddBssParams->nwType = eSIR_11B_NW_TYPE;
    } else {
        pAddBssParams->nwType = bssDescription->nwType;
    }

    pAddBssParams->shortSlotTimeSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortSlotTime;
    pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist;
    pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist;
    pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist;
    pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist;

    limLog(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
    "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval,
    pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount);

    limLog(pMac, LOG2, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
    " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod,
    pAddBssParams->cfParamSet.cfpMaxDuration,
    pAddBssParams->cfParamSet.cfpDurRemaining,
    pAddBssParams->rateSet.numRates);

    limLog(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d"
    "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"),
    pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
    pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
    pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);

    pAddBssParams->dot11_mode = psessionEntry->dot11mode;
    limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode);

    // Use the advertised capabilities from the received beacon/PR


    if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pAssocRsp->HTCaps.present ))
    {
        pAddBssParams->htCapable = pAssocRsp->HTCaps.present;
        limLog(pMac, LOG2, FL("htCapable: %d"),pAddBssParams->htCapable);
        if ( pBeaconStruct->HTInfo.present )
        {
            pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pAssocRsp->HTInfo.opMode;
            pAddBssParams->dualCTSProtection = ( tANI_U8 ) pAssocRsp->HTInfo.dualCTSProtection;
            chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
            if( (pAssocRsp->HTCaps.supportedChannelWidthSet) &&
                (chanWidthSupp) )
            {
                pAddBssParams->txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet;
                pAddBssParams->currentExtChannel = pAssocRsp->HTInfo.secondaryChannelOffset;
            }
            else
            {
                pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
                pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED;
            }
            pAddBssParams->llnNonGFCoexist = (tANI_U8)pAssocRsp->HTInfo.nonGFDevicesPresent;
            pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pAssocRsp->HTInfo.lsigTXOPProtectionFullSupport;
            pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;

            limLog(pMac, LOG2, FL("htOperMode: %d dualCTSProtection: %d "
            "txChannelWidthSet: %d currentExtChannel: %d "),
            pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection,
            pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel);

            limLog(pMac, LOG2, FL("llnNonGFCoexist: %d "
            "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
            pAddBssParams->llnNonGFCoexist,
            pAddBssParams->fLsigTXOPProtectionFullSupport,
            pAddBssParams->fRIFSMode);
        }
    }

    pAddBssParams->currentOperChannel = bssDescription->channelId;
    limLog(pMac, LOG2, FL("currentOperChannel %d"),
    pAddBssParams->currentOperChannel);
#ifdef WLAN_FEATURE_11AC
    if (psessionEntry->vhtCapability && ( pAssocRsp->VHTCaps.present ))
    {
        pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present;
        pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac,
                                                                  pAddBssParams->currentOperChannel,
                                                                  pAddBssParams->currentExtChannel,
                                                                  psessionEntry->apCenterChan,
                                                                  psessionEntry);
        vht_caps =  &pAssocRsp->VHTCaps;
        vht_oper = &pAssocRsp->VHTOperation;
    } else if (psessionEntry->vhtCapability &&
	       pAssocRsp->vendor2_ie.VHTCaps.present) {
        pAddBssParams->vhtCapable =
                  pAssocRsp->vendor2_ie.VHTCaps.present;
        limLog(pMac, LOG1,
                 FL("VHT Caps and Operation are present in vendor Specfic IE"));
        vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
        vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
    }
    else
        pAddBssParams->vhtCapable = 0;

    if (pAddBssParams->vhtCapable) {
        if (vht_oper != NULL)
            lim_update_vht_oper_assoc_resp(pMac, pAddBssParams,
                                vht_oper, psessionEntry);
        if (vht_caps != NULL)
            lim_update_vhtcaps_assoc_resp(pMac, pAddBssParams,
                                vht_caps, psessionEntry);
    }

    limLog(pMac, LOG2, FL("vhtCapable %d vhtTxChannelWidthSet %d "
    "currentExtChannel %d"),pAddBssParams->vhtCapable,
    pAddBssParams->vhtTxChannelWidthSet,
    pAddBssParams->currentExtChannel);
#endif


    // Populate the STA-related parameters here
    // Note that the STA here refers to the AP
    {
        /* staType = PEER*/
        pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA

        vos_mem_copy(pAddBssParams->staContext.bssId,
                     bssDescription->bssId,
                     sizeof( tSirMacAddr));
        pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval;

        /* Fill Assoc id from the dph table */
        pStaDs = dphLookupHashEntry(pMac, pAddBssParams->staContext.bssId,
                &pAddBssParams->staContext.assocId, &psessionEntry->dph.dphHashTable);
        if (pStaDs == NULL)
        {
            PELOGE(limLog(pMac, LOGE, FL("Couldn't get assoc id for "
                       "MAC ADDR: " MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac));)
            retCode = eSIR_FAILURE;
            goto returnFailure;
        }

        if(!pMac->psOffloadEnabled)
        {
            pAddBssParams->staContext.uAPSD = 0;
        }
        else
        {
            pAddBssParams->staContext.uAPSD =
               psessionEntry->gUapsdPerAcBitmask;
        }

        pAddBssParams->staContext.maxSPLen = 0;
        pAddBssParams->staContext.shortPreambleSupported =
		psessionEntry->beaconParams.fShortPreamble;
        pAddBssParams->staContext.updateSta = updateEntry;

        limLog(pMac, LOG2, FL("StaContext: "MAC_ADDRESS_STR
        " shortPreambleSupported: %d"),
        MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
        pAddBssParams->staContext.shortPreambleSupported);

        if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && pBeaconStruct->HTCaps.present)
        {
            pAddBssParams->staContext.us32MaxAmpduDuration = 0;
            pAddBssParams->staContext.htCapable = 1;
            pAddBssParams->staContext.greenFieldCapable  = ( tANI_U8 )pAssocRsp->HTCaps.greenField;
            pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 )pAssocRsp->HTCaps.lsigTXOPProtection;
            limLog(pMac, LOG2,FL("StaContext htCapable: %d greenFieldCapable: %d "
            "lsigTxopProtection: %d"), pAddBssParams->staContext.htCapable,
            pAddBssParams->staContext.greenFieldCapable,
            pAddBssParams->staContext.lsigTxopProtection);
#ifdef WLAN_FEATURE_11AC
            if (psessionEntry->vhtCapability &&
                    (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
                     IS_BSS_VHT_CAPABLE(
                     pBeaconStruct->vendor2_ie.VHTCaps))) {
                pAddBssParams->staContext.vhtCapable = 1;
                pAddBssParams->staContext.vhtSupportedRxNss = pStaDs->vhtSupportedRxNss;
                if (pAssocRsp->VHTCaps.present)
                    vht_caps = &pAssocRsp->VHTCaps;
                else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
                      vht_caps =
                              &pAssocRsp->vendor2_ie.VHTCaps;
                      limLog(pMac, LOG1,
                              FL("VHT Caps is present in vendor Specfic IE"));
                      isVHTCapInVendorIE = 1;
                }
                if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
                      vht_caps->muBeamformerCap) &&
                      psessionEntry->txBFIniFeatureEnabled)
                    pAddBssParams->staContext.vhtTxBFCapable = 1;
                if ((vht_caps != NULL) &&
                            vht_caps->muBeamformerCap &&
                           psessionEntry->txMuBformee)
                    pAddBssParams->staContext.vhtTxMUBformeeCapable = 1;
            }
#endif
            if( (pAssocRsp->HTCaps.supportedChannelWidthSet) &&
                (chanWidthSupp) )
            {
                pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet;
#ifdef WLAN_FEATURE_11AC
                if (pAssocRsp->VHTCaps.present)
                    vht_oper = &pAssocRsp->VHTOperation;
                else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
                      vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
                      limLog(pMac, LOG1, FL("VHT Operation is present in vendor Specfic IE"));
                }

                if ((vht_oper != NULL) &&
                          pAddBssParams->staContext.vhtCapable)
                    pAddBssParams->staContext.vhtTxChannelWidthSet = vht_oper->chanWidth; //pMac->lim.apChanWidth;


                limLog(pMac, LOG2,FL("StaContext vhtCapable %d "
                "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"),
                pAddBssParams->staContext.vhtCapable,
                pAddBssParams->staContext.vhtTxChannelWidthSet,
                pAddBssParams->staContext.vhtTxBFCapable);
#endif
            }
            else
            {
                pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
                if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac,
                                        WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
                                        &enableTxBF20MHz))) {
                    if (VOS_FALSE == enableTxBF20MHz) {
                        pAddBssParams->staContext.vhtTxBFCapable = 0;
                    }
                }
            }
            pAddBssParams->staContext.mimoPS             = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave;
            pAddBssParams->staContext.delBASupport       = ( tANI_U8 )pAssocRsp->HTCaps.delayedBA;
            pAddBssParams->staContext.maxAmsduSize       = ( tANI_U8 )pAssocRsp->HTCaps.maximalAMSDUsize;
            pAddBssParams->staContext.maxAmpduDensity    =            pAssocRsp->HTCaps.mpduDensity;
            pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz;
            /*
             * We will check gShortGI20Mhz and gShortGI40Mhz from ini file.
             * if they are set then we will use what ever Assoc response coming
             * from AP supports. If these values are set as 0 in ini file then
             * we will hardcode this values to 0.
             */
            if (HAL_STATUS_SUCCESS(ccmCfgGetInt
                                   (pMac, WNI_CFG_SHORT_GI_20MHZ,
                                   &shortGi20MhzSupport)))
            {
                if (VOS_TRUE == shortGi20MhzSupport)
                {
                    pAddBssParams->staContext.fShortGI20Mhz =
                                   (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz;
                }
                else
                {
                    pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE;
                }
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz"
                                             "CFG,setting value to default"));)
                pAddBssParams->staContext.fShortGI20Mhz =
                    WNI_CFG_SHORT_GI_20MHZ_STADEF;
            }

            if (HAL_STATUS_SUCCESS(ccmCfgGetInt
                                   (pMac, WNI_CFG_SHORT_GI_40MHZ,
                                   &shortGi40MhzSupport)))
            {
                if (VOS_TRUE == shortGi40MhzSupport)
                {
                    pAddBssParams->staContext.fShortGI40Mhz =
                                   (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz;
                }
                else
                {
                    pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE;
                }
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz"
                                             "CFG,setting value to default"));)
                pAddBssParams->staContext.fShortGI40Mhz =
                    WNI_CFG_SHORT_GI_40MHZ_STADEF;
            }

#ifdef WLAN_FEATURE_11AC
            if (!pAddBssParams->staContext.vhtCapable)
                // Use max ampd factor advertised in HTCAP for non-vht connection
#endif
            {
               pAddBssParams->staContext.maxAmpduSize = pAssocRsp->HTCaps.maxRxAMPDUFactor;
            }
            else if (pAddBssParams->staContext.maxAmpduSize < pAssocRsp->HTCaps.maxRxAMPDUFactor)
            {
               pAddBssParams->staContext.maxAmpduSize = pAssocRsp->HTCaps.maxRxAMPDUFactor;
            }
            if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP )
            {
                pAddBssParams->staContext.htLdpcCapable = 0;
                pAddBssParams->staContext.vhtLdpcCapable = 0;
            }
            else
            {
                if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
                    pAddBssParams->staContext.htLdpcCapable =
                            (tANI_U8)pAssocRsp->HTCaps.advCodingCap;
                else
                    pAddBssParams->staContext.htLdpcCapable = 0;
                if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) {
                    if (!isVHTCapInVendorIE)
                        pAddBssParams->staContext.vhtLdpcCapable =
                            (tANI_U8)pAssocRsp->VHTCaps.ldpcCodingCap;
                    else
                        pAddBssParams->staContext.vhtLdpcCapable =
                            (tANI_U8)vht_caps->ldpcCodingCap;
                } else {
                    pAddBssParams->staContext.vhtLdpcCapable = 0;
                }
            }

            if( pBeaconStruct->HTInfo.present )
                pAddBssParams->staContext.rifsMode = pAssocRsp->HTInfo.rifsMode;

            limLog(pMac, LOG2, FL("StaContext txChannelWidthSet: %d mimoPS: %d"
            " delBASupport: %d maxAmsduSize: %d"),
            pAddBssParams->staContext.txChannelWidthSet,
            pAddBssParams->staContext.mimoPS,
            pAddBssParams->staContext.delBASupport,
            pAddBssParams->staContext.maxAmsduSize);

            limLog(pMac, LOG2, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d "
            "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity,
            pAddBssParams->staContext.fDsssCckMode40Mhz,
            pAddBssParams->staContext.fShortGI20Mhz);

            limLog(pMac, LOG2, FL("fShortGI40Mh: %d  maxAmpduSize: %d "
            "htLdpcCapable: %d vhtLdpcCapable: %d"),
            pAddBssParams->staContext.fShortGI40Mhz,
            pAddBssParams->staContext.maxAmpduSize,
            pAddBssParams->staContext.htLdpcCapable,
            pAddBssParams->staContext.vhtLdpcCapable);
        }
        pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId;
        pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
        pAddBssParams->staContext.wpa_rsn |= (pBeaconStruct->wpaPresent << 1);
        /* For OSEN Connection AP does not advertise RSN or WPA IE
         * so from the IEs we get from supplicant we get this info
         * so for FW to transmit EAPOL message 4 we shall set
         * wpa_rsn
         */
        if ((!pAddBssParams->staContext.wpa_rsn) && (psessionEntry->isOSENConnection))
            pAddBssParams->staContext.wpa_rsn = 1;
        vos_mem_copy(&pAddBssParams->staContext.capab_info,
                     &pAssocRsp->capabilityInfo,
                     sizeof(pAddBssParams->staContext.capab_info));
        vos_mem_copy(&pAddBssParams->staContext.ht_caps,
                     (tANI_U8 *)&pAssocRsp->HTCaps + sizeof(tANI_U8),
                     sizeof(pAddBssParams->staContext.ht_caps));

        //If WMM IE or 802.11E IE is present then enable WMM
        if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) ||
                (psessionEntry->limQosEnabled && pAssocRsp->edcaPresent))
            pAddBssParams->staContext.wmmEnabled = 1;
        else
            pAddBssParams->staContext.wmmEnabled = 0;

        //Update the rates

        pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
        if (pStaDs != NULL)
        {
            limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry);
            vos_mem_copy((tANI_U8*)&pAddBssParams->staContext.supportedRates,
                                                (tANI_U8*)&pStaDs->supportedRates,
                                                sizeof(tSirSupportedRates));
        }
        else
            PELOGE(limLog(pMac, LOGE, FL("could not Update the supported rates."));)

    }

    pAddBssParams->staContext.encryptType =  psessionEntry->encryptType;

#if defined WLAN_FEATURE_VOWIFI
    pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
    limLog(pMac, LOG2,FL("maxTxPower: %d"),
                       pAddBssParams->maxTxPower);
#endif
    // FIXME_GEN4 - Any other value that can be used for initialization?
    pAddBssParams->status = eHAL_STATUS_SUCCESS;
    pAddBssParams->respReqd = true;

    pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona

    if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona)
    {
        pAddBssParams->staContext.p2pCapableSta = 1;
    }

    pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;

#if defined WLAN_FEATURE_VOWIFI_11R
    pAddBssParams->extSetStaKeyParamValid = 0;
    limLog(pMac, LOG2,FL("extSetStaKeyParamValid: %d"),
                      pAddBssParams->extSetStaKeyParamValid);
#endif

#ifdef WLAN_FEATURE_11W
    if (psessionEntry->limRmfEnabled)
    {
        pAddBssParams->rmfEnabled = 1;
        pAddBssParams->staContext.rmfEnabled = 1;
    }
#endif

    // Set a new state for MLME
    if( eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState )
        psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE;
    else
        psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

    if (!pAddBssParams->staContext.htLdpcCapable)
        pAddBssParams->staContext.ht_caps &=
                ~(1 << SIR_MAC_HT_CAP_ADVCODING_S);
    if (!pAddBssParams->staContext.vhtLdpcCapable)
        pAddBssParams->staContext.vht_caps &=
                ~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP);

    limLog(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
    "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled,
    pAddBssParams->staContext.encryptType,
    pAddBssParams->staContext.p2pCapableSta);

    limLog(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
    "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled,
    pAddBssParams->halPersona, psessionEntry->limMlmState);
    if (psessionEntry->isNonRoamReassoc) {
        pAddBssParams->nonRoamReassoc = 1;
    }
    //we need to defer the message until we get the response back from HAL.
    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);

    if (psessionEntry->sub20_channelwidth == SUB20_MODE_5MHZ)
            pAddBssParams->channelwidth = CH_WIDTH_5MHZ;
    else if (psessionEntry->sub20_channelwidth == SUB20_MODE_10MHZ)
            pAddBssParams->channelwidth = CH_WIDTH_10MHZ;

    msgQ.type = WDA_ADD_BSS_REQ;
    /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
    msgQ.reserved = 0;
    msgQ.bodyptr = pAddBssParams;
    msgQ.bodyval = 0;

    limLog(pMac, LOG1, FL("SessionId:%d Sending WDA_ADD_BSS_REQ"),
           psessionEntry->peSessionId);
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    retCode = wdaPostCtrlMsg( pMac, &msgQ );
    if( eSIR_SUCCESS != retCode)
    {
        SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
                retCode );
        goto returnFailure;

    }
    else
        return retCode;

 returnFailure:
    if (pAddBssParams != NULL)
        vos_mem_free(pAddBssParams);
    // Clean-up will be done by the caller...
    return retCode;
}




tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry)
{
    tSirMsgQ msgQ;
    tpAddBssParams pAddBssParams = NULL;
    tANI_U32 retCode;
    tSchBeaconStruct *pBeaconStruct;
    tANI_U8 chanWidthSupp = 0;
    tANI_U32 shortGi20MhzSupport;
    tANI_U32 shortGi40MhzSupport;
    tpSirBssDescription bssDescription = &psessionEntry->pLimJoinReq->bssDescription;
    tDot11fIEVHTCaps *vht_caps = NULL;

    pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct));
    if (NULL == pBeaconStruct)
    {
        limLog(pMac, LOGE, FL("Unable to allocate memory during ADD_BSS") );
        return eSIR_MEM_ALLOC_FAILED;
    }


    // Package SIR_HAL_ADD_BSS_REQ message parameters
    pAddBssParams = vos_mem_malloc(sizeof(tAddBssParams));
    if (NULL == pAddBssParams)
    {
        limLog( pMac, LOGP,
                FL( "Unable to allocate memory during ADD_BSS" ));
        retCode = eSIR_MEM_ALLOC_FAILED;
        goto returnFailure;
    }

    vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0);


    limExtractApCapabilities(pMac,
                            (tANI_U8 *) bssDescription->ieFields,
                            GET_IE_LEN_IN_BSS(bssDescription->length),
                            pBeaconStruct);

    if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
        limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry);
    vos_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
                     sizeof(tSirMacAddr));

    // Fill in tAddBssParams selfMacAddr
    vos_mem_copy(pAddBssParams->selfMacAddr,
                 psessionEntry->selfMacAddr,
                 sizeof(tSirMacAddr));
    limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d"),
                       psessionEntry->smeSessionId, updateEntry,
                       GET_LIM_SYSTEM_ROLE(psessionEntry));

    limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR),
    MAC_ADDR_ARRAY(pAddBssParams->bssId));
    /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on
     * top of an already established Infra link. This lead to issues in
     * concurrent data transfer.
     */

    pAddBssParams->bssType = psessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE;
    pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;

    pAddBssParams->beaconInterval = bssDescription->beaconInterval;

    pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
    pAddBssParams->updateBss = updateEntry;


    pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
    pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod;
    pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration;
    pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining;


    pAddBssParams->rateSet.numRates = pBeaconStruct->supportedRates.numRates;
    vos_mem_copy(pAddBssParams->rateSet.rate,
                 pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates);

    pAddBssParams->nwType = bssDescription->nwType;

    pAddBssParams->shortSlotTimeSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortSlotTime;
    pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist;
    pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist;
    pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist;
    pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist;

    limLog(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
    "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval,
    pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount);

    limLog(pMac, LOG2, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
    " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod,
    pAddBssParams->cfParamSet.cfpMaxDuration,
    pAddBssParams->cfParamSet.cfpDurRemaining,
    pAddBssParams->rateSet.numRates);

    limLog(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d"
    "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"),
    pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
    pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
    pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
    // Use the advertised capabilities from the received beacon/PR
    if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present ))
    {
        pAddBssParams->htCapable = pBeaconStruct->HTCaps.present;
        limLog(pMac, LOG2, FL("htCapable: %d"),pAddBssParams->htCapable);
        if ( pBeaconStruct->HTInfo.present )
        {
            pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pBeaconStruct->HTInfo.opMode;
            pAddBssParams->dualCTSProtection = ( tANI_U8 ) pBeaconStruct->HTInfo.dualCTSProtection;

            chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
            if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
                (chanWidthSupp) )
            {
                pAddBssParams->txChannelWidthSet = ( tANI_U8 ) pBeaconStruct->HTInfo.recommendedTxWidthSet;
                pAddBssParams->currentExtChannel = pBeaconStruct->HTInfo.secondaryChannelOffset;
            }
            else
            {
                pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
                pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED;
            }
            pAddBssParams->llnNonGFCoexist = (tANI_U8)pBeaconStruct->HTInfo.nonGFDevicesPresent;
            pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pBeaconStruct->HTInfo.lsigTXOPProtectionFullSupport;
            pAddBssParams->fRIFSMode = pBeaconStruct->HTInfo.rifsMode;

            limLog(pMac, LOG2, FL("htOperMode: %d dualCTSProtection: %d "
            "txChannelWidthSet: %d currentExtChannel: %d "),
            pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection,
            pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel);

            limLog(pMac, LOG2, FL("llnNonGFCoexist: %d "
            "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
            pAddBssParams->llnNonGFCoexist,
            pAddBssParams->fLsigTXOPProtectionFullSupport,
            pAddBssParams->fRIFSMode);
        }
    }

    pAddBssParams->currentOperChannel = bssDescription->channelId;
    limLog(pMac, LOG2, FL("currentOperChannel %d"),
    pAddBssParams->currentOperChannel);
#ifdef WLAN_FEATURE_11AC
    if (psessionEntry->vhtCapability &&
            (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
             IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor2_ie.VHTCaps))) {
                pAddBssParams->vhtCapable = 1;
        /*
         * in limExtractApCapability function intersection of FW advertised
         * channel width and AP advertised channel width has been taken into
         * account for calculating psessionEntry->apChanWidth
         */
        pAddBssParams->vhtTxChannelWidthSet = psessionEntry->apChanWidth;

        pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac,
                                                                  pAddBssParams->currentOperChannel,
                                                                  pAddBssParams->currentExtChannel,
                                                                  psessionEntry->apCenterChan,
                                                                  psessionEntry);
        pAddBssParams->staContext.maxAmpduSize =
                                  SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
                                           pAddBssParams->staContext.vht_caps);
    }
    else
    {
        pAddBssParams->vhtCapable = 0;
    }
    limLog(pMac, LOG2, FL("vhtCapable %d vhtTxChannelWidthSet %d "
    "currentExtChannel %d"),pAddBssParams->vhtCapable,
    pAddBssParams->vhtTxChannelWidthSet,
    pAddBssParams->currentExtChannel);
#endif

    // Populate the STA-related parameters here
    // Note that the STA here refers to the AP
    {
        pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA

        vos_mem_copy(pAddBssParams->staContext.bssId,
                     bssDescription->bssId,
                     sizeof(tSirMacAddr));
        pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval;

        pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this?
        pAddBssParams->staContext.uAPSD = 0;
        pAddBssParams->staContext.maxSPLen = 0;
        pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortPreamble;
        pAddBssParams->staContext.updateSta = updateEntry;

        limLog(pMac, LOG2, FL("StaContext: "MAC_ADDRESS_STR
        " shortPreambleSupported: %d"),
        MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
        pAddBssParams->staContext.shortPreambleSupported);

        pAddBssParams->dot11_mode = psessionEntry->dot11mode;
        limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode);

        if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present ))
        {
            pAddBssParams->staContext.us32MaxAmpduDuration = 0;
            pAddBssParams->staContext.htCapable = 1;
            pAddBssParams->staContext.greenFieldCapable  = ( tANI_U8 ) pBeaconStruct->HTCaps.greenField;
            pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) pBeaconStruct->HTCaps.lsigTXOPProtection;
            limLog(pMac, LOG2, FL("StaContext htCapable: %d "
            "greenFieldCapable: %d lsigTxopProtection: %d"),
            pAddBssParams->staContext.htCapable,
            pAddBssParams->staContext.greenFieldCapable,
            pAddBssParams->staContext.lsigTxopProtection);
#ifdef WLAN_FEATURE_11AC
            if (psessionEntry->vhtCapability &&
                   (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
                    IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor2_ie.VHTCaps))) {
                pAddBssParams->staContext.vhtCapable = 1;
                if (pBeaconStruct->VHTCaps.present)
                        vht_caps = &pBeaconStruct->VHTCaps;
                else if (
                      pBeaconStruct->vendor2_ie.VHTCaps.present)
                        vht_caps =
                        &pBeaconStruct->vendor2_ie.VHTCaps;

                if ((vht_caps != NULL) &&
                        (vht_caps->suBeamFormerCap ||
                        vht_caps->muBeamformerCap) &&
                        psessionEntry->txBFIniFeatureEnabled)
                     pAddBssParams->staContext.vhtTxBFCapable = 1;
                if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
                                 psessionEntry->txMuBformee)
                    pAddBssParams->staContext.vhtTxMUBformeeCapable = 1;

            }
#endif
            if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
                (chanWidthSupp) )
            {
                pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet;
#ifdef WLAN_FEATURE_11AC
                if (pAddBssParams->staContext.vhtCapable)
                {
                    /*
                     * in limExtractApCapability function intersection of FW
                     * advertised channel width and AP advertised channel width
                     * has been taken into account for calculating
                     * psessionEntry->apChanWidth
                     */
                    pAddBssParams->staContext.vhtTxChannelWidthSet =
                        psessionEntry->apChanWidth;
                }
                limLog(pMac, LOG2,FL("StaContext vhtCapable %d "
                "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"),
                pAddBssParams->staContext.vhtCapable,
                pAddBssParams->staContext.vhtTxChannelWidthSet,
                pAddBssParams->staContext.vhtTxBFCapable);
#endif
            }
            else
            {
                pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
            }
            pAddBssParams->staContext.mimoPS             = (tSirMacHTMIMOPowerSaveState)pBeaconStruct->HTCaps.mimoPowerSave;
            pAddBssParams->staContext.delBASupport       = ( tANI_U8 ) pBeaconStruct->HTCaps.delayedBA;
            pAddBssParams->staContext.maxAmsduSize       = ( tANI_U8 ) pBeaconStruct->HTCaps.maximalAMSDUsize;
            pAddBssParams->staContext.maxAmpduDensity    =             pBeaconStruct->HTCaps.mpduDensity;
            pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pBeaconStruct->HTCaps.dsssCckMode40MHz;
            /*
             * We will check gShortGI20Mhz and gShortGI40Mhz from ini file.
             * if they are set then we will use what ever Beacon coming from AP
             * supports. If these values are set as 0 in ini file then
             * we will hardcode this values to 0.
             */
            if (HAL_STATUS_SUCCESS(ccmCfgGetInt
                                   (pMac, WNI_CFG_SHORT_GI_20MHZ,
                                   &shortGi20MhzSupport)))
            {
                if (VOS_TRUE == shortGi20MhzSupport)
                {
                    pAddBssParams->staContext.fShortGI20Mhz =
                                  (tANI_U8)pBeaconStruct->HTCaps.shortGI20MHz;
                }
                else
                {
                    pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE;
                }
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz"
                                             "CFG,setting value to default"));)
                pAddBssParams->staContext.fShortGI20Mhz =
                    WNI_CFG_SHORT_GI_20MHZ_STADEF;
            }

            if (HAL_STATUS_SUCCESS(ccmCfgGetInt
                                   (pMac, WNI_CFG_SHORT_GI_40MHZ,
                                   &shortGi40MhzSupport)))
            {
                if (VOS_TRUE == shortGi40MhzSupport)
                {
                    pAddBssParams->staContext.fShortGI40Mhz =
                                  (tANI_U8)pBeaconStruct->HTCaps.shortGI40MHz;
                }
                else
                {
                    pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE;
                }
            }
            else
            {
                PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz"
                                             "CFG,setting value to default"));)
                pAddBssParams->staContext.fShortGI40Mhz =
                    WNI_CFG_SHORT_GI_40MHZ_STADEF;
            }

            pAddBssParams->staContext.maxAmpduSize= pBeaconStruct->HTCaps.maxRxAMPDUFactor;
            if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP )
            {
                pAddBssParams->staContext.htLdpcCapable = 0;
                pAddBssParams->staContext.vhtLdpcCapable = 0;
            }
            else
            {
                if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
                    pAddBssParams->staContext.htLdpcCapable =
                            (tANI_U8)pBeaconStruct->HTCaps.advCodingCap;
                else
                    pAddBssParams->staContext.htLdpcCapable = 0;
                if (psessionEntry->txLdpcIniFeatureEnabled & 0x2)
                    pAddBssParams->staContext.vhtLdpcCapable =
                        (tANI_U8)pBeaconStruct->VHTCaps.ldpcCodingCap;
                else
                    pAddBssParams->staContext.vhtLdpcCapable = 0;
            }

            if( pBeaconStruct->HTInfo.present )
                pAddBssParams->staContext.rifsMode = pBeaconStruct->HTInfo.rifsMode;
            limLog(pMac, LOG2, FL("StaContext txChannelWidthSet: %d mimoPS: %d"
            " delBASupport: %d maxAmsduSize: %d"),
            pAddBssParams->staContext.txChannelWidthSet,
            pAddBssParams->staContext.mimoPS,
            pAddBssParams->staContext.delBASupport,
            pAddBssParams->staContext.maxAmsduSize);

            limLog(pMac, LOG2, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d "
            "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity,
            pAddBssParams->staContext.fDsssCckMode40Mhz,
            pAddBssParams->staContext.fShortGI20Mhz);

            limLog(pMac, LOG2, FL("fShortGI40Mh: %d  maxAmpduSize: %d "
            "htLdpcCapable: %d vhtLdpcCapable: %d"),
            pAddBssParams->staContext.fShortGI40Mhz,
            pAddBssParams->staContext.maxAmpduSize,
            pAddBssParams->staContext.htLdpcCapable,
            pAddBssParams->staContext.vhtLdpcCapable);
        }

       //If WMM IE or 802.11E IE is not present and AP is HT AP then enable WMM
       if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent || pAddBssParams->staContext.htCapable)) ||
                (psessionEntry->limQosEnabled && (pBeaconStruct->edcaPresent || pAddBssParams->staContext.htCapable)))
            pAddBssParams->staContext.wmmEnabled = 1;
        else
            pAddBssParams->staContext.wmmEnabled = 0;

        //Update the rates
#ifdef WLAN_FEATURE_11AC
        limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates,
                                        pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry,
                                        &pBeaconStruct->VHTCaps);
#else
        limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates,
                                        pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry);
#endif
        limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,psessionEntry);

    }

    pAddBssParams->staContext.encryptType = psessionEntry->encryptType;

#if defined WLAN_FEATURE_VOWIFI
    pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
    limLog(pMac, LOG2,FL("maxTxPower: %d"),
                       pAddBssParams->maxTxPower);
#endif

    pAddBssParams->status = eHAL_STATUS_SUCCESS;
    pAddBssParams->respReqd = true;

    pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId;
    pAddBssParams->staContext.sessionId = psessionEntry->peSessionId;
    pAddBssParams->sessionId = psessionEntry->peSessionId;

    pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona

    pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;

#if defined WLAN_FEATURE_VOWIFI_11R
    pAddBssParams->extSetStaKeyParamValid = 0;
    limLog(pMac, LOG2,FL("extSetStaKeyParamValid: %d"),
                      pAddBssParams->extSetStaKeyParamValid);
#endif

#ifdef WLAN_FEATURE_11W
    if (psessionEntry->limRmfEnabled)
    {
        pAddBssParams->rmfEnabled = 1;
        pAddBssParams->staContext.rmfEnabled = 1;
    }
#endif

    // Set a new state for MLME
    psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;

    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

    limLog(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
    "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled,
    pAddBssParams->staContext.encryptType,
    pAddBssParams->staContext.p2pCapableSta);

    limLog(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
    "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled,
    pAddBssParams->halPersona, psessionEntry->limMlmState);

    //we need to defer the message until we get the response back from HAL.
    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);

    if (psessionEntry->sub20_channelwidth == SUB20_MODE_5MHZ)
            pAddBssParams->channelwidth = CH_WIDTH_5MHZ;
    else if (psessionEntry->sub20_channelwidth == SUB20_MODE_10MHZ)
            pAddBssParams->channelwidth = CH_WIDTH_10MHZ;

    msgQ.type = WDA_ADD_BSS_REQ;
    /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
    msgQ.reserved = 0;
    msgQ.bodyptr = pAddBssParams;
    msgQ.bodyval = 0;

    limLog(pMac, LOG1, FL("SessionId:%d Sending WDA_ADD_BSS_REQ"),
           psessionEntry->peSessionId);
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    retCode = wdaPostCtrlMsg( pMac, &msgQ );
    if( eSIR_SUCCESS != retCode)
    {
        SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        vos_mem_free(pAddBssParams);
        limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
                retCode );
        goto returnFailure;

    }
    else
    {
        vos_mem_free(pBeaconStruct);
        return retCode;
    }

 returnFailure:
    // Clean-up will be done by the caller...
    vos_mem_free(pBeaconStruct);
    return retCode;
}






/** -------------------------------------------------------------
\fn limPrepareAndSendDelStaCnf
\brief deletes DPH entry
                    changes the MLM mode for station.
                    calls limSendDelStaCnf
\param     tpAniSirGlobal    pMac
\param         tpDphHashNode pStaDs
\return none
  -------------------------------------------------------------*/


void
limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession psessionEntry)
{
    tANI_U16 staDsAssocId = 0;
    tSirMacAddr staDsAddr;
    tLimMlmStaContext mlmStaContext;

    if(pStaDs == NULL)
    {
      PELOGW(limLog(pMac, LOGW, FL("pStaDs is NULL"));)
      return;
    }
    staDsAssocId = pStaDs->assocId;
    vos_mem_copy((tANI_U8 *)staDsAddr,
            pStaDs->staAddr,
            sizeof(tSirMacAddr));

    mlmStaContext = pStaDs->mlmStaContext;
    if (LIM_IS_AP_ROLE(psessionEntry) ||
        LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
        limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry);
    }
    limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry);

    if (LIM_IS_STA_ROLE(psessionEntry) ||
        LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
        psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE,
                        psessionEntry->peSessionId, psessionEntry->limMlmState));
    }
    limSendDelStaCnf(pMac, staDsAddr, staDsAssocId, mlmStaContext, statusCode,psessionEntry);
}

/** -------------------------------------------------------------
\fn limGetStaRateMode
\brief Gets the Station Rate Mode.
\param     tANI_U8 dot11Mode
\return none
  -------------------------------------------------------------*/
tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode)
{
    switch(dot11Mode)
        {
            case WNI_CFG_DOT11_MODE_11A:
                return eSTA_11a;
            case WNI_CFG_DOT11_MODE_11B:
                return eSTA_11b;
            case WNI_CFG_DOT11_MODE_11G:
                return eSTA_11bg;
            case WNI_CFG_DOT11_MODE_11N:
                return eSTA_11n;
#ifdef WLAN_FEATURE_11AC
            case WNI_CFG_DOT11_MODE_11AC:
                return eSTA_11ac;
#endif
            case WNI_CFG_DOT11_MODE_ALL:
            default:
                return eSTA_11n;

        }
}

/** -------------------------------------------------------------
\fn limInitPreAuthTimerTable
\brief Initialize the Pre Auth Tanle and creates the timer for
       each node for the timeout value got from cfg.
\param     tpAniSirGlobal    pMac
\param     tpLimPreAuthTable pPreAuthTimerTable
\return none
  -------------------------------------------------------------*/
void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable)
{
    tANI_U32 cfgValue;
    tANI_U32 authNodeIdx;
    tLimPreAuthNode **pAuthNode = pPreAuthTimerTable->pTable;

    // Get AUTH_RSP Timers value

    if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
                 &cfgValue) != eSIR_SUCCESS)
    {
        /*
        ** Could not get AUTH_RSP timeout value
        ** from CFG. Log error.
        **/
        limLog(pMac, LOGP,
               FL("could not retrieve AUTH_RSP timeout value"));
        return;
    }

    cfgValue = SYS_MS_TO_TICKS(cfgValue);
    for(authNodeIdx=0; authNodeIdx<pPreAuthTimerTable->numEntry; authNodeIdx++)
    {
        if (tx_timer_create(&(pAuthNode[authNodeIdx]->timer),
                        "AUTH RESPONSE TIMEOUT",
                        limAuthResponseTimerHandler,
                        authNodeIdx,
                        cfgValue,
                        0,
                        TX_NO_ACTIVATE) != TX_SUCCESS)
        {
            // Cannot create timer.  Log error.
            limLog(pMac, LOGP, FL("Cannot create Auth Rsp timer of Index :%d."), authNodeIdx);
            return;
        }
        pAuthNode[authNodeIdx]->authNodeIdx = (tANI_U8)authNodeIdx;
        pAuthNode[authNodeIdx]->fFree = 1;
    }
}

/** -------------------------------------------------------------
\fn limAcquireFreePreAuthNode
\brief Retrives a free Pre Auth node from Pre Auth Table.
\param     tpAniSirGlobal    pMac
\param     tpLimPreAuthTable pPreAuthTimerTable
\return none
  -------------------------------------------------------------*/
tLimPreAuthNode * limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable)
{
    tANI_U32 i;
    tLimPreAuthNode **pTempNode = pPreAuthTimerTable->pTable;
    for (i=0; i < pPreAuthTimerTable->numEntry; i++) {
        if (pTempNode[i]->fFree == 1) {
            pTempNode[i]->fFree = 0;
            return pTempNode[i];
        }
    }

    return NULL;
}

/** -------------------------------------------------------------
\fn limGetPreAuthNodeFromIndex
\brief Depending on the Index this retrives the pre auth node.
\param     tpAniSirGlobal    pMac
\param     tpLimPreAuthTable pAuthTable
\param     tANI_U32 authNodeIdx
\return none
  -------------------------------------------------------------*/
tLimPreAuthNode * limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac,
                               tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx)
{
    if ((authNodeIdx >= pAuthTable->numEntry) || (pAuthTable->pTable == NULL))
    {
        limLog(pMac, LOGE, FL("Invalid Auth Timer Index : %d NumEntry : %d"),
                  authNodeIdx, pAuthTable->numEntry);
        return NULL;
    }

    return pAuthTable->pTable[authNodeIdx];
}

/* Util API to check if the channels supported by STA is within range */
tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc)
{
    /*
         * Allow all the stations to join with us.
         * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs
         * as an input into an algorithm used to select a new channel for the BSS.
         * The specification of the algorithm is beyond the scope of this amendment.
         */

    return (eSIR_SUCCESS);
}

/* Util API to check if the txpower supported by STA is within range */
tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession psessionEntry)
{
    tPowerdBm localMaxTxPower;
    tANI_U32 localPwrConstraint;

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

    if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
        limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" ));
        return eSIR_FAILURE;
    }
    localMaxTxPower -= (tPowerdBm)localPwrConstraint;

    /**
         *  The min Tx Power of the associating station should not be greater than (regulatory
         *  max tx power - local power constraint configured on AP).
         */
    if(assoc->powerCapability.minTxPower > localMaxTxPower)
    {
        limLog(pMac, LOGW, FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d"),
                       assoc->powerCapability.minTxPower, localMaxTxPower);
        return (eSIR_FAILURE);
    }

    return (eSIR_SUCCESS);
}

/** -------------------------------------------------------------
\fn     limFillRxHighestSupportedRate
\brief  Fills in the Rx Highest Supported Data Rate field from
\       the 'supported MCS set' field in HT capability element.
\param  tpAniSirGlobal    pMac
\param  tpSirSupportedRates  pRates
\param  tANI_U8*  pSupportedMCSSet
\return none
  -------------------------------------------------------------*/
void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet)
{
    tSirMacRxHighestSupportRate  *pRxHighestRate;
    tANI_U8  *pBuf;
    tANI_U16  rate=0;

    pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET;
    rate = limGetU16(pBuf);

    pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate;
    *rxHighestRate = pRxHighestRate->rate;

    return;
}

#ifdef WLAN_FEATURE_11W
/** -------------------------------------------------------------
\fn     limSendSmeUnprotectedMgmtFrameInd
\brief  Forwards the unprotected management frame to SME.
\param  tpAniSirGlobal    pMac
\param  frameType - 802.11 frame type
\param  frame - frame buffer
\param  sessionId - id for the current session
\param  psessionEntry - PE session context
\return none
  -------------------------------------------------------------*/
void limSendSmeUnprotectedMgmtFrameInd(
                        tpAniSirGlobal pMac, tANI_U8 frameType,
                        tANI_U8  *frame, tANI_U32 frameLen, tANI_U16 sessionId,
                        tpPESession psessionEntry)
{
    tSirMsgQ mmhMsg;
    tSirSmeUnprotMgmtFrameInd * pSirSmeMgmtFrame = NULL;
    tANI_U16 length;

    length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen;

    pSirSmeMgmtFrame = vos_mem_malloc(length);
    if (NULL == pSirSmeMgmtFrame)
    {
        limLog(pMac, LOGP,
               FL("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd"));
        return;
    }
    vos_mem_set((void*)pSirSmeMgmtFrame, length, 0);

    pSirSmeMgmtFrame->sessionId = sessionId;
    pSirSmeMgmtFrame->frameType = frameType;

    vos_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
    pSirSmeMgmtFrame->frameLen = frameLen;

    mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND;
    mmhMsg.bodyptr = pSirSmeMgmtFrame;
    mmhMsg.bodyval = 0;

    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
    return;
}
#endif

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/** -------------------------------------------------------------
\fn     limSendSmeTsmIEInd
\brief  Forwards the TSM IE information to SME.
\param  tpAniSirGlobal    pMac
\param  psessionEntry - PE session context
\param  tid - traffic id
\param  state - tsm state (enabled/disabled)
\param  measurementInterval - measurement interval
\return none
  -------------------------------------------------------------*/
void limSendSmeTsmIEInd(tpAniSirGlobal pMac, tpPESession psessionEntry,
                            tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval)
{
    tSirMsgQ         mmhMsg;
    tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL;

    if (!pMac || !psessionEntry)
    {
        return;
    }
    pSirSmeTsmIeInd = vos_mem_malloc(sizeof(tSirSmeTsmIEInd));
    if (NULL == pSirSmeTsmIeInd)
    {
        limLog(pMac, LOGP,
               FL("AllocateMemory failed for tSirSmeTsmIEInd"));
        return;
    }
    vos_mem_set((void*)pSirSmeTsmIeInd, sizeof(tSirSmeTsmIEInd), 0);

    pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId;
    pSirSmeTsmIeInd->tsmIe.tsid = tid;
    pSirSmeTsmIeInd->tsmIe.state= state;
    pSirSmeTsmIeInd->tsmIe.msmt_interval= measInterval;

    mmhMsg.type = eWNI_SME_TSM_IE_IND;
    mmhMsg.bodyptr = pSirSmeTsmIeInd;
    mmhMsg.bodyval = 0;

    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
    return;
}
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */

void lim_aid_init(aid_t *aid)
{
	mutex_init(&aid->lock);
	aid->valid = false;
}

void lim_send_aid_req_to_sme(tpAniSirGlobal mac, sir_aid_req_t *aid_req)
{
	mac->sme.aid_req_cb(mac->hHdd, aid_req);

	return;
}

tSirRetStatus lim_get_peer_idx_by_user(tpAniSirGlobal mac,
				       tpPESession session,
				       uint8_t *sa,
				       uint8_t type,
				       uint16_t *peer_idx)
{
	tSirRetStatus ret = eSIR_SUCCESS;
	aid_t *aid;
	sir_aid_req_t aid_req;

	vos_mem_copy(aid_req.bssid, session->bssId, VOS_MAC_ADDR_SIZE);
	vos_mem_copy(aid_req.sa, sa, VOS_MAC_ADDR_SIZE);
	aid_req.type = type;
	lim_send_aid_req_to_sme(mac, &aid_req);

	aid = &session->aid;
	init_completion(&aid->timeout);
	mutex_lock(&aid->lock);
	aid->valid = true;
	mutex_unlock(&aid->lock);

	if (!wait_for_completion_timeout(&aid->timeout, msecs_to_jiffies(100))) {
		limLog(mac, LOGE, FL("timeout to get peer idx"));
		mutex_lock(&aid->lock);
		aid->valid = false;
		mutex_unlock(&aid->lock);
		ret = eSIR_FAILURE;
	} else {
		mutex_lock(&aid->lock);
		*peer_idx = aid->aid;
		aid->valid = false;
		mutex_unlock(&aid->lock);
		// add current sta num
		session->gLimNumOfCurrentSTAs++;
		ret = eSIR_SUCCESS;
	}

	return ret;
}
