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

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


/*
 * This file limApi.cc contains the functions that are
 * exported by LIM to other modules.
 *
 * Author:        Chandra Modumudi
 * Date:          02/11/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */
#include "palTypes.h"
#include "wni_cfg.h"
#include "wniApi.h"
#include "sirCommon.h"
#include "sirDebug.h"
#include "cfgApi.h"

#include "schApi.h"
#include "utilsApi.h"
#include "limApi.h"
#include "limGlobal.h"
#include "limTypes.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limPropExtsUtils.h"
#include "limSerDesUtils.h"
#include "limIbssPeerMgmt.h"
#include "limAdmitControl.h"
#include "pmmApi.h"
#include "logDump.h"
#include "limSendSmeRspMessages.h"
#include "wmmApsd.h"
#include "limTrace.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include "limFTDefs.h"
#endif
#include "limSession.h"
#include "wlan_qct_wda.h"

#if defined WLAN_FEATURE_VOWIFI
#include "rrmApi.h"
#endif

#include <limFT.h>
#include "vos_types.h"
#include "vos_packet.h"
#include "vos_utils.h"
#include "wlan_qct_tl.h"
#include "sysStartup.h"
#include "pktlog_ac_fmt.h"

static tp_pe_packetdump_cb gpe_packetdump_cb;

static void __limInitScanVars(tpAniSirGlobal pMac)
{
    pMac->lim.gLimUseScanModeForLearnMode = 1;

    pMac->lim.gLimSystemInScanLearnMode = 0;

    // Scan related globals on STA
    pMac->lim.gLimReturnAfterFirstMatch = 0;
    pMac->lim.gLim24Band11dScanDone = 0;
    pMac->lim.gLim50Band11dScanDone = 0;
    pMac->lim.gLimReturnUniqueResults = 0;

    // Background Scan related globals on STA
    pMac->lim.gLimNumOfBackgroundScanSuccess = 0;
    pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0;
    pMac->lim.gLimNumOfForcedBkgndScan = 0;
    pMac->lim.gLimBackgroundScanDisable = false;      //based on BG timer
    pMac->lim.gLimForceBackgroundScanDisable = false; //debug control flag
    pMac->lim.gLimBackgroundScanTerminate = TRUE;    //controlled by SME
    pMac->lim.gLimReportBackgroundScanResults = FALSE;    //controlled by SME

    pMac->lim.gLimCurrentScanChannelId = 0;
    pMac->lim.gpLimMlmScanReq = NULL;
    pMac->lim.gDeferMsgTypeForNOA = 0;
    pMac->lim.gpDefdSmeMsgForNOA = NULL;
    pMac->lim.gLimMlmScanResultLength = 0;
    pMac->lim.gLimSmeScanResultLength = 0;

    vos_mem_set(pMac->lim.gLimCachedScanHashTable,
                sizeof(pMac->lim.gLimCachedScanHashTable), 0);

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD

    pMac->lim.gLimMlmLfrScanResultLength = 0;
    pMac->lim.gLimSmeLfrScanResultLength = 0;

    vos_mem_set(pMac->lim.gLimCachedLfrScanHashTable,
                sizeof(pMac->lim.gLimCachedLfrScanHashTable), 0);
#endif
    pMac->lim.gLimBackgroundScanChannelId = 0;
    pMac->lim.gLimBackgroundScanStarted = 0;
    pMac->lim.gLimRestoreCBNumScanInterval = LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT;
    pMac->lim.gLimRestoreCBCount = 0;
    vos_mem_set(pMac->lim.gLimLegacyBssidList,
                sizeof(pMac->lim.gLimLegacyBssidList), 0);

    /* Fill in default values */
    pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = 0;

    // abort scan is used to abort an on-going scan
    pMac->lim.abortScan = 0;
    vos_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0);
    vos_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);

//WLAN_SUSPEND_LINK Related
    pMac->lim.gpLimSuspendCallback = NULL;
    pMac->lim.gpLimResumeCallback = NULL;
//end WLAN_SUSPEND_LINK Related
}


static void __limInitBssVars(tpAniSirGlobal pMac)
{
    vos_mem_set((void*)pMac->lim.gpSession,
                 sizeof(*pMac->lim.gpSession)*pMac->lim.maxBssId, 0);

    /* This is for testing purposes only, be default should always be off */
    pMac->lim.gLimForceNoPropIE = 0;
    pMac->lim.gpLimMlmSetKeysReq = NULL;
    pMac->lim.gpLimMlmRemoveKeyReq = NULL;
}


static void __limInitStatsVars(tpAniSirGlobal pMac)
{
    pMac->lim.gLimNumBeaconsRcvd = 0;
    pMac->lim.gLimNumBeaconsIgnored = 0;

    pMac->lim.gLimNumDeferredMsgs = 0;

    /// Variable to keep track of number of currently associated STAs
    pMac->lim.gLimNumOfAniSTAs = 0;      // count of ANI peers

    // Heart-Beat interval value
    pMac->lim.gLimHeartBeatCount = 0;

    vos_mem_zero(pMac->lim.gLimHeartBeatApMac[0],
            sizeof(tSirMacAddr));
    vos_mem_zero(pMac->lim.gLimHeartBeatApMac[1],
            sizeof(tSirMacAddr));
    pMac->lim.gLimHeartBeatApMacIndex = 0;

    // Statistics to keep track of no. beacons rcvd in heart beat interval
    vos_mem_set(pMac->lim.gLimHeartBeatBeaconStats,
                sizeof(pMac->lim.gLimHeartBeatBeaconStats), 0);

#ifdef WLAN_DEBUG
    // Debug counters
    pMac->lim.numTot = 0;
    pMac->lim.numBbt = 0;
    pMac->lim.numProtErr = 0;
    pMac->lim.numLearn = 0;
    pMac->lim.numLearnIgnore = 0;
    pMac->lim.numSme = 0;
    vos_mem_set(pMac->lim.numMAC, sizeof(pMac->lim.numMAC), 0);
    pMac->lim.gLimNumAssocReqDropInvldState = 0;
    pMac->lim.gLimNumAssocReqDropACRejectTS = 0;
    pMac->lim.gLimNumAssocReqDropACRejectSta = 0;
    pMac->lim.gLimNumReassocReqDropInvldState = 0;
    pMac->lim.gLimNumHashMissIgnored = 0;
    pMac->lim.gLimUnexpBcnCnt = 0;
    pMac->lim.gLimBcnSSIDMismatchCnt = 0;
    pMac->lim.gLimNumLinkEsts = 0;
    pMac->lim.gLimNumRxCleanup = 0;
    pMac->lim.gLim11bStaAssocRejectCount = 0;
#endif
}

static void __limInitStates(tpAniSirGlobal pMac)
{
    // Counts Heartbeat failures
    pMac->lim.gLimHBfailureCntInLinkEstState = 0;
    pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0;
    pMac->lim.gLimHBfailureCntInOtherStates = 0;
    pMac->lim.gLimRspReqd = 0;
    pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE;

    /// MLM State visible across all Sirius modules
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, eLIM_MLM_IDLE_STATE));
    pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;

    /// Previous MLM State
    pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE;

    // LIM to HAL SCAN Management Message Interface states
    pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;

    /**
     * Initialize state to eLIM_SME_OFFLINE_STATE
     */
    pMac->lim.gLimSmeState     = eLIM_SME_OFFLINE_STATE;

    /**
     * By default assume 'unknown' role. This will be updated
     * when SME_START_BSS_REQ is received.
     */

    vos_mem_set(&pMac->lim.gLimOverlap11gParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set(&pMac->lim.gLimOverlap11aParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set(&pMac->lim.gLimOverlapHt20Params, sizeof(tLimProtStaParams), 0);
    vos_mem_set(&pMac->lim.gLimOverlapNonGfParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set(&pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams), 0);
    vos_mem_set(&pMac->lim.gLimNoShortSlotParams, sizeof(tLimNoShortSlotParams), 0);

    pMac->lim.gLimPhyMode = 0;
    pMac->lim.scanStartTime = 0;    // used to measure scan time

    vos_mem_set(pMac->lim.gLimMyMacAddr, sizeof(pMac->lim.gLimMyMacAddr), 0);
    pMac->lim.ackPolicy = 0;

    pMac->lim.gLimProbeRespDisableFlag = 0; // control over probe response
}

#ifdef FEATURE_OEM_DATA_SUPPORT
static void lim_set_oem_data_req(tpAniSirGlobal mac)
{
	mac->lim.gpLimMlmOemDataReq = NULL;
}
#else
static inline void lim_set_oem_data_req(tpAniSirGlobal mac)
{
}
#endif

static void __limInitVars(tpAniSirGlobal pMac)
{
    // Place holder for Measurement Req/Rsp/Ind related info

    // Deferred Queue Paramters
    vos_mem_set(&pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq), 0);

    // addts request if any - only one can be outstanding at any time
    vos_mem_set(&pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq) , 0);
    pMac->lim.gLimAddtsSent = 0;
    pMac->lim.gLimAddtsRspTimerCount = 0;

    //protection related config cache
    vos_mem_set(&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0);
    pMac->lim.gLimProtectionControl = 0;
    vos_mem_set(&pMac->lim.gLimAlternateRadio, sizeof(tSirAlternateRadioInfo), 0);
    SET_LIM_PROCESS_DEFD_MESGS(pMac, true);

    // WMM Related Flag
    pMac->lim.gUapsdEnable = 0;
    pMac->lim.gUapsdPerAcBitmask = 0;
    pMac->lim.gUapsdPerAcTriggerEnableMask = 0;
    pMac->lim.gUapsdPerAcDeliveryEnableMask = 0;

    // QoS-AC Downgrade: Initially, no AC is admitted
    pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0;
    pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0;

    //dialogue token List head/tail for Action frames request sent.
    pMac->lim.pDialogueTokenHead = NULL;
    pMac->lim.pDialogueTokenTail = NULL;

    vos_mem_set(&pMac->lim.tspecInfo,
                sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX, 0);

    // admission control policy information
    vos_mem_set(&pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo), 0);

    pMac->lim.gLastBeaconDtimCount = 0;
    pMac->lim.gLastBeaconDtimPeriod = 0;

    //Scan in Power Save Flag
    pMac->lim.gScanInPowersave = 0;
    pMac->lim.probeCounter = 0;
    pMac->lim.maxProbe = 0;

#ifdef SAP_AUTH_OFFLOAD
    /* Init SAP deffered Q Head */
    lim_init_sap_deferred_msg_queue(pMac);
#endif
    lim_set_oem_data_req(pMac);
}

static void __limInitAssocVars(tpAniSirGlobal pMac)
{
    tANI_U32 val;
    if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS)
    {
        limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" ));
    }
    pMac->lim.gLimAssocStaLimit = val;
    pMac->lim.gLimIbssStaLimit = val;
    if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT_AP, &val) != eSIR_SUCCESS)
        limLog( pMac, LOGP, FL( "cfg get assoc sta of AP limit failed" ));

    pMac->lim.glim_assoc_sta_limit_ap = val;

    if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT_GO, &val) != eSIR_SUCCESS)
        limLog( pMac, LOGP, FL( "cfg get assoc sta of GO limit failed" ));

    pMac->lim.glim_assoc_sta_limit_go = val;

    limLog(pMac, LOG1, FL("max_peer:%d ap_peer:%d go_peer:%d"),
           pMac->lim.gLimAssocStaLimit, pMac->lim.glim_assoc_sta_limit_ap,
           pMac->lim.glim_assoc_sta_limit_go);
    // Place holder for current authentication request
    // being handled
    pMac->lim.gpLimMlmAuthReq = NULL;

    /// MAC level Pre-authentication related globals
    pMac->lim.gLimPreAuthChannelNumber = 0;
    pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM;
    vos_mem_set(&pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr), 0);
    pMac->lim.gLimNumPreAuthContexts = 0;
    vos_mem_set(&pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable), 0);

    // Placed holder to deauth reason
    pMac->lim.gLimDeauthReasonCode = 0;

    // Place holder for Pre-authentication node list
    pMac->lim.pLimPreAuthList = NULL;

    //One cache for each overlap and associated case.
    vos_mem_set(pMac->lim.protStaOverlapCache,
                sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE, 0);
    vos_mem_set(pMac->lim.protStaCache,
                sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE, 0);

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
    pMac->lim.pSessionEntry = NULL;
    pMac->lim.reAssocRetryAttempt = 0;
#endif

}

static void __limInitHTVars(tpAniSirGlobal pMac)
{
    pMac->lim.htCapabilityPresentInBeacon = 0;
    pMac->lim.gHTGreenfield = 0;
    pMac->lim.gHTShortGI40Mhz = 0;
    pMac->lim.gHTShortGI20Mhz = 0;
    pMac->lim.gHTMaxAmsduLength = 0;
    pMac->lim.gHTDsssCckRate40MHzSupport = 0;
    pMac->lim.gHTPSMPSupport = 0;
    pMac->lim.gHTLsigTXOPProtection = 0;
    pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC;
    pMac->lim.gHTAMpduDensity = 0;

    pMac->lim.gMaxAmsduSizeEnabled = false;
    pMac->lim.gHTMaxRxAMpduFactor = 0;
    pMac->lim.gHTServiceIntervalGranularity = 0;
    pMac->lim.gHTControlledAccessOnly = 0;
    pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
    pMac->lim.gHTPCOActive = 0;

    pMac->lim.gHTPCOPhase = 0;
    pMac->lim.gHTSecondaryBeacon = 0;
    pMac->lim.gHTDualCTSProtection = 0;
    pMac->lim.gHTSTBCBasicMCS = 0;
    pMac->lim.gAddBA_Declined = 0;               // Flag to Decline the BAR if the particular bit (0-7) is being set
}

static tSirRetStatus __limInitConfig( tpAniSirGlobal pMac )
{
   tANI_U32 val1, val2, val3;
   tANI_U16 val16;
   tANI_U8 val8;
   tSirMacHTCapabilityInfo   *pHTCapabilityInfo;
   tSirMacHTInfoField1       *pHTInfoField1;
   tpSirPowerSaveCfg          pPowerSaveConfig;
   tSirMacHTParametersInfo   *pAmpduParamInfo;

   /* Read all the CFGs here that were updated before peStart is called */
   /* All these CFG READS/WRITES are only allowed in init, at start when there is no session
    * and they will be used throughout when there is no session
    */

   if(wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));)
      return eSIR_FAILURE;
   }

   if(wlan_cfgGetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve Channel Bonding CFG"));)
      return eSIR_FAILURE;
   }
   val16 = ( tANI_U16 ) val1;
   pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;

   pHTCapabilityInfo->supportedChannelWidthSet = val2 ?
     WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
   if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo)
      != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));)
      return eSIR_FAILURE;
   }

   if(wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT INFO Field1 CFG"));)
      return eSIR_FAILURE;
   }

   val8 = ( tANI_U8 ) val1;
   pHTInfoField1 = ( tSirMacHTInfoField1* ) &val8;
   pHTInfoField1->recommendedTxWidthSet =
     (tANI_U8)pHTCapabilityInfo->supportedChannelWidthSet;
   if(cfgSetInt(pMac, WNI_CFG_HT_INFO_FIELD1, *(tANI_U8*)pHTInfoField1)
      != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not update HT Info Field"));)
      return eSIR_FAILURE;
   }

   /* WNI_CFG_HEART_BEAT_THRESHOLD */

   if( wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) !=
       eSIR_SUCCESS )
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG"));)
      return eSIR_FAILURE;
   }
   if(!val1)
   {
      limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER);
      pMac->sys.gSysEnableLinkMonitorMode = 0;
   }
   else
   {
      //No need to activate the timer during init time.
      pMac->sys.gSysEnableLinkMonitorMode = 1;
   }

   /* WNI_CFG_SHORT_GI_20MHZ */

   if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));)
      return eSIR_FAILURE;
   }
   if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG"));)
      return eSIR_FAILURE;
   }
   if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val3) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG"));)
      return eSIR_FAILURE;
   }

   val16 = ( tANI_U16 ) val1;
   pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
   pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2;
   pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val3;

   if(cfgSetInt(pMac,  WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) !=
      eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));)
      return eSIR_FAILURE;
   }

   /* WNI_CFG_MAX_RX_AMPDU_FACTOR */

   if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));)
      return eSIR_FAILURE;
   }
   if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG"));)
   }
   if (wlan_cfgGetInt(pMac, WNI_CFG_MPDU_DENSITY, &val3) != eSIR_SUCCESS) {
       limLog(pMac, LOGE, FL("could not retrieve MPDU Density CFG"));
       return eSIR_FAILURE;
   }

   val16 = ( tANI_U16 ) val1;
   pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16;
   pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2;
   pAmpduParamInfo->mpduDensity = (uint8_t)val3;

   if(cfgSetInt(pMac,  WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) !=
      eSIR_SUCCESS)
   {
     limLog(pMac, LOGE, FL("cfg get short preamble failed"));
     return eSIR_FAILURE;
   }

   /* WNI_CFG_SHORT_PREAMBLE - this one is not updated in
      limHandleCFGparamUpdate do we want to update this? */
   if(wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val1) != eSIR_SUCCESS)
   {
      limLog(pMac, LOGP, FL("cfg get short preamble failed"));
      return eSIR_FAILURE;
   }

   /* WNI_CFG_MAX_PS_POLL */

   if (!pMac->psOffloadEnabled)
   {
       /* Allocate and fill in power save configuration. */
       pPowerSaveConfig = vos_mem_malloc(sizeof(tSirPowerSaveCfg));
       if (NULL == pPowerSaveConfig)
       {
           PELOGE(limLog(pMac, LOGE,
                         FL("LIM: Cannot allocate memory for power save configuration"));)
           return eSIR_FAILURE;
       }

       /* This context should be valid if power-save configuration message has
        * been already dispatched during initialization process. Re-using the
        * present configuration mask
        */
       vos_mem_copy(pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg,
                   sizeof(tSirPowerSaveCfg));

       /* Note: it is okay to do this since DAL/HAL is alrady started */
       if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS)
       {
              PELOGE(limLog(pMac, LOGE,
                            FL("LIM: pmmSendPowerSaveCfg() failed "));)
              return eSIR_FAILURE;
       }
   }

   /* WNI_CFG_BG_SCAN_CHANNEL_LIST_CHANNEL_LIST */

   PELOG1(limLog(pMac, LOG1,
      FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel"));)
   pMac->lim.gLimBackgroundScanChannelId = 0;

   /* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */

   /* This was initially done after resume notification from HAL. Now, DAL is
      started before PE so this can be done here */
   handleHTCapabilityandHTInfo(pMac, NULL);
   if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
                       (tANI_U32 *) &pMac->lim.disableLDPCWithTxbfAP))
   {
      limLog(pMac, LOGP, FL("cfg get disableLDPCWithTxbfAP failed"));
      return eSIR_FAILURE;
   }
#ifdef FEATURE_WLAN_TDLS
   if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_BUF_STA_ENABLED,
                       (tANI_U32 *) &pMac->lim.gLimTDLSBufStaEnabled))
   {
       limLog(pMac, LOGP, FL("cfg get LimTDLSBufStaEnabled failed"));
       return eSIR_FAILURE;
   }
   if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK,
                       (tANI_U32 *) &pMac->lim.gLimTDLSUapsdMask))
   {
       limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed"));
       return eSIR_FAILURE;
   }
   if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED,
                       (tANI_U32 *) &pMac->lim.gLimTDLSOffChannelEnabled))
   {
       limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed"));
       return eSIR_FAILURE;
   }

   if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_WMM_MODE_ENABLED,
                       (tANI_U32 *) &pMac->lim.gLimTDLSWmmMode))
   {
       limLog(pMac, LOGP, FL("cfg get LimTDLSWmmMode failed"));
       return eSIR_FAILURE;
   }
#endif
   return eSIR_SUCCESS;
}

/*
   limStart
   This function is to replace the __limProcessSmeStartReq since there is no
   eWNI_SME_START_REQ post to PE.
*/
tSirRetStatus limStart(tpAniSirGlobal pMac)
{
   tSirResultCodes retCode = eSIR_SUCCESS;

   PELOG1(limLog(pMac, LOG1, FL(" enter"));)

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

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

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

      // Initialize MLM state machine
      if (eSIR_SUCCESS != limInitMlm(pMac)) {
          limLog(pMac, LOGE, FL("Init MLM failed."));
          return eSIR_FAILURE;
      }

      // By default return unique scan results
      pMac->lim.gLimReturnUniqueResults = true;
      pMac->lim.gLimSmeScanResultLength = 0;
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
      pMac->lim.gLimSmeLfrScanResultLength = 0;
#endif
   }
   else
   {
      /**
      * Should not have received eWNI_SME_START_REQ in states
      * other than OFFLINE. Return response to host and
      * log error
      */
      limLog(pMac, LOGE, FL("Invalid SME state %X"),pMac->lim.gLimSmeState );
      retCode = eSIR_FAILURE;
   }

   return retCode;
}

/**
 * limInitialize()
 *
 *FUNCTION:
 * This function is called from LIM thread entry function.
 * LIM related global data structures are initialized in this function.
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac - Pointer to global MAC structure
 * @return None
 */

tSirRetStatus
limInitialize(tpAniSirGlobal pMac)
{
    tSirRetStatus status = eSIR_SUCCESS;

    __limInitAssocVars(pMac);
    __limInitVars(pMac);
    __limInitStates(pMac);
    __limInitStatsVars(pMac);
    __limInitBssVars(pMac);
    __limInitScanVars(pMac);
    __limInitHTVars(pMac);

    status = limStart(pMac);
    if(eSIR_SUCCESS != status)
    {
        return status;
    }

    // Initializations for maintaining peers in IBSS
    limIbssInit(pMac);

    if(!pMac->psOffloadEnabled)
       pmmInitialize(pMac);

#if defined WLAN_FEATURE_VOWIFI
    rrmInitialize(pMac);
#endif

    vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue);

    //Initialize the configurations needed by PE
    if( eSIR_FAILURE == __limInitConfig(pMac))
    {
       //We need to undo everything in limStart
       limCleanupMlm(pMac);
       return eSIR_FAILURE;
    }

   //initialize the TSPEC admission control table.
   //Note that this was initially done after resume notification from HAL.
   //Now, DAL is started before PE so this can be done here
   limAdmitControlInit(pMac);
   limRegisterHalIndCallBack(pMac);

   return status;

} /*** end limInitialize() ***/



/**
 * limCleanup()
 *
 *FUNCTION:
 * This function is called upon reset or persona change
 * to cleanup LIM state
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac - Pointer to Global MAC structure
 * @return None
 */

void
limCleanup(tpAniSirGlobal pMac)
{
//Before destroying the list making sure all the nodes have been deleted.
//Which should be the normal case, but a memory leak has been reported.
    uint8_t i;

    tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL;

    while(vos_list_remove_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
            (vos_list_node_t**)&pLimMgmtRegistration) == VOS_STATUS_SUCCESS)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                FL("Fixing leak! Deallocating pLimMgmtRegistration node"));

        vos_mem_free(pLimMgmtRegistration);
    }

    vos_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue);

    limCleanupMlm(pMac);
    limCleanupLmm(pMac);

    // free up preAuth table
    if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL)
    {
        for (i = 0; i < pMac->lim.gLimPreAuthTimerTable.numEntry; i++)
            vos_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable[i]);
        vos_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
        pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
        pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
    }

    if(NULL != pMac->lim.pDialogueTokenHead)
    {
        limDeleteDialogueTokenList(pMac);
    }

    if(NULL != pMac->lim.pDialogueTokenTail)
    {
        vos_mem_free(pMac->lim.pDialogueTokenTail);
        pMac->lim.pDialogueTokenTail = NULL;
    }

    if (pMac->lim.gpLimMlmSetKeysReq != NULL)
    {
        vos_mem_free(pMac->lim.gpLimMlmSetKeysReq);
        pMac->lim.gpLimMlmSetKeysReq = NULL;
    }

    if (pMac->lim.gpLimMlmAuthReq != NULL)
    {
        vos_mem_free(pMac->lim.gpLimMlmAuthReq);
        pMac->lim.gpLimMlmAuthReq = NULL;
    }

    if (pMac->lim.gpLimMlmRemoveKeyReq != NULL)
    {
        vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq);
        pMac->lim.gpLimMlmRemoveKeyReq = NULL;
    }

    if (pMac->lim.gpDefdSmeMsgForNOA != NULL)
    {
        vos_mem_free(pMac->lim.gpDefdSmeMsgForNOA);
        pMac->lim.gpDefdSmeMsgForNOA = NULL;
    }

    if (pMac->lim.gpLimMlmScanReq != NULL)
    {
        vos_mem_free(pMac->lim.gpLimMlmScanReq);
        pMac->lim.gpLimMlmScanReq = NULL;
    }

    // Now, finally reset the deferred message queue pointers
    limResetDeferredMsgQ(pMac);

#if defined WLAN_FEATURE_VOWIFI
    rrmCleanup(pMac);
#endif

#if defined WLAN_FEATURE_VOWIFI_11R
    limFTCleanupAllFTSessions(pMac);
#endif

#ifdef SAP_AUTH_OFFLOAD
    lim_cleanup_sap_deferred_msg_queue(pMac);
#endif

} /*** end limCleanup() ***/

/**
 * lim_state_info_dump() - print state information of lim layer
 * @buf: buffer pointer
 * @size: size of buffer to be filled
 *
 * This function is used to print state information of lim layer
 *
 * Return: None
 */
static void lim_state_info_dump(char **buf_ptr, uint16_t *size)
{
	tHalHandle hal;
	tpAniSirGlobal mac;
	v_CONTEXT_t vos_ctx_ptr;
	uint16_t len = 0;
	char *buf = *buf_ptr;

	/* get the global voss context */
	vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL);

	if (NULL == vos_ctx_ptr) {
		VOS_ASSERT(0);
		return;
	}

	hal = vos_get_context(VOS_MODULE_ID_PE, vos_ctx_ptr);
	if (NULL == hal) {
		VOS_ASSERT(0);
		return;
	}

	mac = PMAC_STRUCT(hal);

	limLog(mac, LOG1, FL("size of buffer: %d"), *size);

	len += vos_scnprintf(buf + len, *size - len,
		"\n SmeState: %d", mac->lim.gLimSmeState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n PrevSmeState: %d", mac->lim.gLimPrevSmeState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n MlmState: %d", mac->lim.gLimMlmState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n PrevMlmState: %d", mac->lim.gLimPrevMlmState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n SystemInScanLearnMode: %d",
		mac->lim.gLimSystemInScanLearnMode);
	len += vos_scnprintf(buf + len, *size - len,
		"\n ProcessDefdMsgs: %d", mac->lim.gLimProcessDefdMsgs);
	len += vos_scnprintf(buf + len, *size - len,
		"\n gLimHalScanState: %d", mac->lim.gLimHalScanState);

	*size -= len;
	*buf_ptr += len;
}

/**
 * lim_register_debug_callback() - registration function for lim layer
 * to print lim state information
 *
 * Return: None
 */
static void lim_register_debug_callback(void)
{
	vos_register_debug_callback(VOS_MODULE_ID_PE, &lim_state_info_dump);
}

/** -------------------------------------------------------------
\fn peOpen
\brief will be called in Open sequence from macOpen
\param   tpAniSirGlobal pMac
\param   tHalOpenParameters *pHalOpenParam
\return  tSirRetStatus
  -------------------------------------------------------------*/

tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam)
{
    tSirRetStatus status = eSIR_SUCCESS;

    if (eDRIVER_TYPE_MFG == pMacOpenParam->driverType)
       return eSIR_SUCCESS;

    pMac->lim.maxBssId = pMacOpenParam->maxBssId;
    pMac->lim.maxStation = pMacOpenParam->maxStation;

    if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0)) {
         PELOGE(limLog(pMac, LOGE,
                       FL("max number of Bssid or Stations cannot be zero!"));)
         return eSIR_FAILURE;
    }

    pMac->lim.limTimers.gpLimCnfWaitTimer = vos_mem_malloc(sizeof(TX_TIMER) *
                                               (pMac->lim.maxStation + 1));
    if (NULL == pMac->lim.limTimers.gpLimCnfWaitTimer) {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));)
        return eSIR_FAILURE;
    }

    pMac->lim.gpSession = vos_mem_malloc(sizeof(tPESession)*
                                          pMac->lim.maxBssId);
    if (NULL == pMac->lim.gpSession) {
        limLog(pMac, LOGE, FL("memory allocate failed!"));
        status = eSIR_FAILURE;
        goto pe_open_psession_fail;
    }

    vos_mem_set(pMac->lim.gpSession, sizeof(tPESession) *
                                     pMac->lim.maxBssId, 0);

    pMac->pmm.gPmmTim.pTim = vos_mem_malloc(sizeof(tANI_U8) *
                                            pMac->lim.maxStation);
    if (NULL == pMac->pmm.gPmmTim.pTim) {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pTim!"));)
        status = eSIR_FAILURE;
        goto pe_open_ptim_fail;
    }
    vos_mem_set(pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8) *
                                        pMac->lim.maxStation, 0);

    pMac->lim.mgmtFrameSessionId = 0xff;
    pMac->lim.tdls_frm_session_id = 0xff;
    pMac->lim.deferredMsgCnt = 0;

    if (!VOS_IS_STATUS_SUCCESS(vos_lock_init(&pMac->lim.lkPeGlobalLock))) {
        PELOGE(limLog(pMac, LOGE, FL("pe lock init failed!"));)
        status = eSIR_FAILURE;
        goto pe_open_lock_fail;
    }
    pMac->lim.deauthMsgCnt = 0;
    pMac->lim.retry_packet_cnt = 0;
    pMac->lim.gLimIbssRetryCnt = 0;

    /*
     * peOpen is successful by now, so it is right time to initialize
     * MTRACE for PE module. if LIM_TRACE_RECORD is not defined in build file
     * then nothing will be logged for PE module.
     */
#ifdef LIM_TRACE_RECORD
    MTRACE(limTraceInit(pMac));
#endif
    lim_register_debug_callback();

    return status; /* status here will be eSIR_SUCCESS */

pe_open_lock_fail:
    vos_mem_free(pMac->pmm.gPmmTim.pTim);
    pMac->pmm.gPmmTim.pTim = NULL;
pe_open_ptim_fail:
    vos_mem_free(pMac->lim.gpSession);
    pMac->lim.gpSession = NULL;
pe_open_psession_fail:
    vos_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer);
    pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;

    return status;
}

#ifdef FEATURE_OEM_DATA_SUPPORT
static void lim_free_oem_data_req(tpAniSirGlobal mac)
{
	if (mac->lim.gpLimMlmOemDataReq) {
		if (mac->lim.gpLimMlmOemDataReq->data) {
			vos_mem_free(mac->lim.gpLimMlmOemDataReq->data);
			mac->lim.gpLimMlmOemDataReq->data = NULL;
		}
		vos_mem_free(mac->lim.gpLimMlmOemDataReq);
		mac->lim.gpLimMlmOemDataReq = NULL;
	}
}
#else
static inline void lim_free_oem_data_req(tpAniSirGlobal mac)
{
}
#endif

/** -------------------------------------------------------------
\fn peClose
\brief will be called in close sequence from macClose
\param   tpAniSirGlobal pMac
\return  tSirRetStatus
  -------------------------------------------------------------*/

tSirRetStatus peClose(tpAniSirGlobal pMac)
{
    tANI_U8 i;

    if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG)
        return eSIR_SUCCESS;

    for(i =0; i < pMac->lim.maxBssId; i++)
    {
        if(pMac->lim.gpSession[i].valid == TRUE)
        {
            peDeleteSession(pMac,&pMac->lim.gpSession[i]);
        }
    }
    vos_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer);
    pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
    lim_free_oem_data_req(pMac);
    vos_mem_free(pMac->lim.gpSession);
    pMac->lim.gpSession = NULL;
    vos_mem_free(pMac->pmm.gPmmTim.pTim);
    pMac->pmm.gPmmTim.pTim = NULL;
    if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pMac->lim.lkPeGlobalLock ) ) )
    {
        return eSIR_FAILURE;
    }
    return eSIR_SUCCESS;
}

/** -------------------------------------------------------------
\fn peStart
\brief will be called in start sequence from macStart
\param   tpAniSirGlobal pMac
\return none
  -------------------------------------------------------------*/

tSirRetStatus peStart(tpAniSirGlobal pMac)
{
    tSirRetStatus status = eSIR_SUCCESS;

    status = limInitialize(pMac);
#if defined(ANI_LOGDUMP)
    limDumpInit(pMac);
#endif //#if defined(ANI_LOGDUMP)

    return status;
}

/** -------------------------------------------------------------
\fn peStop
\brief will be called in stop sequence from macStop
\param   tpAniSirGlobal pMac
\return none
  -------------------------------------------------------------*/

void peStop(tpAniSirGlobal pMac)
{
    limCleanup(pMac);
    SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE);
    return;
}

/** -------------------------------------------------------------
\fn peFreeMsg
\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs)
\      to free a given PE message on the TX and MC thread.
\      This happens when there are messages pending in the PE
\      queue when system is being stopped and reset.
\param   tpAniSirGlobal pMac
\param   tSirMsgQ       pMsg
\return none
-----------------------------------------------------------------*/
v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg)
{
    if (pMsg != NULL)
    {
        if (NULL != pMsg->bodyptr)
        {
            if (SIR_BB_XPORT_MGMT_MSG == pMsg->type)
            {
                vos_pkt_return_packet((vos_pkt_t *)pMsg->bodyptr);
            }
            else
            {
                vos_mem_free((v_VOID_t*)pMsg->bodyptr);
            }
        }
        pMsg->bodyptr = 0;
        pMsg->bodyval = 0;
        pMsg->type = 0;
    }
    return;
}


/**
 * The function checks if a particular timer should be allowed
 * into LIM while device is sleeping
 */
tANI_U8 limIsTimerAllowedInPowerSaveState(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
{
    tANI_U8 retStatus = TRUE;

    if(!limIsSystemInActiveState(pMac))
    {
        switch(pMsg->type)
        {
            /* Don't allow following timer messages if in sleep */
            case SIR_LIM_MIN_CHANNEL_TIMEOUT:
            case SIR_LIM_MAX_CHANNEL_TIMEOUT:
            case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
                retStatus = FALSE;
                break;
            /* Safe to allow as of today, this triggers background scan
             * which will not be started if the device is in power-save mode
             * might need to block in the future if we decide to implement
             * spectrum management
             */
            case SIR_LIM_QUIET_TIMEOUT:

            /* Safe to allow as of today, this triggers background scan
             * which will not be started if the device is in power-save mode
             * might need to block in the future if we decide to implement
             * spectrum management
             */
            case SIR_LIM_QUIET_BSS_TIMEOUT:

            /* Safe to allow this timermessage, triggers background scan
             * which is blocked in sleep mode
             */
            case SIR_LIM_CHANNEL_SCAN_TIMEOUT:

            /* Safe to allow this timer, since, while in IMPS this timer will not
             * be started. In case of BMPS sleep, SoftMAC handles the heart-beat
             * when heart-beat control is handled back to PE, device would have
             * already woken-up due to EXIT_BMPS_IND mesage from SoftMAC
             */
            case SIR_LIM_HEART_BEAT_TIMEOUT:
            case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:

            /* Safe to allow, PE is not handling this message as of now. May need
             * to block it, basically, free the buffer and restart the timer
             */
            case SIR_LIM_REASSOC_FAIL_TIMEOUT:
            case SIR_LIM_JOIN_FAIL_TIMEOUT:
            case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
            case SIR_LIM_ASSOC_FAIL_TIMEOUT:
            case SIR_LIM_AUTH_FAIL_TIMEOUT:
            case SIR_LIM_ADDTS_RSP_TIMEOUT:
            case SIR_LIM_AUTH_RETRY_TIMEOUT:
                retStatus = TRUE;
                break;

            /* by default allow rest of messages */
            default:
                retStatus = TRUE;
                break;


        }
    }

    return retStatus;

}



/**
 * limPostMsgApi()
 *
 *FUNCTION:
 * This function is called from other thread while posting a
 * message to LIM message Queue gSirLimMsgQ.
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac - Pointer to Global MAC structure
 * @param  pMsg - Pointer to the message structure
 * @return None
 */

tANI_U32
limPostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
{
    return  vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg);


} /*** end limPostMsgApi() ***/

/**
 * lim_post_msg_high_pri() - posts high priority pe message
 * @mac: mac context
 * @msg: message to be posted
 *
 * This function is used to post high priority pe message
 *
 * Return: returns value returned by vos_mq_post_message_by_priority
 */
uint32_t
lim_post_msg_high_pri(tpAniSirGlobal mac, tSirMsgQ *msg)
{
	return vos_mq_post_message_by_priority(VOS_MQ_ID_PE, (vos_msg_t *)msg,
					       HIGH_PRIORITY);
}

/*--------------------------------------------------------------------------

  \brief pePostMsgApi() - A wrapper function to post message to Voss msg queues

  This function can be called by legacy code to post message to voss queues OR
  legacy code may keep on invoking 'limPostMsgApi' to post the message to voss queue
  for dispatching it later.

  \param pMac - Pointer to Global MAC structure
  \param pMsg - Pointer to the message structure

  \return  tANI_U32 - TX_SUCCESS for success.

  --------------------------------------------------------------------------*/

tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
{
   return (tSirRetStatus)limPostMsgApi(pMac, pMsg);
}

/*--------------------------------------------------------------------------

  \brief peProcessMessages() - Message Processor for PE

  Voss calls this function to dispatch the message to PE

  \param pMac - Pointer to Global MAC structure
  \param pMsg - Pointer to the message structure

  \return  tANI_U32 - TX_SUCCESS for success.

  --------------------------------------------------------------------------*/

tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg)
{
   if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG) {
      return eSIR_SUCCESS;
   }
   /**
    * If the Message to be handled is for CFG Module call the CFG Msg Handler
    * and for all the other cases post it to LIM
    */
    if ( SIR_CFG_PARAM_UPDATE_IND != pMsg->type && IS_CFG_MSG(pMsg->type))
        cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr);
    else
        limMessageProcessor(pMac, pMsg);
    return eSIR_SUCCESS;
}



// ---------------------------------------------------------------------------
/**
 * peHandleMgmtFrame
 *
 * FUNCTION:
 *    Process the Management frames from TL
 *
 * LOGIC:
 *
 * ASSUMPTIONS: TL sends the packet along with the VOS GlobalContext
 *
 * NOTE:
 *
 * @param pvosGCtx  Global Vos Context
 * @param vossBuff  Packet
 * @return None
 */

VOS_STATUS peHandleMgmtFrame( v_PVOID_t pvosGCtx, v_PVOID_t vosBuff)
{
    tpAniSirGlobal  pMac;
    tpSirMacMgmtHdr mHdr;
    tSirMsgQ        msg;
    vos_pkt_t      *pVosPkt;
    VOS_STATUS      vosStatus;
    v_U8_t         *pRxPacketInfo;

    pVosPkt = (vos_pkt_t *)vosBuff;
    if (NULL == pVosPkt)
    {
        return VOS_STATUS_E_FAILURE;
    }

    pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, pvosGCtx);
    if (NULL == pMac)
    {
        // cannot log a failure without a valid pMac
        vos_pkt_return_packet(pVosPkt);
        pVosPkt = NULL;
        return VOS_STATUS_E_FAILURE;
    }

    vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (void *)&pRxPacketInfo, VOS_FALSE );

    if(!VOS_IS_STATUS_SUCCESS(vosStatus))
    {
        vos_pkt_return_packet(pVosPkt);
        pVosPkt = NULL;
        return VOS_STATUS_E_FAILURE;
    }


    //
    //  The MPDU header is now present at a certain "offset" in
    // the BD and is specified in the BD itself
    //

    mHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
    if(mHdr->fc.type == SIR_MAC_MGMT_FRAME) {
        limLog(pMac, LOG2,
              FL("Type: %d Subtype: %d from: " MAC_ADDRESS_STR " with Seq no %d"),
              mHdr->fc.type, mHdr->fc.subType, MAC_ADDR_ARRAY(mHdr->sa),
              ((mHdr->seqControl.seqNumHi << 4) |
              (mHdr->seqControl.seqNumLo)));

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
       if (WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))
           limLog(pMac, LOG1, FL("roamCandidateInd %d"),
                  WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo));

       if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))
           limLog(pMac, LOG1, FL("offloadScanLearn %d"),
                  WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo));
#endif

    if ((mHdr->fc.subType != SIR_MAC_MGMT_BEACON) && gpe_packetdump_cb)
        gpe_packetdump_cb(pVosPkt->pkt_buf, VOS_STATUS_SUCCESS,
                                   pVosPkt->pkt_meta.sessionId, RX_MGMT_PKT);
    }


    // Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG
    msg.type = SIR_BB_XPORT_MGMT_MSG;
    msg.bodyptr = vosBuff;
    msg.bodyval = 0;

    if( eSIR_SUCCESS != sysBbtProcessMessageCore( pMac,
                                                  &msg,
                                                  mHdr->fc.type,
                                                  mHdr->fc.subType ))
    {
        vos_pkt_return_packet(pVosPkt);
        pVosPkt = NULL;
        return VOS_STATUS_E_FAILURE;
    }

    return  VOS_STATUS_SUCCESS;
}

// ---------------------------------------------------------------------------
/**
 * peRegisterTLHandle
 *
 * FUNCTION:
 *    Registers the Handler which, process the Management frames from TL
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @return None
 */

void peRegisterTLHandle(tpAniSirGlobal pMac)
{
    v_PVOID_t pvosGCTx;
    VOS_STATUS retStatus;

    pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);

    retStatus = WLANTL_RegisterMgmtFrmClient(pvosGCTx, peHandleMgmtFrame);

    if (retStatus != VOS_STATUS_SUCCESS)
        limLog( pMac, LOGP, FL("Registering the PE Handle with TL has failed bailing out..."));

}


/**
 * limIsSystemInScanState()
 *
 *FUNCTION:
 * This function is called by various MAC software modules to
 * determine if System is in Scan/Learn state
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac  - Pointer to Global MAC structure
 * @return true  - System is in Scan/Learn state
 *         false - System is NOT in Scan/Learn state
 */

tANI_U8
limIsSystemInScanState(tpAniSirGlobal pMac)
{
    switch (pMac->lim.gLimSmeState)
    {
        case eLIM_SME_CHANNEL_SCAN_STATE:
        case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
        case eLIM_SME_LINK_EST_WT_SCAN_STATE:
        case eLIM_SME_WT_SCAN_STATE:
            // System is in Learn mode
            return true;

        default:
            // System is NOT in Learn mode
            return false;
    }
} /*** end limIsSystemInScanState() ***/



/**
 * limIsSystemInActiveState()
 *
 *FUNCTION:
 * This function is called by various MAC software modules to
 * determine if System is in Active/Wakeup state
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac  - Pointer to Global MAC structure
 * @return true  - System is in Active state
 *         false - System is not in Active state
 */

tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac)
{
    switch (pMac->pmm.gPmmState)
    {
        case ePMM_STATE_BMPS_WAKEUP:
        case ePMM_STATE_IMPS_WAKEUP:
        case ePMM_STATE_READY:
            // System is in Active mode
            return true;
        default:
            return false;
          // System is NOT in Active mode
    }
}





/**
*\brief limReceivedHBHandler()
*
* This function is called by schBeaconProcess() upon
* receiving a Beacon on STA. This also gets called upon
* receiving Probe Response after heat beat failure is
* detected.
*
* param pMac - global mac structure
* param channel - channel number indicated in Beacon, Probe Response
* return - none
*/


void
limReceivedHBHandler(tpAniSirGlobal pMac, tANI_U8 channelId, tpPESession psessionEntry)
{
    if((channelId == 0 ) || (channelId == psessionEntry->currentOperChannel) )
    psessionEntry->LimRxedBeaconCntDuringHB++;

    if(pMac->psOffloadEnabled)
        psessionEntry->pmmOffloadInfo.bcnmiss = FALSE;
    else
        pMac->pmm.inMissedBeaconScenario = FALSE;
} /*** end limReceivedHBHandler() ***/



/** -------------------------------------------------------------
\fn limUpdateOverlapStaParam
\brief Updates overlap cache and param data structure
\param      tpAniSirGlobal    pMac
\param      tSirMacAddr bssId
\param      tpLimProtStaParams pStaParams
\return      None
  -------------------------------------------------------------*/
void
limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams)
{
    int i;
    if (!pStaParams->numSta)
    {
        vos_mem_copy(pMac->lim.protStaOverlapCache[0].addr,
                     bssId,
                     sizeof(tSirMacAddr));
        pMac->lim.protStaOverlapCache[0].active = true;

        pStaParams->numSta = 1;

        return;
    }

    for (i=0; i<LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
    {
        if (pMac->lim.protStaOverlapCache[i].active)
        {
            if (vos_mem_compare( pMac->lim.protStaOverlapCache[i].addr,
                          bssId,
                          sizeof(tSirMacAddr))) {
                return; }
        }
        else
            break;
    }

    if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE)
    {
       PELOG1(limLog(pMac, LOGW, FL("Overlap cache is full"));)
    }
    else
    {
        vos_mem_copy(pMac->lim.protStaOverlapCache[i].addr,
                     bssId,
                     sizeof(tSirMacAddr));
        pMac->lim.protStaOverlapCache[i].active = true;

        pStaParams->numSta++;
    }
}


/**
 * limIbssEncTypeMatched
 *
 *FUNCTION:
 * This function compares the encryption type of the peer with self
 * while operating in IBSS mode and detects mismatch.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pBeacon  - Parsed Beacon Frame structure
 * @param  pSession - Pointer to the PE session
 *
 * @return eSIR_TRUE if encryption type is matched; eSIR_FALSE otherwise
 */
static tAniBool limIbssEncTypeMatched(tpSchBeaconStruct  pBeacon,
                                      tpPESession        pSession)
{
    if (!pBeacon || !pSession)
        return eSIR_FALSE;

    /* Open case */
    if (pBeacon->capabilityInfo.privacy == 0
            && pSession->encryptType == eSIR_ED_NONE)
        return eSIR_TRUE;

    /* WEP case */
    if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 0
            && pBeacon->rsnPresent == 0
            && (pSession->encryptType == eSIR_ED_WEP40
                    || pSession->encryptType == eSIR_ED_WEP104))
        return eSIR_TRUE;

    /* WPA-None case */
    if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 1
            && pBeacon->rsnPresent == 0
            && ((pSession->encryptType == eSIR_ED_CCMP) ||
                (pSession->encryptType == eSIR_ED_TKIP)))
        return eSIR_TRUE;

    return eSIR_FALSE;
}


/**
 * limHandleIBSScoalescing()
 *
 *FUNCTION:
 * This function is called upon receiving Beacon/Probe Response
 * while operating in IBSS mode.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac    - Pointer to Global MAC structure
 * @param  pBeacon - Parsed Beacon Frame structure
 * @param  pRxPacketInfo - Pointer to RX packet info structure
 *
 * @return Status whether to process or ignore received Beacon Frame
 */

tSirRetStatus
limHandleIBSScoalescing(
    tpAniSirGlobal      pMac,
    tpSchBeaconStruct   pBeacon,
    tANI_U8            *pRxPacketInfo,tpPESession psessionEntry)
{
    tpSirMacMgmtHdr pHdr;
    tSirRetStatus   retCode;

    pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);

    /* Ignore the beacon when any of the conditions below is met:
       1. The beacon claims no IBSS network
       2. SSID in the beacon does not match SSID of self station
       3. Operational channel in the beacon does not match self station
       4. Encyption type in the beacon does not match with self station
    */
    if ( (!pBeacon->capabilityInfo.ibss) ||
         (limCmpSSid(pMac, &pBeacon->ssId,psessionEntry) != true) ||
         (psessionEntry->currentOperChannel != pBeacon->channelNumber) )
        retCode =  eSIR_LIM_IGNORE_BEACON;
    else if (limIbssEncTypeMatched(pBeacon, psessionEntry) != eSIR_TRUE)
    {
        PELOG3(limLog(pMac, LOG3,
            FL("peer privacy %d peer wpa %d peer rsn %d self encType %d"),
            pBeacon->capabilityInfo.privacy,
            pBeacon->wpaPresent,
            pBeacon->rsnPresent,
            psessionEntry->encryptType);)
        retCode =  eSIR_LIM_IGNORE_BEACON;
    }
    else
    {
        tANI_U32 ieLen;
        tANI_U16 tsfLater;
        tANI_U8 *pIEs;
        ieLen    = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
        tsfLater = WDA_GET_RX_TSF_LATER(pRxPacketInfo);
        pIEs = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
        PELOG3(limLog(pMac, LOG3, FL("BEFORE Coalescing tsfLater val :%d"), tsfLater);)
        retCode  = limIbssCoalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,psessionEntry);
    }
    return retCode;
} /*** end limHandleIBSScoalescing() ***/

/**
 * lim_enc_type_matched() - matches security type of incoming beracon with
 * current
 * @mac_ctx      Pointer to Global MAC structure
 * @bcn          Pointer to parsed Beacon structure
 * @session     PE session entry
 *
 * This function matches security type of incoming beracon with current
 *
 * @return true if matched, false otherwise
 */
static bool
lim_enc_type_matched(tpAniSirGlobal mac_ctx,
                  tpSchBeaconStruct bcn,
                  tpPESession session)
{
    if (!bcn || !session)
        return false;

    limLog(mac_ctx, LOG1,
           FL("Beacon/Probe:: Privacy :%d WPA Present:%d RSN Present: %d"),
           bcn->capabilityInfo.privacy, bcn->wpaPresent,
           bcn->rsnPresent);
    limLog(mac_ctx, LOG1,
           FL("session:: Privacy :%d EncyptionType: %d OSEN %d WPS %d"),
           SIR_MAC_GET_PRIVACY(session->limCurrentBssCaps),
           session->encryptType, session->osen_association,
           session->wps_registration);

    /* This is handled by sending probe req due to IOT issues so return TRUE */
    if ((bcn->capabilityInfo.privacy) !=
            SIR_MAC_GET_PRIVACY(session->limCurrentBssCaps)) {
        limLog(mac_ctx, LOGW, FL("Privacy bit miss match\n"));
        return true;
    }

    /* Open */
    if ((bcn->capabilityInfo.privacy == 0)
           && (session->encryptType == eSIR_ED_NONE))
        return true;

    /* WEP */
    if ((bcn->capabilityInfo.privacy == 1)
           && (bcn->wpaPresent == 0)
           && (bcn->rsnPresent == 0)
           && ((session->encryptType == eSIR_ED_WEP40)
                  || (session->encryptType == eSIR_ED_WEP104)
#ifdef FEATURE_WLAN_WAPI
                  || (session->encryptType == eSIR_ED_WPI)
#endif
           ))
        return true;

    /* WPA OR RSN*/
    if ((bcn->capabilityInfo.privacy == 1)
            && ((bcn->wpaPresent == 1) || (bcn->rsnPresent == 1))
            && ((session->encryptType == eSIR_ED_TKIP)
                    || (session->encryptType == eSIR_ED_CCMP)
                    || (session->encryptType == eSIR_ED_AES_128_CMAC)))
        return true;

    /* For HS2.0, RSN ie is not present
     * in beacon. Therefore no need to
     * check for security type in case
     * OSEN session.
     * For WPS registration session no need to
     * detect security mismatch as it won't match and
     * driver may end up sending probe request without
     * WPS IE during WPS registration process.
     */
     /*TODO: AP capability mismatch
     * is not checked here because
     * no logic for beacon parsing
     * is avilable for HS2.0
     */
    if (session->osen_association ||
            session->wps_registration)
        return eSIR_TRUE;

    return false;
}

/**
 * limDetectChangeInApCapabilities()
 *
 *FUNCTION:
 * This function is called while SCH is processing
 * received Beacon from AP on STA to detect any
 * change in AP's capabilities. If there any change
 * is detected, Roaming is informed of such change
 * so that it can trigger reassociation.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 * Notification is enabled for STA product only since
 * it is not a requirement on BP side.
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  pBeacon   Pointer to parsed Beacon structure
 * @return None
 */

void
limDetectChangeInApCapabilities(tpAniSirGlobal pMac,
                                tpSirProbeRespBeacon pBeacon,
                                tpPESession psessionEntry)
{
    tANI_U8                 len;
    tSirSmeApNewCaps   apNewCaps;
    tANI_U8            newChannel;
    bool security_caps_matched = true;
    tSirRetStatus status = eSIR_SUCCESS;
    apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);
    newChannel = (tANI_U8) pBeacon->channelNumber;

    security_caps_matched = lim_enc_type_matched(pMac, pBeacon, psessionEntry);
    if ( ( false == psessionEntry->limSentCapsChangeNtf ) &&
        ( ( ( !limIsNullSsid(&pBeacon->ssId) ) &&
             ( false == limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) ) ) ||
          ( (SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) !=
             SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps) ) ||
          ( SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) !=
            SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps) ) ||
          ( SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) !=
            SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps) ) ||
          ( SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) !=
            SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps) ) ||
          ( (newChannel !=  psessionEntry->currentOperChannel) &&
            (newChannel != 0) ) ||
          (eSIR_FALSE == security_caps_matched)
          ) ) )
    {
        if (false == psessionEntry->fWaitForProbeRsp)
        {
            /* If Beacon capabilities is not matching with the current capability,
             * then send unicast probe request to AP and take decision after
             * receiving probe response */
            if ( true == psessionEntry->fIgnoreCapsChange )
            {
                limLog(pMac, LOGW, FL("Ignoring the Capability change as it is false alarm"));
                return;
            }
            psessionEntry->fWaitForProbeRsp = true;
            limLog(pMac, LOGW, FL("AP capabilities are not matching,"
                   "sending directed probe request.. "));
            status = limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId,
                    psessionEntry->currentOperChannel,psessionEntry->selfMacAddr,
                    psessionEntry->dot11mode, 0, NULL);

            if ( eSIR_SUCCESS != status )
            {
               limLog(pMac, LOGE, FL("send ProbeReq failed"));
               psessionEntry->fWaitForProbeRsp = false;
            }
            return;
        }
        /**
         * BSS capabilities have changed.
         * Inform Roaming.
         */
        len = sizeof(tSirMacCapabilityInfo) +
              sizeof(tSirMacAddr) + sizeof(tANI_U8) +
              3 * sizeof(tANI_U8) + // reserved fields
              pBeacon->ssId.length + 1;

        vos_mem_copy(apNewCaps.bssId,
                     psessionEntry->bssId,
                     sizeof(tSirMacAddr));
        if (newChannel != psessionEntry->currentOperChannel)
        {
            PELOGE(limLog(pMac, LOGE, FL("Channel Change from %d --> %d  - "
                                         "Ignoring beacon!"),
                          psessionEntry->currentOperChannel, newChannel);)
            return;
        }

       /**
        * When Cisco 1262 Enterprise APs are configured with WPA2-PSK with
        * AES+TKIP Pairwise ciphers and WEP-40 Group cipher, they do not set
        * the privacy bit in Beacons (wpa/rsnie is still present in beacons),
        * the privacy bit is set in Probe and association responses.
        * Due to this anomaly, we detect a change in
        * AP capabilities when we receive a beacon after association and
        * disconnect from the AP. The following check makes sure that we can
        * connect to such APs
        */
        else if ((SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) == 0) &&
                (pBeacon->rsnPresent || pBeacon->wpaPresent))
        {
            PELOGE(limLog(pMac, LOGE, FL("BSS Caps (Privacy) bit 0 in beacon,"
                                         " but WPA or RSN IE present, Ignore Beacon!"));)
            return;
        }
        else
            apNewCaps.channelId = psessionEntry->currentOperChannel;
        vos_mem_copy((tANI_U8 *) &apNewCaps.ssId,
                     (tANI_U8 *) &pBeacon->ssId,
                      pBeacon->ssId.length + 1);

        psessionEntry->fIgnoreCapsChange = false;
        psessionEntry->fWaitForProbeRsp = false;
        psessionEntry->limSentCapsChangeNtf = true;
        limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_AP_CAPS_CHANGED,
                                    (tANI_U32 *) &apNewCaps,
                                    len, psessionEntry->smeSessionId);
    }
    else if ( true == psessionEntry->fWaitForProbeRsp )
    {
        /* Only for probe response frames and matching capabilities the control
         * will come here. If beacon is with broadcast ssid then fWaitForProbeRsp
         * will be false, the control will not come here*/

        limLog(pMac, LOG1, FL("capabilities in probe response are"
                    "matching with the current setting,"
                    "Ignoring subsequent capability"
                    "mismatch"));
        psessionEntry->fIgnoreCapsChange = true;
        psessionEntry->fWaitForProbeRsp = false;
     }

} /*** limDetectChangeInApCapabilities() ***/




// ---------------------------------------------------------------------
/**
 * limUpdateShortSlot
 *
 * FUNCTION:
 * Enable/Disable short slot
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param enable        Flag to enable/disable short slot
 * @return None
 */

tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, tpSirProbeRespBeacon pBeacon, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
{

    tSirSmeApNewCaps   apNewCaps;
    tANI_U32           nShortSlot;
    tANI_U32 val = 0;
    tANI_U32 phyMode;

    // Check Admin mode first. If it is disabled just return
    if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val)
                   != eSIR_SUCCESS)
    {
        limLog(pMac, LOGP,
               FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed"));
        return eSIR_FAILURE;
    }
    if (val == false)
        return eSIR_SUCCESS;

    // Check for 11a mode or 11b mode. In both cases return since slot time is constant and cannot/should not change in beacon
    limGetPhyMode(pMac, &phyMode, psessionEntry);
    if ((phyMode == WNI_CFG_PHY_MODE_11A) || (phyMode == WNI_CFG_PHY_MODE_11B))
        return eSIR_SUCCESS;

    apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);

    //  Earlier implementation: determine the appropriate short slot mode based on AP advertised modes
    // when erp is present, apply short slot always unless, prot=on  && shortSlot=off
    // if no erp present, use short slot based on current ap caps

    // Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4);

    //Resolution : always use the shortSlot setting the capability info to decide slot time.
    // The difference between the earlier implementation and the new one is only Case4.
    /*
                        ERP IE Present  |   useProtection   |   shortSlot   =   QC STA Short Slot
       Case1        1                                   1                       1                       1           //AP should not advertise this combination.
       Case2        1                                   1                       0                       0
       Case3        1                                   0                       1                       1
       Case4        1                                   0                       0                       0
       Case5        0                                   1                       1                       1
       Case6        0                                   1                       0                       0
       Case7        0                                   0                       1                       1
       Case8        0                                   0                       0                       0
    */
    nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo);

    if (nShortSlot != psessionEntry->shortSlotTimeSupported)
    {
        // Short slot time capability of AP has changed. Adopt to it.
        PELOG1(limLog(pMac, LOG1, FL("Shortslot capability of AP changed: %d"),  nShortSlot);)
        ((tpSirMacCapabilityInfo)&psessionEntry->limCurrentBssCaps)->shortSlotTime = (tANI_U16)nShortSlot;
        psessionEntry->shortSlotTimeSupported = nShortSlot;
        pBeaconParams->fShortSlotTime = (tANI_U8) nShortSlot;
        pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
    }
    return eSIR_SUCCESS;
}

/** -----------------------------------------------------------------
  \brief limHandleMissedBeaconInd() - handles missed beacon indication

  This function process the SIR_HAL_MISSED_BEACON_IND message from HAL,
  and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND
  to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'.

  \param pMac - global mac structure
  \return - none
  \sa
  ----------------------------------------------------------------- */
void limHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
    tpSirSmeMissedBeaconInd  pSirMissedBeaconInd =
                           (tpSirSmeMissedBeaconInd)pMsg->bodyptr;
    tpPESession psessionEntry = peFindSessionByBssIdx(pMac,pSirMissedBeaconInd->bssIdx);
    if (psessionEntry == NULL)
    {
         limLog(pMac, LOGE,
               FL("session does not exist for given BSSIdx:%d"),
               pSirMissedBeaconInd->bssIdx);
         return;
    }
#endif
    if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) ||
         (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)||
         (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) )
    {
        pMac->pmm.inMissedBeaconScenario = TRUE;
        PELOGE(limLog(pMac, LOGE,
              FL("Sending EXIT_BMPS_IND to SME due to Missed beacon from FW"));)
        limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD, psessionEntry);
    }
/* ACTIVE_MODE_HB_OFFLOAD */
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
    else if(((pMac->pmm.gPmmState == ePMM_STATE_READY) ||
                     (pMac->pmm.gPmmState == ePMM_STATE_BMPS_WAKEUP)) &&
                     (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
    {
        pMac->pmm.inMissedBeaconScenario = TRUE;
        PELOGE(limLog(pMac, LOGE, FL("Received Heart Beat Failure"));)
        limMissedBeaconInActiveMode(pMac, psessionEntry);
    }
#endif
    if (pMac->pmm.inMissedBeaconScenario == TRUE) {
        limLog(pMac, LOGW,
               FL("beacon miss handling is already going on for BSSIdx:%d"),
               pSirMissedBeaconInd->bssIdx);
        return;
    }
    else
    {
        limLog(pMac, LOGE,
            FL("Received SIR_HAL_MISSED_BEACON_IND while in incorrect state: %d"),
            pMac->pmm.gPmmState);
    }
    return;
}

/**
 * lim_smps_force_mode_ind() - Process smps force mode event
 * @mac_ctx: Global MAC pointer
 * @data: message containing the parameters of the event
 *
 * Process the smps force mode event and post message to SME to
 * invoke the HDD callback
 *
 * Return: None
 */
void lim_smps_force_mode_ind(tpAniSirGlobal mac_ctx, tpSirMsgQ data)
{
	tSirMsgQ msg;
	tpPESession psession_entry;
	struct sir_smps_force_mode_event *smps_ind, *param;

	smps_ind = data->bodyptr;
	psession_entry = pe_find_session_by_sme_session_id(mac_ctx,
						smps_ind->vdev_id);
	if (psession_entry == NULL) {
		limLog(mac_ctx, LOGE,
		       FL("session does not exist for given BSSIdx: %d"),
		       smps_ind->vdev_id);
		return;
	}

	param = vos_mem_malloc(sizeof(*param));
	if (NULL == param) {
		limLog(mac_ctx, LOGE, FL("Failed to allocate memory"));
		return;
	}
	*param = *smps_ind;

	msg.type = eWNI_SME_SMPS_FORCE_MODE_IND;
	msg.bodyptr = param;
	msg.bodyval = 0;
	limLog(mac_ctx, LOGE,
	       FL("send eWNI_SME_SMPS_FORCE_MODE_IND to SME"));

	limSysProcessMmhMsgApi(mac_ctx, &msg, ePROT);
	return;
}

void
limSendHeartBeatTimeoutInd(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
    tANI_U32 statusCode;
    tSirMsgQ msg;

    /* Prepare and post message to LIM Message Queue */
    msg.type = (tANI_U16) SIR_LIM_HEART_BEAT_TIMEOUT;
    msg.bodyptr = psessionEntry;
    msg.bodyval = 0;
    limLog(pMac, LOGE,
                 FL("Heartbeat failure from Fw"));

    statusCode = limPostMsgApi(pMac, &msg);

    if(statusCode != eSIR_SUCCESS)
    {
       limLog(pMac, LOGE,
              FL("posting message %X to LIM failed, reason=%d"),
              msg.type, statusCode);
    }
}

/** -----------------------------------------------------------------
  \brief limPsOffloadHandleMissedBeaconInd() - handles missed beacon indication

  This function process the SIR_HAL_MISSED_BEACON_IND message from HAL,
  and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND
  to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'.

  \param pMac - global mac structure
  \return - none
  \sa
  ----------------------------------------------------------------- */
void limPsOffloadHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    tpSirSmeMissedBeaconInd  pSirMissedBeaconInd =
                           (tpSirSmeMissedBeaconInd)pMsg->bodyptr;
    tpPESession psessionEntry =
        peFindSessionByBssIdx(pMac,pSirMissedBeaconInd->bssIdx);

    if(!psessionEntry)
    {
         limLog(pMac, LOGE,
               FL("session does not exist for given BSSId"));
         return;
    }

    /* Set Beacon Miss in Powersave Offload */
    psessionEntry->pmmOffloadInfo.bcnmiss = TRUE;

    /*
     * If the session is in power save state then
     * first need to come out of power save before
     * triggering ap probing
     */
    if(psessionEntry->pmmOffloadInfo.psstate == PMM_POWER_SAVE)
    {
        PELOGE(limLog(pMac, LOGE,
            FL("Received Heart Beat Failure in Power Save State"));)

        /* Send Request for Full Power to SME */
        limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD, psessionEntry);
    }
    else
    {
        PELOGE(limLog(pMac, LOGE,
            FL("Received Heart Beat Failure in active state"));)
        /*  Incase  of Active state do AP probing immediately */
        limSendHeartBeatTimeoutInd(pMac, psessionEntry);
    }
    return;
}

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
eHalStatus limRoamFillBssDescr(tpAniSirGlobal pMac,
      tSirRoamOffloadSynchInd *pRoamOffloadSynchInd)
{
   v_U32_t uLen = 0;
   tpSirProbeRespBeacon pParsedFrame;
   tpSirMacMgmtHdr macHeader;
   tANI_U8 *pBeaconProbeResp;
   tSirBssDescription *pBssDescr = NULL;

   pBeaconProbeResp = (tANI_U8 *)pRoamOffloadSynchInd +
   pRoamOffloadSynchInd->beaconProbeRespOffset;
   macHeader = (tpSirMacMgmtHdr)pBeaconProbeResp;
   pParsedFrame =
     (tpSirProbeRespBeacon) vos_mem_malloc(sizeof(tSirProbeRespBeacon));
   if (NULL == pParsedFrame)
   {
     VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
       "%s: fail to allocate memory for frame",__func__);
     return eHAL_STATUS_RESOURCES;
   }

   if ( pRoamOffloadSynchInd->beaconProbeRespLength <= SIR_MAC_HDR_LEN_3A )
   {
      VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
      "%s: Very few bytes in synchInd beacon / probe resp frame! length=%d",
      __func__, pRoamOffloadSynchInd->beaconProbeRespLength);
      vos_mem_free(pParsedFrame);
      return eHAL_STATUS_FAILURE;
   }

   VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,"LFR3: Beacon/Prb Rsp:");
   VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
      pBeaconProbeResp, pRoamOffloadSynchInd->beaconProbeRespLength);
   if (pRoamOffloadSynchInd->isBeacon) {
     if (sirParseBeaconIE(pMac, pParsedFrame,
         &pBeaconProbeResp[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET],
         pRoamOffloadSynchInd->beaconProbeRespLength -
         SIR_MAC_HDR_LEN_3A) != eSIR_SUCCESS || !pParsedFrame->ssidPresent) {
         VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                   "Parse error Beacon, length=%d",
                   pRoamOffloadSynchInd->beaconProbeRespLength);
         vos_mem_free(pParsedFrame);
         return eHAL_STATUS_FAILURE;
     }
   }
   else {
     if (sirConvertProbeFrame2Struct(pMac,
         &pBeaconProbeResp[SIR_MAC_HDR_LEN_3A],
         pRoamOffloadSynchInd->beaconProbeRespLength - SIR_MAC_HDR_LEN_3A,
         pParsedFrame) != eSIR_SUCCESS ||
         !pParsedFrame->ssidPresent) {
         VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
         "Parse error ProbeResponse, length=%d",
         pRoamOffloadSynchInd->beaconProbeRespLength);
         vos_mem_free(pParsedFrame);
         return eHAL_STATUS_FAILURE;
     }
   }
   /* 24 byte MAC header and 12 byte to ssid IE */
   if (pRoamOffloadSynchInd->beaconProbeRespLength >
      (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
     uLen = pRoamOffloadSynchInd->beaconProbeRespLength -
            (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
   }
   pRoamOffloadSynchInd->pbssDescription =
   vos_mem_malloc(sizeof (tSirBssDescription) + uLen); /*De-allocated in
                                           csrProcessRoamOffloadSynchInd*/
   pBssDescr = pRoamOffloadSynchInd->pbssDescription;
   if (NULL == pBssDescr)
   {
     PELOGE(limLog( pMac, LOGE, "LFR3:Failed to allocate memory");)
     VOS_ASSERT(pBssDescr != NULL);
     return eHAL_STATUS_RESOURCES;
   }
     vos_mem_zero(pBssDescr, sizeof(tSirBssDescription));

    /**
     * Length of BSS desription is without length of
     * length itself and length of pointer
     * that holds ieFields
     *
     * tSirBssDescription
     * +--------+---------------------------------+---------------+
     * | length | other fields                    | pointer to IEs|
     * +--------+---------------------------------+---------------+
     *                                            ^
     *                                            ieFields
     */
    pBssDescr->length = (tANI_U16)(offsetof(tSirBssDescription, ieFields[0]) -
                                   sizeof(pBssDescr->length) + uLen);

   if (pParsedFrame->dsParamsPresent)
   {
     pBssDescr->channelId = pParsedFrame->channelNumber;
   }
   else if (pParsedFrame->HTInfo.present)
   {
     pBssDescr->channelId = pParsedFrame->HTInfo.primaryChannel;
   }
   else
   {
     /*If DS Params or HTIE is not present in the probe resp or beacon,
      * then use the channel frequency provided by firmware to fill the
      * channel in the BSS descriptor.*/
     pBssDescr->channelId = vos_freq_to_chan(pRoamOffloadSynchInd->chan_freq);
   }
   pBssDescr->channelIdSelf = pBssDescr->channelId;

   if ((pBssDescr->channelId > 0) && (pBssDescr->channelId < 15))
   {
     int i;
     /* 11b or 11g packet
      * 11g if extended Rate IE is present or
      * if there is an A rate in suppRate IE */
     for (i = 0; i < pParsedFrame->supportedRates.numRates; i++) {
       if (sirIsArate(pParsedFrame->supportedRates.rate[i] & 0x7f)) {
          pBssDescr->nwType = eSIR_11G_NW_TYPE;
          break;
       }
     }
     if (pParsedFrame->extendedRatesPresent) {
         pBssDescr->nwType = eSIR_11G_NW_TYPE;
     }
   } else {
     /* 11a packet */
     pBssDescr->nwType = eSIR_11A_NW_TYPE;
   }

   pBssDescr->sinr = 0;
   pBssDescr->beaconInterval = pParsedFrame->beaconInterval;
   pBssDescr->timeStamp[0]   = pParsedFrame->timeStamp[0];
   pBssDescr->timeStamp[1]   = pParsedFrame->timeStamp[1];
   vos_mem_copy(&pBssDescr->capabilityInfo,
   &pBeaconProbeResp[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_CAPAB_OFFSET], 2);
   vos_mem_copy((tANI_U8 *) &pBssDescr->bssId,
                 (tANI_U8 *) macHeader->bssId,
                         sizeof(tSirMacAddr));
   pBssDescr->nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
   if(pParsedFrame->mdiePresent) {
     pBssDescr->mdiePresent = pParsedFrame->mdiePresent;
     vos_mem_copy((tANI_U8 *)pBssDescr->mdie, (tANI_U8 *)pParsedFrame->mdie,
                   SIR_MDIE_SIZE);
   }
   VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
             "LFR3:%s:BssDescr Info:", __func__);
   VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
                      pBssDescr->bssId, sizeof(tSirMacAddr));
   VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
             "chan=%d, rssi=%d",pBssDescr->channelId,pBssDescr->rssi);
   if (uLen)
   {
     vos_mem_copy(&pBssDescr->ieFields,
     pBeaconProbeResp + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET),
     uLen);
   }
   vos_mem_free(pParsedFrame);
   return eHAL_STATUS_SUCCESS;
}

/** -----------------------------------------------------------------
  * brief limRoamOffloadSynchInd() - Handles Roam Synch Indication
  * param pMac - global mac structure
  * return - none
  ----------------------------------------------------------------- */
void limRoamOffloadSynchInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
     tpPESession psessionEntry;
     tpPESession pftSessionEntry;
     tANI_U8 sessionId;
     tSirMsgQ mmhMsg;
     tSirBssDescription *pbssDescription = NULL;
     tpSirRoamOffloadSynchInd pRoamOffloadSynchInd =
                           (tpSirRoamOffloadSynchInd)pMsg->bodyptr;

     if (!pRoamOffloadSynchInd) {
       VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
       "LFR3:%s:pRoamOffloadSynchInd is NULL", __func__);
       return;
     }
     VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
               "LFR3: Received WDA_ROAM_OFFLOAD_SYNCH_IND");
     VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
               "LFR3:%s:authStatus=%d, vdevId=%d", __func__,
               pRoamOffloadSynchInd->authStatus,
               pRoamOffloadSynchInd->roamedVdevId);
     VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
                        pRoamOffloadSynchInd->bssId,6);
     psessionEntry = peFindSessionByBssIdx(pMac,
                     pRoamOffloadSynchInd->roamedVdevId);
     if (psessionEntry == NULL) {
       PELOGE(limLog( pMac, LOGE,
               "%s: LFR3:Unable to find session", __func__);)
       return;
     }
     /* Nothing to be done if the session is not in STA mode */
     if (!LIM_IS_STA_ROLE(psessionEntry)) {
        PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));)
        return;
     }
     if (!HAL_STATUS_SUCCESS(limRoamFillBssDescr(pMac,
                             pRoamOffloadSynchInd))) {
       VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
       "LFR3:%s:Failed to fill Bss Descr", __func__);
       return;
     }
     pbssDescription = pRoamOffloadSynchInd->pbssDescription;
     if((pftSessionEntry = peCreateSession(pMac, pbssDescription->bssId,
                                       &sessionId, pMac->lim.maxStation,
                                       eSIR_INFRASTRUCTURE_MODE)) == NULL) {
        limLog(pMac, LOGE, FL("LFR3: Session Can not be created for new AP"
                              "during Roam Offload Synch"));
        limPrintMacAddr( pMac, pbssDescription->bssId, LOGE );
        return;
     }
     pftSessionEntry->peSessionId = sessionId;
     sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr);
     sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId);
     pftSessionEntry->bssType = eSIR_INFRASTRUCTURE_MODE;
     /*Set bRoamSynchInProgress here since this session is
      * specific to roam synch indication. This flag will
      * later be used to differentiate LFR3 with LFR2 in LIM
      */
     pftSessionEntry->bRoamSynchInProgress = VOS_TRUE;

     if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
       pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
     else {
       limLog(pMac, LOGE, FL("LFR3:Invalid bss type"));
       return;
     }
     pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
     pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
     VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
               "LFR3:%s:created session (%pK) with id = %d",
               __func__, pftSessionEntry, pftSessionEntry->peSessionId);
     /* Update the ReAssoc BSSID of the current session */
     sirCopyMacAddr(psessionEntry->limReAssocbssId, pbssDescription->bssId);
     limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOG2);

     /* Prepare the session right now with as much as possible */
     limFillFTSession(pMac, pbssDescription, pftSessionEntry, psessionEntry);
     limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry, pbssDescription );
     mmhMsg.type =
     pRoamOffloadSynchInd->messageType;/* eWNI_SME_ROAM_OFFLOAD_SYNCH_IND */
     mmhMsg.bodyptr = pRoamOffloadSynchInd;
     mmhMsg.bodyval = 0;

     VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
         "LFR3:%s:sending eWNI_SME_ROAM_OFFLOAD_SYNCH_IND", __func__);
     limSysProcessMmhMsgApi(pMac, &mmhMsg,  ePROT);
}

#endif

/**
 * lim_mon_init_session() - create PE session for monitor mode operation
 * @mac_ptr: mac pointer
 * @msg: Pointer to struct sir_create_session type.
 *
 * Return: NONE
 */
void lim_mon_init_session(tpAniSirGlobal mac_ptr,
			  struct sir_create_session *msg)
{
	tpPESession psession_entry;
	uint8_t session_id;

	if((psession_entry = peCreateSession(mac_ptr, msg->bss_id,
	                                  &session_id, mac_ptr->lim.maxStation,
	                                  eSIR_MONITOR_MODE)) == NULL) {
		limLog(mac_ptr, LOGE,
		       FL("Monitor mode: Session Can not be created"));
		limPrintMacAddr(mac_ptr, msg->bss_id, LOGE);
		return;
	}
	psession_entry->vhtCapability = 1;
	psession_entry->sub20_channelwidth = mac_ptr->sub20_channelwidth;
}

/** -----------------------------------------------------------------
  \brief limMicFailureInd() - handles mic failure  indication

  This function process the SIR_HAL_MIC_FAILURE_IND message from HAL,

  \param pMac - global mac structure
  \return - none
  \sa
  ----------------------------------------------------------------- */
void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
{
    tpSirSmeMicFailureInd pSirSmeMicFailureInd;
    tpSirSmeMicFailureInd pSirMicFailureInd = (tpSirSmeMicFailureInd)pMsg->bodyptr;
    tSirMsgQ            mmhMsg;
    tpPESession psessionEntry ;
    tANI_U8     sessionId;

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

    pSirSmeMicFailureInd = vos_mem_malloc(sizeof(*pSirSmeMicFailureInd));
    if (NULL == pSirSmeMicFailureInd)
    {
        // Log error
       limLog(pMac, LOGP,
               FL("memory allocate failed for eWNI_SME_MIC_FAILURE_IND"));
       return;
    }

    *pSirSmeMicFailureInd = *pSirMicFailureInd;
    pSirSmeMicFailureInd->sessionId = psessionEntry->smeSessionId;

    mmhMsg.type = eWNI_SME_MIC_FAILURE_IND;
    mmhMsg.bodyptr = pSirSmeMicFailureInd;
    mmhMsg.bodyval = 0;
    MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type));
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
    return;
}

tANI_U8 limIsBeaconMissScenario(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
{
    if(pMac->psOffloadEnabled)
    {
        tpSirMacMgmtHdr pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
        tANI_U8 sessionId;
        tpPESession psessionEntry =
                    peFindSessionByBssid(pMac,pHdr->bssId,&sessionId);

        if(psessionEntry && psessionEntry->pmmOffloadInfo.bcnmiss)
           return true;
    }
    else if(pMac->pmm.inMissedBeaconScenario)
    {
        return true;
    }
    return false;
}

/** -----------------------------------------------------------------
  \brief limIsPktCandidateForDrop() - decides whether to drop the frame or not

  This function is called before enqueuing the frame to PE queue for further processing.
  This prevents unnecessary frames getting into PE Queue and drops them right away.
  Frames will be droped in the following scenarios:

   - In Scan State, drop the frames which are not marked as scan frames
   - In non-Scan state, drop the frames which are marked as scan frames.
   - Drop INFRA Beacons and Probe Responses in IBSS Mode
   - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon

  \param pMac - global mac structure
  \return - none
  \sa
  ----------------------------------------------------------------- */

tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType)
{
    tANI_U32                     framelen;
    tANI_U8                      *pBody;
    tSirMacCapabilityInfo     capabilityInfo;
    tpSirMacMgmtHdr           pHdr=NULL;
    tpPESession               psessionEntry=NULL;
    tANI_U8                   sessionId;

    /*
    *
    * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames.
    * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames.
    * Allow other mgmt frames, they must be from our own AP, as we don't allow
    * other than beacons or probe responses in scan state.
    */
    if( (subType == SIR_MAC_MGMT_BEACON) ||
        (subType == SIR_MAC_MGMT_PROBE_RSP))
    {
        if(limIsBeaconMissScenario(pMac, pRxPacketInfo))
        {
            MTRACE(macTrace(pMac, TRACE_CODE_INFO_LOG, 0, eLOG_NODROP_MISSED_BEACON_SCENARIO));
            return eMGMT_DROP_NO_DROP;
        }
        if (limIsSystemInScanState(pMac))
        {
            return eMGMT_DROP_NO_DROP;
        }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
        else if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))
        {
            return eMGMT_DROP_NO_DROP;
        }
#endif
        else if (WDA_IS_RX_IN_SCAN(pRxPacketInfo))
        {
            return eMGMT_DROP_SCAN_MODE_FRAME;
        }
    }

    framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
    pBody    = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);

    //Drop INFRA Beacons and Probe Responses in IBSS Mode
    if( (subType == SIR_MAC_MGMT_BEACON) ||
        (subType == SIR_MAC_MGMT_PROBE_RSP))
    {
        //drop the frame if length is less than 12
        if(framelen < LIM_MIN_BCN_PR_LENGTH)
            return eMGMT_DROP_INVALID_SIZE;

        *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET);

        /* Note sure if this is sufficient, basically this condition allows all probe responses and
         *   beacons from an infrastructure network
         */
        if(!capabilityInfo.ibss)
            return eMGMT_DROP_NO_DROP;

        //This can be enhanced to even check the SSID before deciding to enque the frame.
        if(capabilityInfo.ess)
            return eMGMT_DROP_INFRA_BCN_IN_IBSS;
    }
    else if( (subType == SIR_MAC_MGMT_PROBE_REQ) &&
                (!WDA_GET_RX_BEACON_SENT(pRxPacketInfo)))
    {
        pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
        psessionEntry = peFindSessionByBssid(pMac, pHdr->bssId, &sessionId);
        if ((psessionEntry && !LIM_IS_IBSS_ROLE(psessionEntry)) ||
            (!psessionEntry))
            return eMGMT_DROP_NO_DROP;

        //Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
        //In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq
        return eMGMT_DROP_NOT_LAST_IBSS_BCN;
    }

    return eMGMT_DROP_NO_DROP;
}

/**
 * lim_update_lost_link_info() - update lost link information to SME
 * @mac: global MAC handle
 * @session: PE session
 * @rssi: rssi value from the received frame
 *
 * Return: none
 */
void lim_update_lost_link_info(tpAniSirGlobal mac, tpPESession session,
                               int8_t rssi)
{
	struct sir_lost_link_info *lost_link_info;
	tSirMsgQ mmh_msg;
	if ((NULL == mac) || (NULL == session)) {
		VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
			  "%s: parameter NULL", __func__);
		return;
	}
	if (!LIM_IS_STA_ROLE(session)) {
		VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
			  "%s: not STA mode, do nothing", __func__);
		return;
	}

	lost_link_info = vos_mem_malloc(sizeof(*lost_link_info));
	if (NULL == lost_link_info) {
		VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
			  "%s: lost_link_info allocation failure", __func__);
		return;
	}

	lost_link_info->vdev_id = session->smeSessionId;
	lost_link_info->rssi = rssi;
	mmh_msg.type = eWNI_SME_LOST_LINK_INFO_IND;
	mmh_msg.bodyptr = lost_link_info;
	mmh_msg.bodyval = 0;
	VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
		  "%s: post eWNI_SME_LOST_LINK_INFO_IND, bss_idx %d, rssi %d",
		  __func__, lost_link_info->vdev_id, lost_link_info->rssi);

	limSysProcessMmhMsgApi(mac, &mmh_msg, ePROT);
}

eHalStatus pe_AcquireGlobalLock( tAniSirLim *psPe)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;

    if(psPe)
    {
        if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psPe->lkPeGlobalLock) ) )
        {
            status = eHAL_STATUS_SUCCESS;
        }
    }
    return (status);
}
eHalStatus pe_ReleaseGlobalLock( tAniSirLim *psPe)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    if(psPe)
    {
        if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psPe->lkPeGlobalLock) ) )
        {
            status = eHAL_STATUS_SUCCESS;
        }
    }
    return (status);
}

/**
 * pe_register_packetdump_callback() - stores rx packet dump
 * callback handler
 * @pe_packetdump_cb: packetdump cb
 *
 * This function is used to store rx packet dump callback
 *
 * Return: None
 *
 */
void pe_register_packetdump_callback(tp_pe_packetdump_cb pe_packetdump_cb)
{
	gpe_packetdump_cb = pe_packetdump_cb;
}

/**
 * pe_deregister_packetdump_callback() - removes tx packet dump
 * callback handler
 *
 * This function is used to remove rx packet dump callback
 *
 * Return: None
 *
 */
void pe_deregister_packetdump_callback(void)
{
	gpe_packetdump_cb = NULL;
}
