/*
 * Copyright (c) 2012-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 schBeaconProcess.cc contains beacon processing related
 * functions
 *
 * Author:      Sandesh Goel
 * Date:        02/25/02
 * History:-
 * Date            Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */

#include "palTypes.h"
#include "wniCfg.h"

#include "cfgApi.h"
#include "pmmApi.h"
#include "limApi.h"
#include "utilsApi.h"
#include "schDebug.h"
#include "schApi.h"


#include "limUtils.h"
#include "limSendMessages.h"
#include "limStaHashApi.h"

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

#ifdef FEATURE_WLAN_DIAG_SUPPORT
#include "vos_diag_core_log.h"
#endif //FEATURE_WLAN_DIAG_SUPPORT 

/**
 * Number of bytes of variation in beacon length from the last beacon
 * to trigger reprogramming of rx delay register
 */
#define SCH_BEACON_LEN_DELTA       3

// calculate 2^cw - 1
#define CW_GET(cw) (((cw) == 0) ? 1 : ((1 << (cw)) - 1))

static void
ap_beacon_process(
    tpAniSirGlobal    pMac,
    tANI_U8*      pRxPacketInfo,
    tpSchBeaconStruct pBcnStruct,
    tpUpdateBeaconParams pBeaconParams,
    tpPESession         psessionEntry)
{
    tpSirMacMgmtHdr    pMh = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
    tANI_U32           phyMode;
    tSirRFBand          rfBand = SIR_BAND_UNKNOWN;
    //Get RF band from psessionEntry
    rfBand = psessionEntry->limRFBand;

    limGetPhyMode(pMac, &phyMode, psessionEntry);

    if(SIR_BAND_5_GHZ == rfBand)
    {
        if (psessionEntry->htCapability)
        {
            if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel)
            {
              //11a (non HT) AP  overlaps or
              //HT AP with HT op mode as mixed overlaps.              
              //HT AP with HT op mode as overlap legacy overlaps.                            
              if ((!pBcnStruct->HTInfo.present) ||
                  (eSIR_HT_OP_MODE_MIXED == pBcnStruct->HTInfo.opMode) ||
                  (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBcnStruct->HTInfo.opMode))
              {
                   limUpdateOverlapStaParam(pMac, pMh->bssId, &(pMac->lim.gLimOverlap11aParams));

                  if (pMac->lim.gLimOverlap11aParams.numSta &&
                      !pMac->lim.gLimOverlap11aParams.protectionEnabled)
                  {
                      limEnable11aProtection(pMac, true, true, pBeaconParams,psessionEntry);
                  }
              }
              //HT AP with HT20 op mode overlaps.
              else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBcnStruct->HTInfo.opMode)
              {
                  limUpdateOverlapStaParam(pMac, pMh->bssId, &(pMac->lim.gLimOverlapHt20Params));

                  if (pMac->lim.gLimOverlapHt20Params.numSta &&
                      !pMac->lim.gLimOverlapHt20Params.protectionEnabled)
                  {
                      limEnableHT20Protection(pMac, true, true, pBeaconParams,psessionEntry);
                  }
              }
            }
        }    
    }
    else if(SIR_BAND_2_4_GHZ == rfBand)
    {
        //We are 11G AP.
        if ((phyMode == WNI_CFG_PHY_MODE_11G) &&
              (false == psessionEntry->htCapability))
        {
            if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel)        
            {
                if (((!(pBcnStruct->erpPresent)) && 
                      !(pBcnStruct->HTInfo.present))|| 
                    //if erp not present then  11B AP overlapping
                    (!pMac->roam.configParam.ignorePeerErpInfo &&
                      pBcnStruct->erpPresent &&
                    (pBcnStruct->erpIEInfo.useProtection ||
                    pBcnStruct->erpIEInfo.nonErpPresent)))
                {
#ifdef FEATURE_WLAN_ESE
                    if( psessionEntry->isESEconnection )
                    {
                        VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                            "%s: [INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d", __func__,
                            pBcnStruct->erpPresent,
                            pBcnStruct->erpIEInfo.useProtection,
                            pBcnStruct->erpIEInfo.nonErpPresent);
                    } 
#endif 
                    limEnableOverlap11gProtection(pMac, pBeaconParams, pMh,psessionEntry);
                }

            }
        }        
        // handling the case when HT AP has overlapping legacy BSS.
        else if(psessionEntry->htCapability)
        {             
            if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel)
            {
              if (((!(pBcnStruct->erpPresent)) && 
                    !(pBcnStruct->HTInfo.present))|| 
                  //if erp not present then  11B AP overlapping
                  (!pMac->roam.configParam.ignorePeerErpInfo &&
                    pBcnStruct->erpPresent &&
                  (pBcnStruct->erpIEInfo.useProtection ||
                  pBcnStruct->erpIEInfo.nonErpPresent)))
              {
#ifdef FEATURE_WLAN_ESE
                  if( psessionEntry->isESEconnection )
                  {
                      VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                          "%s: [INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d", __func__,
                          pBcnStruct->erpPresent,
                          pBcnStruct->erpIEInfo.useProtection,
                          pBcnStruct->erpIEInfo.nonErpPresent);
                  }  
#endif 
                  limEnableOverlap11gProtection(pMac, pBeaconParams, pMh,psessionEntry);
              }

              //11g device overlaps
              if (pBcnStruct->erpPresent &&
                  !(pBcnStruct->erpIEInfo.useProtection || 
                    pBcnStruct->erpIEInfo.nonErpPresent) && !(pBcnStruct->HTInfo.present))
              {
                    limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlap11gParams));

                  if (psessionEntry->gLimOverlap11gParams.numSta && 
                      !psessionEntry->gLimOverlap11gParams.protectionEnabled)
                  {
                      limEnableHtProtectionFrom11g(pMac, true, true, pBeaconParams,psessionEntry);
                  }
              }

              //ht device overlaps.
              //here we will check for HT related devices only which might need protection.
              //check for 11b and 11g is already done in the previous blocks.
              //so we will not check for HT operating mode as MIXED.
              if (pBcnStruct->HTInfo.present)
              {
                  //if we are not already in mixed mode or legacy mode as HT operating mode
                  //and received beacon has HT operating mode as legacy
                  //then we need to enable protection from 11g station. 
                  //we don't need protection from 11b because if that's needed then our operating
                  //mode would have already been set to legacy in the previous blocks.
                  if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBcnStruct->HTInfo.opMode
                     && !pMac->roam.configParam.ignorePeerHTopMode)
                  {
                      if((eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) &&
                          (eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode))
                      {
                          limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlap11gParams));
                          if (psessionEntry->gLimOverlap11gParams.numSta &&
                              !psessionEntry->gLimOverlap11gParams.protectionEnabled)
                          {
                              limEnableHtProtectionFrom11g(pMac, true, true, pBeaconParams,psessionEntry);
                          }
                      }
                  }           
                  else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBcnStruct->HTInfo.opMode)
                  {
                      limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlapHt20Params));
                      if (psessionEntry->gLimOverlapHt20Params.numSta &&
                          !psessionEntry->gLimOverlapHt20Params.protectionEnabled)
                      {
                          limEnableHT20Protection(pMac, true, true, pBeaconParams,psessionEntry);
                      }
                  }
              }
              
            }
        }     
    }
    pMac->sch.gSchBcnIgnored++;
}
// --------------------------------------------------------------------




/**
 * __schBeaconProcessNoSession
 *
 * FUNCTION:
 * Process the received beacon frame when 
 *  -- Station is not scanning 
 *  -- No corresponding session is found
 *
 * LOGIC:
 *        Following scenarios exist when Session Does not exist:
 *             * IBSS Beacons, when IBSS session already exists with same SSID, 
 *                but from STA which has not yet joined and has a different BSSID.
 *                - invoke limHandleIBSScoalescing with the session context of existing IBSS session.
 *
 *             * IBSS Beacons when IBSS session does not exist, only Infra or BT-AMP session exists,
 *                then save the beacon in the scan results and throw it away.
 *                
 *             * Infra Beacons
 *                - beacons received when no session active 
 *                    should not come here, it should be handled as part of scanning, 
 *                    else they should not be getting received, should update scan results and drop it if that happens.
 *                - beacons received when IBSS session active:
 *                    update scan results and drop it.
 *                - beacons received when Infra session(STA) is active:
 *                    update scan results and drop it
 *                - beacons received when BT-STA session is active:
 *                    update scan results and drop it.
 *                - beacons received when Infra/BT-STA  or Infra/IBSS is active.
 *                    update scan results and drop it.
 * 

 */
static void __schBeaconProcessNoSession(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon,tANI_U8* pRxPacketInfo)
{
    tpPESession psessionEntry = NULL;
 
    if(  (psessionEntry = limIsIBSSSessionActive(pMac)) != NULL)
    {
        limHandleIBSScoalescing(pMac, pBeacon, pRxPacketInfo, psessionEntry);
    }

    //If station(STA/BT-STA/BT-AP/IBSS) mode, Always save the beacon in the scan results, if atleast one session is active
    //schBeaconProcessNoSession will be called only when there is atleast one session active, so not checking 
    //it again here.
    if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || pMac->fScanOffload)
        limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo,
                                     eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE);

    return;  
}



/*
 * __schBeaconProcessForSession
 *
 * FUNCTION:
 * Process the received beacon frame when 
 *  -- Station is not scanning 
 *  -- Corresponding session is found
 *
 * LOGIC:
 *        Following scenarios exist when Session exists
 *             * IBSS STA receving beacons from IBSS Peers, who are part of IBSS.
 *                 - call limHandleIBSScoalescing with that session context.
 *             * Infra STA receving beacons from AP to which it is connected
 *                 - call schBeaconProcessFromAP with that session's context.
 *             * BTAMP STA receving beacons from BTAMP AP
 *                 - call schBeaconProcessFromAP with that session's context.
 *             * BTAMP AP receiving beacons from BTAMP STA 
 *               (here need to make sure BTAP creates session entry for BT STA)
 *                - just update the beacon count for heart beat purposes for now, 
 *                  for now, don't process the beacon.
 *             * Infra/IBSS both active and receives IBSS beacon:
 *                  - call limHandleIBSScoalescing with that session context.
 *             * Infra/IBSS both active and receives Infra beacon:
 *                  - call schBeaconProcessFromAP with that session's context.
 *                     any updates to EDCA parameters will be effective for IBSS as well, 
 *                     even though no WMM for IBSS ?? Need to figure out how to handle this scenario.
 *             * Infra/BTSTA both active and receive Infra beacon.
 *                  - change in EDCA parameters on Infra affect the BTSTA link.
 *                     Update the same parameters on BT link
 *              * Infra/BTSTA both active and receive BT-AP beacon.
 *                 -update beacon cnt for heartbeat
 *             * Infra/BTAP both active and receive Infra beacon.
 *                 - BT-AP starts advertising BE parameters from Infra AP, if they get changed.
 *
 *             * Infra/BTAP both active and receive BTSTA beacon.
 *                - update beacon cnt for heartbeat
 */

static void __schBeaconProcessForSession( tpAniSirGlobal      pMac,
                                                                     tpSchBeaconStruct   pBeacon,
                                                                     tANI_U8* pRxPacketInfo,    
                                                                     tpPESession psessionEntry)
{
    tANI_U32                     bi;
    tANI_U8 bssIdx = 0;
    //tpSirMacMgmtHdr         pMh = SIR_MAC_BD_TO_MPDUHEADER(pRxPacketInfo);
    //tANI_U8 bssid[sizeof(tSirMacAddr)];
    tUpdateBeaconParams beaconParams;
    tANI_U8 sendProbeReq = FALSE;
    tpDphHashNode pStaDs = NULL;
    tANI_U32   channelBondingMode = 0;
#ifdef WLAN_FEATURE_11AC
    tpSirMacMgmtHdr    pMh = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
    tANI_U16  aid;
    tANI_U8  operMode;
    tANI_U8  chWidth = 0;
#endif
#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI
     tPowerdBm regMax = 0,maxTxPower = 0;
#endif

    vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
    beaconParams.paramChangeBitmap = 0;

    if(eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole )
    {
        if( limHandleIBSScoalescing(pMac, pBeacon, pRxPacketInfo, psessionEntry)
                                                               != eSIR_SUCCESS )
            return;
    }
    else if(  (eLIM_STA_ROLE == psessionEntry->limSystemRole) || 
                  (eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole))
    {
        /*
        *  This handles two cases:
        *  -- Infra STA receving beacons from AP  
        *  -- BTAMP_STA receving beacons from BTAMP_AP
        */
        //Always save the beacon into LIM's cached scan results
        limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE);

        /**
               * This is the Beacon received from the AP  we're currently associated with. Check
               * if there are any changes in AP's capabilities 
               */
        if((tANI_U8) pBeacon->channelNumber != psessionEntry->currentOperChannel)
        {
            PELOGE(schLog(pMac, LOGE, FL("Channel Change from %d --> %d  - "
                                         "Ignoring beacon!"),
                          psessionEntry->currentOperChannel, pBeacon->channelNumber);)
           goto fail;
        }

        if (psessionEntry->gLimSpecMgmt.dfs_channel_csa) {
           limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
           psessionEntry->gLimSpecMgmt.dfs_channel_csa = false;
        }

        if(RF_CHAN_14 >= psessionEntry->currentOperChannel)
        {
            if (psessionEntry->force_24ghz_in_ht20)
                channelBondingMode =
                     WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
            else
                channelBondingMode =
                     pMac->roam.configParam.channelBondingMode24GHz;
        }
        else
        {
           channelBondingMode = pMac->roam.configParam.channelBondingMode5GHz;
        }

        limDetectChangeInApCapabilities(pMac, pBeacon, psessionEntry);
        if(limGetStaHashBssidx(pMac, DPH_STA_HASH_INDEX_PEER, &bssIdx, psessionEntry) != eSIR_SUCCESS)
            goto fail;
        beaconParams.bssIdx = bssIdx;
        vos_mem_copy(( tANI_U8* )&psessionEntry->lastBeaconTimeStamp,
                     ( tANI_U8* )pBeacon->timeStamp, sizeof(tANI_U64));
        psessionEntry->lastBeaconDtimCount = pBeacon->tim.dtimCount;
        psessionEntry->lastBeaconDtimPeriod= pBeacon->tim.dtimPeriod;
        psessionEntry->currentBssBeaconCnt++;



        MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, psessionEntry->peSessionId, pBeacon->timeStamp[0]);)
        MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, psessionEntry->peSessionId, pBeacon->timeStamp[1]);)

        /* Read beacon interval session Entry */
        bi = psessionEntry->beaconParams.beaconInterval;
        if (bi != pBeacon->beaconInterval)
        {
           schLog(pMac, LOG1, FL("Beacon interval changed from %d to %d"),
                   pBeacon->beaconInterval, bi);

            bi = pBeacon->beaconInterval;
            psessionEntry->beaconParams.beaconInterval = (tANI_U16) bi;
            beaconParams.paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED;
            beaconParams.beaconInterval = (tANI_U16)bi;
        }

        if (pBeacon->cfPresent)
        {
            cfgSetInt(pMac, WNI_CFG_CFP_PERIOD, pBeacon->cfParamSet.cfpPeriod);
            limSendCFParams(pMac, bssIdx, pBeacon->cfParamSet.cfpCount, pBeacon->cfParamSet.cfpPeriod);
        }

        if (pBeacon->timPresent)
        {
            cfgSetInt(pMac, WNI_CFG_DTIM_PERIOD, pBeacon->tim.dtimPeriod);
            //No need to send DTIM Period and Count to HAL/SMAC
            //SMAC already parses TIM bit.
        }

        if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)

        limDecideStaProtection(pMac, pBeacon, &beaconParams, psessionEntry);
        if (pBeacon->erpPresent)
        {
            if (pBeacon->erpIEInfo.barkerPreambleMode)
                limEnableShortPreamble(pMac, false, &beaconParams, psessionEntry);
            else
                limEnableShortPreamble(pMac, true, &beaconParams, psessionEntry);
          }
        limUpdateShortSlot(pMac, pBeacon, &beaconParams,psessionEntry);

        pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
        if ((pBeacon->wmeEdcaPresent && (psessionEntry->limWmeEnabled)) ||
             (pBeacon->edcaPresent    && (psessionEntry->limQosEnabled)))
        {
            if(pBeacon->edcaParams.qosInfo.count != psessionEntry->gLimEdcaParamSetCount)
            {
                if (schBeaconEdcaProcess(pMac, &pBeacon->edcaParams, psessionEntry) != eSIR_SUCCESS)
                    PELOGE(schLog(pMac, LOGE, FL("EDCA parameter processing error"));)
                else if(pStaDs != NULL)
                {
                    // If needed, downgrade the EDCA parameters
                    limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); 

                    if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
                        limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
                    else
                        limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
                }
                else
                    PELOGE(schLog(pMac, LOGE, FL("Self Entry missing in Hash Table"));)
            }
        }
        else if( (pBeacon->qosCapabilityPresent && psessionEntry->limQosEnabled) &&
            (pBeacon->qosCapability.qosInfo.count != psessionEntry->gLimEdcaParamSetCount))
            sendProbeReq = TRUE;
    }

    if ( psessionEntry->htCapability && pBeacon->HTInfo.present &&
                                  (!LIM_IS_IBSS_ROLE(psessionEntry)))
    {
        limUpdateStaRunTimeHTSwitchChnlParams( pMac, &pBeacon->HTInfo, bssIdx,psessionEntry);
    }

    if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ||
          (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) )
    {
        /* Channel Switch information element updated */
        if(pBeacon->channelSwitchPresent ||
            pBeacon->propIEinfo.propChannelSwitchPresent ||
            pBeacon->ecsa_present)
        {
            limUpdateChannelSwitch(pMac, pBeacon, psessionEntry);
        }
        else if (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING)
        {
            limCancelDot11hChannelSwitch(pMac, psessionEntry);
        }
        // check for HT capability
        pStaDs = dphLookupHashEntry(pMac, pMh->sa, &aid,
                                    &psessionEntry->dph.dphHashTable);
        /* Update the channel bonding mode only if channel bonding
         * mode is enabled in INI.
         */
        if ( (pStaDs != NULL) && (HAL_STA_INVALID_IDX != pStaDs->staIndex ) &&
              (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != channelBondingMode) )
        {
           /* Following check is related to HT40 on 2.4GHz mode*/
           if ((pStaDs->htSecondaryChannelOffset !=
                pBeacon->HTInfo.secondaryChannelOffset) &&
                (IS_HT40_OBSS_SCAN_FEATURE_ENABLE) &&
                (psessionEntry->currentOperChannel <= RF_CHAN_14))
           {
               VOS_TRACE( VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                        FL(" Current Secondarychanoffset %d received "
                        " secondaryChannelOffset %d, staIdx = %d"),
                        pStaDs->htSecondaryChannelOffset,
                        pBeacon->HTInfo.secondaryChannelOffset,
                        pStaDs->staIndex);
              if (eANI_BOOLEAN_TRUE ==(limCheckHTChanBondModeChange(pMac,
                                              psessionEntry,
                                              pBeacon->HTInfo.secondaryChannelOffset,
                                              pStaDs->htSecondaryChannelOffset,
                                              pStaDs->staIndex)))
              {
                  pStaDs->htSupportedChannelWidthSet =
                             pBeacon->HTInfo.recommendedTxWidthSet;
                  pStaDs->htSecondaryChannelOffset =
                             pBeacon->HTInfo.secondaryChannelOffset;
                  limUpdateMaxRateFlag(pMac, psessionEntry->smeSessionId,
                                       limGetMaxRateFlags(pStaDs, psessionEntry));
              }
           }
        }
        else
           schLog(pMac, LOG1,
                  FL("Self Entry missing in Hash Table or channel bonding mode is disabled"));
    }
    /* TODO : Below condition checks can be merged with the if */
#ifdef WLAN_FEATURE_11AC
    if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
        (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ||
        (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE))
    {
       // check for VHT capability
       pStaDs = dphLookupHashEntry(pMac, pMh->sa, &aid,
             &psessionEntry->dph.dphHashTable);

       /* Update the channel bonding mode only if channel bonding
        * mode is enabled in INI.
        */
       if ( (NULL != pStaDs) && (HAL_STA_INVALID_IDX != pStaDs->staIndex ) &&
            (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != channelBondingMode) )
       {
          if (psessionEntry->vhtCapability && pBeacon->OperatingMode.present )
          {
             operMode = pStaDs->vhtSupportedChannelWidthSet ?
                eHT_CHANNEL_WIDTH_80MHZ :
                pStaDs->htSupportedChannelWidthSet ?
                eHT_CHANNEL_WIDTH_40MHZ: eHT_CHANNEL_WIDTH_20MHZ;
             if (operMode != pBeacon->OperatingMode.chanWidth)
             {
                   schLog(pMac, LOG1,
                         FL(" received OpMode Chanwidth %d, staIdx = %d"),
                         pBeacon->OperatingMode.chanWidth,
                         pStaDs->staIndex);
                   schLog(pMac, LOG1, FL(" MAC -" MAC_ADDRESS_STR),
                                              MAC_ADDR_ARRAY(pMh->sa));

                   if (pBeacon->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ)
                   {
                      schLog(pMac, LOG1,
                               FL("Updating the CH Width to 80MHz"));
                         pStaDs->vhtSupportedChannelWidthSet =
                         WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
                      pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
                   }
                   else if (pBeacon->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_40MHZ)
                   {
                      schLog(pMac, LOG1,
                               FL("Updating the CH Width to 40MHz"));
                         pStaDs->vhtSupportedChannelWidthSet =
                         WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                      pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
                   }
                   else if (pBeacon->OperatingMode.chanWidth ==
                         eHT_CHANNEL_WIDTH_20MHZ)
                   {
                      schLog(pMac, LOG1,
                               FL("Updating the CH Width to 20MHz"));
                         pStaDs->vhtSupportedChannelWidthSet =
                         WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                      pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
                   }
                limCheckVHTOpModeChange(pMac, psessionEntry,
                      pBeacon->OperatingMode.chanWidth,
                      pStaDs->staIndex);
             }
          }
          else if (psessionEntry->vhtCapability && pBeacon->VHTOperation.present)
          {
             operMode = pStaDs->vhtSupportedChannelWidthSet;
             if (operMode != pBeacon->VHTOperation.chanWidth)
             {
                   schLog(pMac, LOG1,
                         FL(" received VHTOP CHWidth %d staIdx = %d"),
                         pBeacon->VHTOperation.chanWidth,
                         pStaDs->staIndex);
                   schLog(pMac, LOG1, FL(" MAC -" MAC_ADDRESS_STR),
                                            MAC_ADDR_ARRAY(pMh->sa));

                   if (pBeacon->VHTOperation.chanWidth ==
                         WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
                   {
                      schLog(pMac, LOG1,
                               FL("Updating the CH Width to 80MHz"));
                         pStaDs->vhtSupportedChannelWidthSet =
                         WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
                      pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
                      chWidth = eHT_CHANNEL_WIDTH_80MHZ;
                   }
                   else if (pBeacon->VHTOperation.chanWidth ==
                         WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ)
                   {
                      pStaDs->vhtSupportedChannelWidthSet =
                         WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
                      if (pBeacon->HTCaps.supportedChannelWidthSet)
                      {
                         schLog(pMac, LOG1,
                                  FL("Updating the CH Width to 40MHz"));
                            pStaDs->htSupportedChannelWidthSet =
                            eHT_CHANNEL_WIDTH_40MHZ;
                         chWidth = eHT_CHANNEL_WIDTH_40MHZ;
                      }
                      else
                      {
                         schLog(pMac, LOG1,
                                  FL("Updating the CH Width to 20MHz"));
                            pStaDs->htSupportedChannelWidthSet =
                            eHT_CHANNEL_WIDTH_20MHZ;
                         chWidth = eHT_CHANNEL_WIDTH_20MHZ;
                      }
                   }
                limCheckVHTOpModeChange(pMac, psessionEntry,
                      chWidth, pStaDs->staIndex);
             }
          }
       }
    }
#endif

#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI)
    /* Obtain the Max Tx power for the current regulatory  */
    regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel );
#endif
#if defined WLAN_FEATURE_VOWIFI
    {
        tPowerdBm  localRRMConstraint = 0;
        if ( pMac->rrm.rrmPEContext.rrmEnable && pBeacon->powerConstraintPresent )
        {
            localRRMConstraint = pBeacon->localPowerConstraint.localPowerConstraints;
        }
        else
        {
            localRRMConstraint = 0;
        }
        maxTxPower =  limGetMaxTxPower(regMax, regMax - localRRMConstraint,
                                     pMac->roam.configParam.nTxPowerCap);
    }
#elif defined FEATURE_WLAN_ESE
    maxTxPower = regMax;
#endif

#if defined FEATURE_WLAN_ESE
    if( psessionEntry->isESEconnection )
    {
        tPowerdBm  localESEConstraint = 0;
        if (pBeacon->eseTxPwr.present)
        {
            localESEConstraint = pBeacon->eseTxPwr.power_limit;
            maxTxPower = limGetMaxTxPower(maxTxPower, localESEConstraint, pMac->roam.configParam.nTxPowerCap);
        }
        schLog( pMac, LOG1, "RegMax = %d, localESECons = %d, MaxTx = %d", regMax, localESEConstraint, maxTxPower );
    }
#endif

#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI)
    {
        //If maxTxPower is increased or decreased
        if( maxTxPower != psessionEntry->maxTxPower )
        {
             schLog( pMac, LOG1, "Local power constraint change..updating new maxTx power %d to HAL",maxTxPower);
             if( limSendSetMaxTxPowerReq ( pMac, maxTxPower, psessionEntry ) == eSIR_SUCCESS )
                   psessionEntry->maxTxPower = maxTxPower;
        }
    }
#endif

    // Indicate to LIM that Beacon is received

    if (pBeacon->HTInfo.present)
        limReceivedHBHandler(pMac, (tANI_U8)pBeacon->HTInfo.primaryChannel, psessionEntry);
    else
        limReceivedHBHandler(pMac, (tANI_U8)pBeacon->channelNumber, psessionEntry);

    // I don't know if any additional IE is required here. Currently, not include addIE.
    if(sendProbeReq)
        limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId,
            psessionEntry->bssId, psessionEntry->currentOperChannel,psessionEntry->selfMacAddr,
            psessionEntry->dot11mode, 0, NULL);

    if(beaconParams.paramChangeBitmap)
    {
        schLog(pMac, LOGW, FL("Beacon for session[%d] got changed. "), psessionEntry->peSessionId);
        schLog(pMac, LOGW, FL("sending beacon param change bitmap: 0x%x "), beaconParams.paramChangeBitmap);
        limSendBeaconParams(pMac, &beaconParams, psessionEntry);
    }

fail:
    return;

}

/**
 * schBeaconProcess
 *
 * FUNCTION:
 * Process the received beacon frame
 *
 * LOGIC:
  *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param pRxPacketInfo pointer to buffer descriptor
 * @return None
 */
 
void schBeaconProcess(tpAniSirGlobal pMac, tANI_U8* pRxPacketInfo, tpPESession psessionEntry)
{
    static tSchBeaconStruct beaconStruct;
    tUpdateBeaconParams beaconParams;
    tpPESession pAPSession = NULL;
    vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
    beaconParams.paramChangeBitmap = 0;

    pMac->sch.gSchBcnRcvCnt++;

    // Convert the beacon frame into a structure
    if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, &beaconStruct)!= eSIR_SUCCESS)
    {
        schLog(pMac, LOGE, FL("beacon parsing failed"));
        pMac->sch.gSchBcnParseErrorCnt++;

        if ((NULL != psessionEntry) && (!psessionEntry->currentBssBeaconCnt))
            limParseBeaconForTim(pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry);

        return;
    }

    /*
    * First process the beacon in the context of any existing AP or BTAP session.
    * This takes cares of following two scenarios:
    *  - psessionEntry = NULL:  
    *      e.g. beacon received from a neighboring BSS, you want to apply the protection settings to BTAP/InfraAP beacons
    *  - psessionEntry is non NULL: 
    *      e.g. beacon received is from the INFRA AP to which you are connected on another concurrent link.
    *      In this case also, we want to apply the protection settings(as advertised by Infra AP) to BTAP beacons
    * 
    * 
    */
    
    if (((pAPSession = limIsApSessionActive(pMac)) != NULL)
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
          && (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)))
#endif
    )
    {
        beaconParams.bssIdx = pAPSession->bssIdx;
        if (pAPSession->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
            ap_beacon_process(pMac,  pRxPacketInfo, &beaconStruct, &beaconParams, pAPSession);

        if (beaconParams.paramChangeBitmap)
        {
            //Update the beacons and apply the new settings to HAL
            schSetFixedBeaconFields(pMac, pAPSession);
            schLog(pMac, LOG1, FL("Beacon for PE session[%d] got changed."),
                                                      pAPSession->peSessionId);
            schLog(pMac, LOG1, FL("sending beacon param change bitmap: 0x%x "),
                                               beaconParams.paramChangeBitmap);
            limSendBeaconParams(pMac, &beaconParams, pAPSession);
        }
    }

    /*
    * Now process the beacon in the context of the BSS which is transmitting the beacons, if one is found
    */
    if(psessionEntry == NULL)
    {
        __schBeaconProcessNoSession(pMac,   &beaconStruct, pRxPacketInfo );   
    }
    else
    {
        __schBeaconProcessForSession(pMac,   &beaconStruct, pRxPacketInfo, psessionEntry );   
    }

}





// --------------------------------------------------------------------
/**
 * schBeaconEdcaProcess
 *
 * FUNCTION:
 * Process the EDCA parameter set in the received beacon frame
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param edca reference to edca parameters in beacon struct
 * @return success
 */

tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry)
{
    tANI_U8 i;
#ifdef FEATURE_WLAN_DIAG_SUPPORT
    vos_log_qos_edca_pkt_type *log_ptr = NULL;
#endif //FEATURE_WLAN_DIAG_SUPPORT 

    schLog(pMac, LOG2, FL("Updating parameter set count: Old %d ---> new %d"),
           psessionEntry->gLimEdcaParamSetCount, edca->qosInfo.count);

    psessionEntry->gLimEdcaParamSetCount = edca->qosInfo.count;
    psessionEntry->gLimEdcaParams[EDCA_AC_BE] = edca->acbe;
    psessionEntry->gLimEdcaParams[EDCA_AC_BK] = edca->acbk;
    psessionEntry->gLimEdcaParams[EDCA_AC_VI] = edca->acvi;
    psessionEntry->gLimEdcaParams[EDCA_AC_VO] = edca->acvo;

    if (pMac->roam.configParam.enable_edca_params) {
        psessionEntry->gLimEdcaParams[EDCA_AC_VO].aci.aifsn =
               pMac->roam.configParam.edca_vo_aifs;
        psessionEntry->gLimEdcaParams[EDCA_AC_VI].aci.aifsn =
               pMac->roam.configParam.edca_vi_aifs;
        psessionEntry->gLimEdcaParams[EDCA_AC_BK].aci.aifsn =
               pMac->roam.configParam.edca_bk_aifs;
        psessionEntry->gLimEdcaParams[EDCA_AC_BE].aci.aifsn =
               pMac->roam.configParam.edca_be_aifs;

        psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.min =
               pMac->roam.configParam.edca_vo_cwmin;
        psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.min =
               pMac->roam.configParam.edca_vi_cwmin;
        psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.min =
               pMac->roam.configParam.edca_bk_cwmin;
        psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.min =
               pMac->roam.configParam.edca_be_cwmin;

        psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.max =
               pMac->roam.configParam.edca_vo_cwmax;
        psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.max =
               pMac->roam.configParam.edca_vi_cwmax;
        psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.max =
               pMac->roam.configParam.edca_bk_cwmax;
        psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.max =
               pMac->roam.configParam.edca_be_cwmax;
    }
//log: LOG_WLAN_QOS_EDCA_C
#ifdef FEATURE_WLAN_DIAG_SUPPORT
    WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C);
    if(log_ptr)
    {
       log_ptr->aci_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].aci.aci;
       log_ptr->cw_be  = psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.max << 4 |
          psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.min;
       log_ptr->txoplimit_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].txoplimit;
       log_ptr->aci_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].aci.aci;
       log_ptr->cw_bk  = psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.max << 4 |
          psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.min;
       log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].txoplimit;
       log_ptr->aci_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].aci.aci;
       log_ptr->cw_vi  = psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.max << 4 |
          psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.min;
       log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].txoplimit;
       log_ptr->aci_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].aci.aci;
       log_ptr->cw_vo  = psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.max << 4 |
          psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.min;
       log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].txoplimit;
    }
    WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
#endif //FEATURE_WLAN_DIAG_SUPPORT
    schLog(pMac, LOG1,
           FL("edsa param enabled in ini %d. Updating Local EDCA Params(gLimEdcaParams) to: "),
           pMac->roam.configParam.enable_edca_params);
    for(i=0; i<MAX_NUM_AC; i++)
    {
        schLog(pMac, LOG1, FL("AC[%d]:  AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d"),
            i,
            psessionEntry->gLimEdcaParams[i].aci.aifsn, 
            psessionEntry->gLimEdcaParams[i].aci.acm,
            psessionEntry->gLimEdcaParams[i].cw.min,
            psessionEntry->gLimEdcaParams[i].cw.max,
            psessionEntry->gLimEdcaParams[i].txoplimit);
    }

    return eSIR_SUCCESS;
}
