/*
 * Copyright (c) 2012-2013, 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.
 */
/*
 * Copyright (c) 2012, 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.
 */

/*
 * Airgo Networks, Inc proprietary. All rights reserved.
 * 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 "wniCfgSta.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"
#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 "wlan_qct_tl.h"
#include "sysStartup.h"


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;

    palZeroMemory(pMac->hHdd, pMac->lim.gLimCachedScanHashTable,
                    sizeof(pMac->lim.gLimCachedScanHashTable));

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD

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

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

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


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

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


static void __limInitBssVars(tpAniSirGlobal pMac)
{

    palZeroMemory(pMac->hHdd,  (void*)pMac->lim.gpSession,   sizeof(*pMac->lim.gpSession)*pMac->lim.maxBssId);


    //pMac->lim.gpLimStartBssReq = NULL;




/* These global variables are moved to session table and intialization is done during session creation Oct 9th Review */
#if 0

   // Place holder for BSS description that we're
   // currently joined with
   palZeroMemory(pMac->hHdd, &pMac->lim.gLimCurrentBssId, sizeof(tSirMacAddr));
   pMac->lim.gLimCurrentChannelId = HAL_INVALID_CHANNEL_ID;
   palZeroMemory(pMac->hHdd, &pMac->lim.gLimCurrentSSID, sizeof(tSirMacSSid));
   pMac->lim.gLimCurrentBssCaps = 0;
   QosCaps is a bit map of various qos capabilities - see defn above
   pMac->lim.gLimCurrentBssQosCaps = 0;
   pMac->lim.gLimCurrentBssPropCap = 0;
   pMac->lim.gLimSentCapsChangeNtf = 0;

   // Place holder for BSS description that
   // we're currently Reassociating
   palZeroMemory(pMac->hHdd, &pMac->lim.gLimReassocBssId, sizeof(tSirMacAddr));
   pMac->lim.gLimReassocChannelId = 0;
   palZeroMemory(pMac->hHdd, &pMac->lim.gLimReassocSSID, sizeof(tSirMacSSid));
   pMac->lim.gLimReassocBssCaps = 0;
   pMac->lim.gLimReassocBssQosCaps = 0;
   pMac->lim.gLimReassocBssPropCap = 0;
 #endif

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

   // pMac->lim.gLimBssIdx = 0;

    pMac->lim.gpLimMlmSetKeysReq = NULL;
    pMac->lim.gpLimMlmRemoveKeyReq = NULL;
  //  pMac->lim.gLimStaid = 0; //TO SUPPORT BT-AMP

}


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.gLimNumOfCurrentSTAs = 0;
    pMac->lim.gLimNumOfAniSTAs = 0;      // count of ANI peers

    /// This indicates number of RXed Beacons during HB period
    //pMac->lim.gLimRxedBeaconCntDuringHB = 0;

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

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

#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;
    palZeroMemory(pMac->hHdd, pMac->lim.numMAC, sizeof(pMac->lim.numMAC));
    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;

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

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

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

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

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

#if 0 /* Moving all these to session specific elements */
    pMac->lim.gLimQosEnabled = 0; //11E
    pMac->lim.gLimWmeEnabled = 0; //WME
    pMac->lim.gLimWsmEnabled = 0; //WSM
    pMac->lim.gLimHcfEnabled = 0;
    pMac->lim.gLim11dEnabled = 0;
#endif

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

static void __limInitVars(tpAniSirGlobal pMac)
{


    // Place holder for Measurement Req/Rsp/Ind related info

    // WDS info
    pMac->lim.gLimNumWdsInfoInd = 0;
    pMac->lim.gLimNumWdsInfoSet = 0;
    palZeroMemory(pMac->hHdd, &pMac->lim.gLimWdsInfo, sizeof(tSirWdsInfo));
    /* initialize some parameters */
    limInitWdsInfoParams(pMac);

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

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

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

#if 0
    // 11h Spectrum Management Related Flag
    LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
    pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE;
#endif
    // 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;

    palZeroMemory(pMac->hHdd, &pMac->lim.tspecInfo, sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX);

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

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

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

static void __limInitAssocVars(tpAniSirGlobal pMac)
{
    tANI_U32 val;
#if 0
    palZeroMemory(pMac->hHdd, pMac->lim.gpLimAIDpool,
                  sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1));
    pMac->lim.freeAidHead = 0;
    pMac->lim.freeAidTail = 0;
#endif
    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;

    // Place holder for current authentication request
    // being handled
    pMac->lim.gpLimMlmAuthReq = NULL;
    //pMac->lim.gpLimMlmJoinReq = NULL;

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

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

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

    // Send Disassociate frame threshold parameters
    pMac->lim.gLimDisassocFrameThreshold = LIM_SEND_DISASSOC_FRAME_THRESHOLD;
    pMac->lim.gLimDisassocFrameCredit = 0;

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

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

}


static void __limInitTitanVars(tpAniSirGlobal pMac)
{
#if 0
    palZeroMemory(pMac->hHdd, &pMac->lim.gLimChannelSwitch, sizeof(tLimChannelSwitchInfo));
    pMac->lim.gLimChannelSwitch.state               = eLIM_CHANNEL_SWITCH_IDLE;
    pMac->lim.gLimChannelSwitch.secondarySubBand    = PHY_SINGLE_CHANNEL_CENTERED;
#endif
    // Debug workaround for BEACON's
    // State change triggered by "dump 222"
    pMac->lim.gLimScanOverride = 1;
    pMac->lim.gLimScanOverrideSaved = eSIR_ACTIVE_SCAN;
    pMac->lim.gLimTitanStaCount = 0;
    pMac->lim.gLimBlockNonTitanSta = 0;
}

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;
  
   //channel bonding mode could be set to anything from 0 to 4(Titan had these 
   // modes But for Taurus we have only two modes: enable(>0) or disable(=0)
   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"));)
      return eSIR_FAILURE;
   }
   val16 = ( tANI_U16 ) val1;
   pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16;
   pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2;
   if(cfgSetInt(pMac,  WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != 
      eSIR_SUCCESS)
   {
      PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG"));)
      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 */

   /* Allocate and fill in power save configuration. */
   if (palAllocateMemory(pMac->hHdd, (void **)&pPowerSaveConfig,
        sizeof(tSirPowerSaveCfg)) != eHAL_STATUS_SUCCESS)
   {
      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
    */
   palCopyMemory(pMac->hHdd, 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(wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,(tANI_U32 *) &pMac->lim.disableLDPCWithTxbfAP) != eSIR_SUCCESS)
   {
      limLog(pMac, LOGP, FL("cfg get disableLDPCWithTxbfAP failed"));
      return eSIR_FAILURE;
   }
#ifdef FEATURE_WLAN_TDLS
   if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_BUF_STA_ENABLED,(tANI_U32 *) &pMac->lim.gLimTDLSBufStaEnabled) != eSIR_SUCCESS)
   {
       limLog(pMac, LOGP, FL("cfg get LimTDLSBufStaEnabled failed"));
       return eSIR_FAILURE;
   }
   if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK,(tANI_U32 *) &pMac->lim.gLimTDLSUapsdMask) != eSIR_SUCCESS)
   {
       limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask 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
      limInitMlm(pMac);

      // 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);
    __limInitTitanVars(pMac);

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

    /*
     * MLM will be intitalized when 'START' request comes from SME.
     * limInitMlm calls limCreateTimers, which actually relies on
     * CFG to be downloaded. So it should not be called as part of
     * peStart, as CFG download is happening after peStart.
     */
    //limInitMlm(pMac);
    // Initializations for maintaining peers in IBSS
    limIbssInit(pMac);

    pmmInitialize(pMac);

    
#if defined WLAN_FEATURE_VOWIFI
    rrmInitialize(pMac);
#endif
#if defined WLAN_FEATURE_VOWIFI_11R
    limFTOpen(pMac);
#endif

    vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue);

#if 0

    vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR);
    vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN);
    vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL);

    vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_WARN);
    vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_ERROR);

    vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN);
    vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR);
    vos_trace_setLevel(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR);
    
    vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR);
    
    vos_trace_setLevel(VOS_MODULE_ID_SSC, VOS_TRACE_LEVEL_ERROR);
    
    vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR);
    vos_trace_setLevel(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR);

    vos_trace_setLevel(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR);

    
    vos_trace_setLevel(VOS_MODULE_ID_BAL, VOS_TRACE_LEVEL_ERROR);
    
    vos_trace_setLevel(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR);
#endif
    MTRACE(limTraceInit(pMac));

    //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)
{
    v_PVOID_t pvosGCTx;
    VOS_STATUS retStatus;

//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.

    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"));

        palFreeMemory(pMac, pLimMgmtRegistration);
    }

    vos_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue);

    limCleanupMlm(pMac);
    limCleanupLmm(pMac);

    // free up preAuth table
    if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL)
    {
        palFreeMemory(pMac->hHdd, 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)
    {
        palFreeMemory(pMac->hHdd, (void *) pMac->lim.pDialogueTokenTail);
        pMac->lim.pDialogueTokenTail = NULL;
    }

    # if 0
    if (pMac->lim.gpLimStartBssReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimStartBssReq);
        pMac->lim.gpLimStartBssReq = NULL;
    }
    #endif

    if (pMac->lim.gpLimMlmSetKeysReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmSetKeysReq);
        pMac->lim.gpLimMlmSetKeysReq = NULL;
    }

    #if 0
    if (pMac->lim.gpLimJoinReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimJoinReq);
        pMac->lim.gpLimJoinReq = NULL;
    }
    #endif

    if (pMac->lim.gpLimMlmAuthReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmAuthReq);
        pMac->lim.gpLimMlmAuthReq = NULL;
    }

#if 0
    if (pMac->lim.gpLimMlmJoinReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmJoinReq);
        pMac->lim.gpLimMlmJoinReq = NULL;
    }
#endif

    #if 0
    if (pMac->lim.gpLimReassocReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimReassocReq);
        pMac->lim.gpLimReassocReq = NULL;
    }
    #endif

    if (pMac->lim.gpLimMlmRemoveKeyReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmRemoveKeyReq);
        pMac->lim.gpLimMlmRemoveKeyReq = NULL;
    }

    if (pMac->lim.gpDefdSmeMsgForNOA != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpDefdSmeMsgForNOA);
        pMac->lim.gpDefdSmeMsgForNOA = NULL;
    }

    if (pMac->lim.gpLimMlmScanReq != NULL)
    {
        palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmScanReq);
        pMac->lim.gpLimMlmScanReq = NULL;
    }

#if 0
    if(NULL != pMac->lim.beacon)
    {
        palFreeMemory(pMac->hHdd, (void*) pMac->lim.beacon);
        pMac->lim.beacon = NULL;
     }
#endif
    #if 0
    if(NULL != pMac->lim.assocReq)
    {
        palFreeMemory(pMac->hHdd, (void*) pMac->lim.assocReq);
        pMac->lim.assocReq= NULL;
     }
    #endif

#if 0
    if(NULL != pMac->lim.assocRsp)
    {
        palFreeMemory(pMac->hHdd, (void*) pMac->lim.assocRsp);
        pMac->lim.assocRsp= NULL;
     }
#endif
    // Now, finally reset the deferred message queue pointers
    limResetDeferredMsgQ(pMac);


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

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

#if defined WLAN_FEATURE_VOWIFI
    rrmCleanup(pMac);
#endif
#if defined WLAN_FEATURE_VOWIFI_11R
    limFTCleanup(pMac);
#endif

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


/** -------------------------------------------------------------
\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)
{
    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;
    }

    if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
              (void **) &pMac->lim.limTimers.gpLimCnfWaitTimer, sizeof(TX_TIMER)*pMac->lim.maxStation))
    {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));)
        return eSIR_FAILURE;
    }

#if 0
    if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
              (void **) &pMac->lim.gpLimAIDpool, 
              sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1)))
    {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));)
        return eSIR_FAILURE;
    }
#endif
    if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
        (void **) &pMac->lim.gpSession, sizeof(tPESession)* pMac->lim.maxBssId))
    {
        limLog(pMac, LOGE, FL("memory allocate failed!"));
        return eSIR_FAILURE;
    }
 
    palZeroMemory(pMac->hHdd, pMac->lim.gpSession, sizeof(tPESession)*pMac->lim.maxBssId);


 /*
    if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
              (void **) &pMac->dph.dphHashTable.pHashTable, sizeof(tpDphHashNode)*pMac->lim.maxStation))
    {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));)
        return eSIR_FAILURE;
    }

    if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
              (void **) &pMac->dph.dphHashTable.pDphNodeArray, sizeof(tDphHashNode)*pMac->lim.maxStation))
    {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));)
        return eSIR_FAILURE;
    }
    */

    if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
              (void **) &pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation))
    {
        PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pTim!"));)
        return eSIR_FAILURE;
    }
    palZeroMemory(pMac->hHdd, pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation);

    pMac->lim.mgmtFrameSessionId = 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!"));)
        return eSIR_FAILURE;
    }
    pMac->lim.deauthMsgCnt = 0;
    return eSIR_SUCCESS;
}

/** -------------------------------------------------------------
\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]);
        }
    }
    palFreeMemory(pMac->hHdd, pMac->lim.limTimers.gpLimCnfWaitTimer);
    pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
#if 0
    palFreeMemory(pMac->hHdd, pMac->lim.gpLimAIDpool);
    pMac->lim.gpLimAIDpool = NULL;
#endif
    
    palFreeMemory(pMac->hHdd, pMac->lim.gpSession);
    pMac->lim.gpSession = NULL;
    /*
    palFreeMemory(pMac->hHdd, pMac->dph.dphHashTable.pHashTable);
    pMac->dph.dphHashTable.pHashTable = NULL;
    palFreeMemory(pMac->hHdd, pMac->dph.dphHashTable.pDphNodeArray);
    pMac->dph.dphHashTable.pDphNodeArray = NULL;
    */
    palFreeMemory(pMac->hHdd, 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;
            /* May allow following timer messages in sleep mode */
            case SIR_LIM_HASH_MISS_THRES_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_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:
                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() ***/


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

  \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(pMac->gDriverType == 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);
        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);
        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) 
    {
    PELOG1(limLog( pMac, LOG1,
       FL ( "RxBd=%p mHdr=%p Type: %d Subtype: %d  Sizes:FC%d Mgmt%d"),
       pRxPacketInfo, mHdr, mHdr->fc.type, mHdr->fc.subType, sizeof(tSirMacFrameCtl), sizeof(tSirMacMgmtHdr) );)

    MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT, NO_SESSION, 
                        LIM_TRACE_MAKE_RXMGMT(mHdr->fc.subType,  
                        (tANI_U16) (((tANI_U16) (mHdr->seqControl.seqNumHi << 4)) | mHdr->seqControl.seqNumLo)));)
    }


    // 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);
        limLog( pMac, LOGW,
                FL ( "sysBbtProcessMessageCore failed to process SIR_BB_XPORT_MGMT_MSG" ));
        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++;

    pMac->pmm.inMissedBeaconScenario = FALSE;
} /*** end limReceivedHBHandler() ***/



#if 0
void limResetHBPktCount(tpPESession psessionEntry)
{
    psessionEntry->LimRxedBeaconCntDuringHB = 0;
}
#endif


/*
 * limProcessWdsInfo()
 *
 *FUNCTION:
 * This function is called from schBeaconProcess in BP
 *
 *PARAMS:
 * @param pMac     - Pointer to Global MAC structure
 * @param propIEInfo - proprietary IE info
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 *
 *RETURNS:
 *
 */

void limProcessWdsInfo(tpAniSirGlobal pMac,
                       tSirPropIEStruct propIEInfo)
{
}



/**
 * limInitWdsInfoParams()
 *
 *FUNCTION:
 * This function is called while processing
 * START_BSS/JOIN/REASSOC_REQ  to initialize WDS info
 * ind/set related parameters.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

void
limInitWdsInfoParams(tpAniSirGlobal pMac)
{
    pMac->lim.gLimWdsInfo.wdsLength = 0;
    pMac->lim.gLimNumWdsInfoInd     = 0;
    pMac->lim.gLimNumWdsInfoSet     = 0;
} /*** limInitWdsInfoParams() ***/


/** -------------------------------------------------------------
\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)
    {
        palCopyMemory( pMac->hHdd, 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 (palEqualMemory( pMac->hHdd,pMac->lim.protStaOverlapCache[i].addr,
                          bssId,
                          sizeof(tSirMacAddr))) {
                return; }
        }
        else
            break;
    }

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

        pStaParams->numSta++;
    }
}


/**
 * 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);
    if ( (!pBeacon->capabilityInfo.ibss) || (limCmpSSid(pMac, &pBeacon->ssId,psessionEntry) != true) )
        /* Received SSID does not match => Ignore received Beacon frame. */
        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() ***/



/**
 * 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;
    tSirRetStatus status = eSIR_SUCCESS;
    apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);
    newChannel = (tANI_U8) pBeacon->channelNumber;

    /* Some APs are not setting privacy bit when hidden ssid enabled.
     * So LIM was keep on sending eSIR_SME_AP_CAPS_CHANGED event to SME */
    if ((limIsNullSsid(&pBeacon->ssId) &&
            (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))
       )
    {
        /* If Hidden SSID and privacy bit is not matching with the current capability,
         * then send unicast probe request to AP and take decision after
         * receiving probe response */
        if (psessionEntry->fIgnoreCapsChange == true)
        {
            limLog(pMac, LOGW, FL("Ignoring the Capability change as it is false alarm"));
            return;
        }
        psessionEntry->fWaitForProbeRsp = true;
        limLog(pMac, LOGW, FL("Hidden SSID and privacy bit is not matching,"
                    " Or Short preamble bit is not matching ,"
                    "sending directed probe request.. "));
        status = limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId,
                psessionEntry->currentOperChannel,psessionEntry->selfMacAddr,
                psessionEntry->dot11mode, 0, NULL);

        if ( status != eSIR_SUCCESS)
        {
            limLog(pMac, LOGE, FL("send ProbeReq failed"));
        }

        return;
    }
    else
    {
        /* The control will come here if the frame is beacon with broadcast ssid
         * or probe response frame */
        if (psessionEntry->fWaitForProbeRsp == true)
        {
            if ((((!limIsNullSsid(&pBeacon->ssId)) &&
                        (limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) == true)) &&
                    (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))
               )
            {
                /* Only for probe response frames the control will come here */
                /* If beacon with broadcast ssid then fWaitForProbeRsp will be false,
                   the control wll not come here*/
                limLog(pMac, LOGW, FL("Privacy bit in probe response is"
                            "matching with the current setting,"
                            "Ignoring subsequent privacy bit capability"
                            "mismatch"));
                psessionEntry->fIgnoreCapsChange = true;
                psessionEntry->fWaitForProbeRsp = false;
            }
        }
    }

    if ((psessionEntry->limSentCapsChangeNtf == false) &&
        (((!limIsNullSsid(&pBeacon->ssId)) && (limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) == false)) ||
        ((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)
         )))
    {

        /**
         * BSS capabilities have changed.
         * Inform Roaming.
         */
        len = sizeof(tSirMacCapabilityInfo) +
              sizeof(tSirMacAddr) + sizeof(tANI_U8) +
              3 * sizeof(tANI_U8) + // reserved fields
              pBeacon->ssId.length + 1;

        palCopyMemory( pMac->hHdd, 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;
        palCopyMemory( pMac->hHdd, (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);
    }
} /*** 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 limHandleLowRssiInd() - handles low rssi indication
 
  This function process the SIR_HAL_LOW_RSSI_IND message from
  HAL, and sends a eWNI_SME_LOW_RSSI_IND to CSR.

  \param pMac - global mac structure

  \return  

  \sa
  ----------------------------------------------------------------- */
void limHandleLowRssiInd(tpAniSirGlobal pMac)
{
#if 0  //RSSI related indications will now go to TL and not PE
    if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) ||
         (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)||
         (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) )
    {
        PELOG1(limLog(pMac, LOG1, FL("Sending LOW_RSSI_IND to SME "));)
        limSendSmeRsp(pMac, eWNI_SME_LOW_RSSI_IND, eSIR_SME_SUCCESS, 0, 0);
    }
    else
    {
        limLog(pMac, LOGE,
            FL("Received SIR_HAL_LOW_RSSI_IND while in incorrect state: %d"),
            pMac->pmm.gPmmState);
    }
    return;
#endif
}


/** -----------------------------------------------------------------
  \brief limHandleBmpsStatusInd() - handles BMPS status indication
 
  This function process the SIR_HAL_BMPS_STATUS_IND message from HAL, 
  and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND 
  to SME with reason code 'eSME_EXIT_BMPS_IND_RCVD'. 
  
  HAL sends this message when Firmware fails to enter BMPS mode 'AFTER'
  HAL had already send PE a SIR_HAL_ENTER_BMPS_RSP with status 
  code "success".  Hence, HAL needs to notify PE to get out of BMPS mode. 
  This message can also come from FW anytime after we have entered BMPS. 
  This means we should handle it in WoWL and UAPSD states as well
   
  \param pMac - global mac structure
  \return - none
  \sa
  ----------------------------------------------------------------- */
void limHandleBmpsStatusInd(tpAniSirGlobal pMac)
{
    switch(pMac->pmm.gPmmState)
    {
        case ePMM_STATE_BMPS_SLEEP:
        case ePMM_STATE_UAPSD_WT_SLEEP_RSP:
        case ePMM_STATE_UAPSD_SLEEP:
        case ePMM_STATE_UAPSD_WT_WAKEUP_RSP:
        case ePMM_STATE_WOWLAN:
            PELOG1(limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME "));)
            limSendExitBmpsInd(pMac, eSME_BMPS_STATUS_IND_RCVD);
            break;

        default:
            limLog(pMac, LOGE,
                FL("Received SIR_HAL_BMPS_STATUS_IND while in incorrect state: %d"),
                pMac->pmm.gPmmState);
            break;
    }
    return;
}


/** -----------------------------------------------------------------
  \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;
        PELOG1(limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME "));)
        limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD);
    }
/* 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
    else
    {
        limLog(pMac, LOGE,
            FL("Received SIR_HAL_MISSED_BEACON_IND while in incorrect state: %d"),
            pMac->pmm.gPmmState);
    }
    return;
}

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

    if (eHAL_STATUS_SUCCESS !=
                    palAllocateMemory(pMac->hHdd,
                                      (void **) &pSirSmeMicFailureInd,
                                      sizeof(tSirSmeMicFailureInd)))
    {
        // Log error
       limLog(pMac, LOGP,
               FL("memory allocate failed for eWNI_SME_MIC_FAILURE_IND"));
       return;
    }

    pSirSmeMicFailureInd->messageType = eWNI_SME_MIC_FAILURE_IND;
    pSirSmeMicFailureInd->length = sizeof(pSirSmeMicFailureInd);
    pSirSmeMicFailureInd->sessionId = psessionEntry->smeSessionId;

    vos_mem_copy(pSirSmeMicFailureInd->bssId,
        pSirMicFailureInd->bssId,
        sizeof(tSirMacAddr));

    vos_mem_copy(pSirSmeMicFailureInd->info.srcMacAddr,
        pSirMicFailureInd->info.srcMacAddr,
        sizeof(tSirMacAddr));

    vos_mem_copy(pSirSmeMicFailureInd->info.taMacAddr,
        pSirMicFailureInd->info.taMacAddr,
        sizeof(tSirMacAddr));

    vos_mem_copy(pSirSmeMicFailureInd->info.dstMacAddr,
        pSirMicFailureInd->info.dstMacAddr,
        sizeof(tSirMacAddr));

    vos_mem_copy(pSirSmeMicFailureInd->info.rxMacAddr,
        pSirMicFailureInd->info.rxMacAddr,
        sizeof(tSirMacAddr));

    pSirSmeMicFailureInd->info.multicast = 
                                   pSirMicFailureInd->info.multicast;

    pSirSmeMicFailureInd->info.keyId= 
                                  pSirMicFailureInd->info.keyId;

    pSirSmeMicFailureInd->info.IV1= 
                                  pSirMicFailureInd->info.IV1;

    vos_mem_copy(pSirSmeMicFailureInd->info.TSC,
         pSirMicFailureInd->info.TSC,SIR_CIPHER_SEQ_CTR_SIZE);

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


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

    /*
    * 
    * 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(pMac->pmm.inMissedBeaconScenario)
        {
            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);

   /* Note sure if this is sufficient, basically this condition allows all probe responses and 
    *   beacons from an infrastructure network 
    */
        *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET);
    if(!capabilityInfo.ibss)
        return eMGMT_DROP_NO_DROP;
#if 0
    //Allow the mgmt frames to be queued if STA not in IBSS mode.
    if (pMac->lim.gLimSystemRole != eLIM_STA_IN_IBSS_ROLE)
        return eMGMT_DROP_NO_DROP;
#endif

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

        //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)))
    {
        //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;
}

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