/*
 * 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 limProcessMlmMessages.cc contains the code
 * for processing MLM request messages.
 * Author:        Chandra Modumudi
 * Date:          02/12/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */
#include "palTypes.h"
#ifdef ANI_PRODUCT_TYPE_AP
#include "wniCfgAp.h"
#else
#include "wniCfgSta.h"
#endif
#include "aniGlobal.h"
#include "sirApi.h"
#include "sirParams.h"
#include "cfgApi.h"

#include "schApi.h"
#include "utilsApi.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limPropExtsUtils.h"
#include "limSecurityUtils.h"
#include "limSendMessages.h"
#include "pmmApi.h"
#include "limSendMessages.h"
//#include "limSessionUtils.h"
#include "limSessionUtils.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include <limFT.h>
#endif



// MLM REQ processing function templates
static void limProcessMlmStartReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmScanReq(tpAniSirGlobal, tANI_U32 *);
#ifdef FEATURE_OEM_DATA_SUPPORT
static void limProcessMlmOemDataReq(tpAniSirGlobal, tANI_U32 *);
#endif
static void limProcessMlmJoinReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmAuthReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmAssocReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmReassocReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmDisassocReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmDeauthReq(tpAniSirGlobal, tANI_U32 *);
static void limProcessMlmSetKeysReq(tpAniSirGlobal, tANI_U32 *);

static void limProcessMlmAddBAReq( tpAniSirGlobal, tANI_U32 * );
static void limProcessMlmAddBARsp( tpAniSirGlobal, tANI_U32 * );
static void limProcessMlmDelBAReq( tpAniSirGlobal, tANI_U32 * );

// MLM Timeout event handler templates
static void limProcessMinChannelTimeout(tpAniSirGlobal);
static void limProcessMaxChannelTimeout(tpAniSirGlobal);
static void limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac);
static void limProcessJoinFailureTimeout(tpAniSirGlobal);
static void limProcessAuthFailureTimeout(tpAniSirGlobal);
static void limProcessAuthRspTimeout(tpAniSirGlobal, tANI_U32);
static void limProcessAssocFailureTimeout(tpAniSirGlobal, tANI_U32);

static void limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf);
void 
limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId);
#define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac)    (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_AGGRESSIVE_BACKGROUND_SCAN)


/**
 * limProcessMlmReqMessages()
 *
 *FUNCTION:
 * This function is called by limPostMlmMessage(). This
 * function handles MLM primitives invoked by SME.
 *
 *LOGIC:
 * Depending on the message type, corresponding function will be
 * called.
 *
 *ASSUMPTIONS:
 * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes
 *    APIs exposed by Beacon Processing module for setting parameters
 *    at MAC hardware.
 * 2. If attempt to Reassociate with an AP fails, link with current
 *    AP is restored back.
 *
 *NOTE:
 *
 * @param pMac      Pointer to Global MAC structure
 * @param msgType   Indicates the MLM primitive message type
 * @param *pMsgBuf  A pointer to the MLM message buffer
 *
 * @return None
 */

void
limProcessMlmReqMessages(tpAniSirGlobal pMac, tpSirMsgQ Msg)
{
    switch (Msg->type)
    {
        case LIM_MLM_START_REQ:             limProcessMlmStartReq(pMac, Msg->bodyptr);   break;
        case LIM_MLM_SCAN_REQ:              limProcessMlmScanReq(pMac, Msg->bodyptr);    break;
#ifdef FEATURE_OEM_DATA_SUPPORT
        case LIM_MLM_OEM_DATA_REQ: limProcessMlmOemDataReq(pMac, Msg->bodyptr); break;
#endif
        case LIM_MLM_JOIN_REQ:              limProcessMlmJoinReq(pMac, Msg->bodyptr);    break;
        case LIM_MLM_AUTH_REQ:              limProcessMlmAuthReq(pMac, Msg->bodyptr);    break;
        case LIM_MLM_ASSOC_REQ:             limProcessMlmAssocReq(pMac, Msg->bodyptr);   break;
        case LIM_MLM_REASSOC_REQ:           limProcessMlmReassocReq(pMac, Msg->bodyptr); break;
        case LIM_MLM_DISASSOC_REQ:          limProcessMlmDisassocReq(pMac, Msg->bodyptr);  break;
        case LIM_MLM_DEAUTH_REQ:            limProcessMlmDeauthReq(pMac, Msg->bodyptr);  break;
        case LIM_MLM_SETKEYS_REQ:           limProcessMlmSetKeysReq(pMac, Msg->bodyptr);  break;
        case LIM_MLM_REMOVEKEY_REQ:         limProcessMlmRemoveKeyReq(pMac, Msg->bodyptr); break;
        case SIR_LIM_MIN_CHANNEL_TIMEOUT:   limProcessMinChannelTimeout(pMac);  break;
        case SIR_LIM_MAX_CHANNEL_TIMEOUT:   limProcessMaxChannelTimeout(pMac);  break;
        case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
                               limProcessPeriodicProbeReqTimer(pMac);  break;
        case SIR_LIM_JOIN_FAIL_TIMEOUT:     limProcessJoinFailureTimeout(pMac);  break;
        case SIR_LIM_AUTH_FAIL_TIMEOUT:     limProcessAuthFailureTimeout(pMac);  break;
        case SIR_LIM_AUTH_RSP_TIMEOUT:      limProcessAuthRspTimeout(pMac, Msg->bodyval);  break;
        case SIR_LIM_ASSOC_FAIL_TIMEOUT:    limProcessAssocFailureTimeout(pMac, Msg->bodyval);  break;
#ifdef WLAN_FEATURE_VOWIFI_11R
        case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:limProcessFTPreauthRspTimeout(pMac); break;
#endif
#ifdef WLAN_FEATURE_P2P
        case SIR_LIM_REMAIN_CHN_TIMEOUT:    limProcessRemainOnChnTimeout(pMac); break;
#endif
        case LIM_MLM_ADDBA_REQ:             limProcessMlmAddBAReq( pMac, Msg->bodyptr ); break;
        case LIM_MLM_ADDBA_RSP:             limProcessMlmAddBARsp( pMac, Msg->bodyptr ); break;
        case LIM_MLM_DELBA_REQ:             limProcessMlmDelBAReq( pMac, Msg->bodyptr ); break;
        case LIM_MLM_TSPEC_REQ:                 
        default:
            break;
    } // switch (msgType)
} /*** end limProcessMlmReqMessages() ***/


/**
 * limSetScanMode()
 *
 *FUNCTION:
 * This function is called to setup system into Scan mode
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @return None
 */

void
limSetScanMode(tpAniSirGlobal pMac)
{
    tSirLinkTrafficCheck checkTraffic;

    /// Set current scan channel id to the first in the channel list
    pMac->lim.gLimCurrentScanChannelId = 0;

#ifdef ANI_PRODUCT_TYPE_CLIENT         
       if ( IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) )
           checkTraffic = eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN;
       else 
           checkTraffic = eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN;
#else
            /* Currently checking the traffic before scan for Linux station. This is because MLM
             * scan request is not filled as scan is received via Measurement req in Linux. This
             * should be made as common code for Windows/Linux station once the scan requests are
             * enabled in Linux
             * TODO */
            checkTraffic = eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN;
#endif

    PELOG1(limLog(pMac, LOG1, FL("Calling limSendHalInitScanReq\n"));)
    limSendHalInitScanReq(pMac, eLIM_HAL_INIT_SCAN_WAIT_STATE, checkTraffic);

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

//WLAN_SUSPEND_LINK Related

/* limIsLinkSuspended()
 *
 *FUNCTION:
 * This function returns is link is suspended or not.
 *
 *LOGIC:
 * Since Suspen link uses init scan, it just returns 
 *                    gLimSystemInScanLearnMode flag. 
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @return None
 */
tANI_U8
limIsLinkSuspended(tpAniSirGlobal pMac)
{
    return pMac->lim.gLimSystemInScanLearnMode; 
}
/**
 * limSuspendLink()
 *
 *FUNCTION:
 * This function is called to suspend traffic. Internally this function uses WDA_INIT_SCAN_REQ.
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @param trafficCheck - Takes value from enum tSirLinkTrafficCheck. 
 * @param callback - Callback function to be called after suspending the link.
 * @param data - Pointer to any buffer that will be passed to callback.
 * @return None
 */
void
limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck,  SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data)
{
   if( NULL == callback )
   {
      limLog( pMac, LOGE, "%s:%d: Invalid parameters\n", __FUNCTION__, __LINE__ );
      return;
   }

   if( pMac->lim.gpLimSuspendCallback )
   {
      limLog( pMac, LOGE, "%s:%d: gLimSuspendLink callback is not NULL...something is wrong\n", __FUNCTION__, __LINE__ );
      callback( pMac, eHAL_STATUS_FAILURE, data ); 
      return;
   }

   pMac->lim.gLimSystemInScanLearnMode = 1;
   pMac->lim.gpLimSuspendCallback = callback;
   pMac->lim.gpLimSuspendData = data;
   limSendHalInitScanReq(pMac, eLIM_HAL_SUSPEND_LINK_WAIT_STATE, trafficCheck );
}

/**
 * limResumeLink()
 *
 *FUNCTION:
 * This function is called to Resume traffic after a suspend. Internally this function uses WDA_FINISH_SCAN_REQ.
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @param callback - Callback function to be called after Resuming the link.
 * @param data - Pointer to any buffer that will be passed to callback.
 * @return None
 */
void
limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data)
{
   if( NULL == callback )
   {
      limLog( pMac, LOGE, "%s:%d: Invalid parameters\n", __FUNCTION__, __LINE__ );
      return;
   }

   if( pMac->lim.gpLimResumeCallback )
   {
      limLog( pMac, LOGE, "%s:%d: gLimResumeLink callback is not NULL...something is wrong\n", __FUNCTION__, __LINE__ );
      callback( pMac, eHAL_STATUS_FAILURE, data ); 
      return;
   }

   pMac->lim.gpLimResumeCallback = callback;
   pMac->lim.gpLimResumeData = data;
   limSendHalFinishScanReq(pMac, eLIM_HAL_RESUME_LINK_WAIT_STATE );
}
//end WLAN_SUSPEND_LINK Related


/**
 *
 * limChangeChannelWithCallback()
 *
 * FUNCTION:
 * This function is called to change channel and perform off channel operation
 * if required. The caller registers a callback to be called at the end of the
 * channel change. 
 *
 */
void
limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel, 
    CHANGE_CHANNEL_CALLBACK callback, 
    tANI_U32 *cbdata, tpPESession psessionEntry)
{
    // Sanity checks for the current and new channel
#if defined WLAN_VOWIFI_DEBUG
        PELOGE(limLog( pMac, LOGE, "Switching channel to %d\n", newChannel);)
#endif
    psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION;

    pMac->lim.gpchangeChannelCallback = callback;
    pMac->lim.gpchangeChannelData = cbdata;

    limSendSwitchChnlParams(pMac, newChannel,
        PHY_SINGLE_CHANNEL_CENTERED,
        psessionEntry->maxTxPower, psessionEntry->peSessionId);

    return;
}


/**
 * limContinuePostChannelScan()
 *
 *FUNCTION:
 * This function is called to scan the current channel.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac    - Pointer to Global MAC structure
 *
 * @return None
 */

void limContinuePostChannelScan(tpAniSirGlobal pMac)
{
    tANI_U8 channelNum;
    tANI_U8 handleError = 0;
    tANI_U8 i = 0;
    tSirRetStatus status = eSIR_SUCCESS;
    
    if( pMac->lim.abortScan || (NULL == pMac->lim.gpLimMlmScanReq ) ||
        (pMac->lim.gLimCurrentScanChannelId >
            (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)))
    {
        pMac->lim.abortScan = 0;
        limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
        limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
        //Set the resume channel to Any valid channel (invalid). 
        //This will instruct HAL to set it to any previous valid channel.
        peSetResumeChannel(pMac, 0, 0);

        limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE);
        return;
    }

    channelNum = limGetCurrentScanChannel(pMac);
    if ((pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) &&
        (limActiveScanAllowed(pMac, channelNum)))
    {
        TX_TIMER *periodicScanTimer;
        PELOG2(limLog(pMac, LOG2, FL("ACTIVE Scan chan %d, sending probe\n"), channelNum);)

        do
        {
            /* Prepare and send Probe Request frame for all the SSIDs present in the saved MLM 
                    */
       
            PELOGE(limLog(pMac, LOG1, FL("sending ProbeReq number %d, for SSID %s on channel: %d\n"), 
                                                i, pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);)
            // include additional IE if there is
            status = limSendProbeReqMgmtFrame( pMac, &pMac->lim.gpLimMlmScanReq->ssId[i],
               pMac->lim.gpLimMlmScanReq->bssId, channelNum, pMac->lim.gSelfMacAddr, 
               pMac->lim.gpLimMlmScanReq->dot11mode,
               pMac->lim.gpLimMlmScanReq->uIEFieldLen,
               (tANI_U8 *)(pMac->lim.gpLimMlmScanReq)+pMac->lim.gpLimMlmScanReq->uIEFieldOffset);
            
            if ( status != eSIR_SUCCESS)
            {
                PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID %s on channel: %d\n"), 
                                                pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);)
                limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
                limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE);
                return;
            }
            i++;
        } while (i < pMac->lim.gpLimMlmScanReq->numSsid);

        {
#if defined WLAN_FEATURE_VOWIFI
           //If minChannelTime is set to zero, SME is requesting scan to not use min channel timer.
           //This is used in 11k to request for beacon measurement request with a fixed duration in
           //max channel time.
           if( pMac->lim.gpLimMlmScanReq->minChannelTime != 0 )
           {
#endif
            /// TXP has sent Probe Request
            /// Activate minChannelTimer
            limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);

#ifdef GEN6_TODO
            /* revisit this piece of code to assign the appropriate sessionId below
             * priority - LOW/might not be needed
             */ 
            pMac->lim.limTimers.gLimMinChannelTimer.sessionId = sessionId;
#endif            
            
            MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_MIN_CHANNEL_TIMER));

            if (tx_timer_activate(&pMac->lim.limTimers.gLimMinChannelTimer) != TX_SUCCESS)
            {
                limLog(pMac, LOGP, FL("could not start min channel timer\n"));
                return;
            }

            // Initialize max timer too
            limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
#if defined WLAN_FEATURE_VOWIFI
        }
           else
           {
#if defined WLAN_VOWIFI_DEBUG
              PELOGE(limLog( pMac, LOGE, "Min channel time == 0, Use only max chan timer\n" );)
#endif
              //No Need to start Min channel timer. Start Max Channel timer.
              limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
              if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer)
                    == TX_TIMER_ERROR)
              {
                 /// Could not activate max channel timer.
                 // Log error
                 limLog(pMac,LOGP, FL("could not start max channel timer\n"));
                 return; 
              }

    }
#endif
        }
        /* Start peridic timer which will trigger probe req based on min/max
           channel timer */
        periodicScanTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer;
        if (tx_timer_activate(periodicScanTimer) != TX_SUCCESS)
        {
             limLog(pMac, LOGP, FL("could not start periodic probe req "
                                                                  "timer\n"));
             return;
        }
        periodicScanTimer->sessionId = channelNum;
    }
    else
    {
        tANI_U32 val;
        PELOG2(limLog(pMac, LOG2, FL("START PASSIVE Scan chan %d\n"), channelNum);)

        /// Passive Scanning. Activate maxChannelTimer
        MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_MAX_CHANNEL_TIMER));
        if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer)
                                      != TX_SUCCESS)
        {
            // Could not deactivate max channel timer.
            // Log error
            limLog(pMac, LOGP, FL("Unable to deactivate max channel timer\n"));
            return;
        }
        else
        {
            if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,    
                          &val) != eSIR_SUCCESS)
            {
                /**
                 * Could not get max channel value
                 * from CFG. Log error.
                 */
                limLog(pMac, LOGP, FL("could not retrieve passive max channel value\n"));
                return;
            }
            else
            {
                tANI_U32 val1 = 0;

                val = SYS_MS_TO_TICKS(val);
                //TODO: consider sessions.
#if 0
#ifdef ANI_PRODUCT_TYPE_CLIENT
                // If a background was triggered via Quiet BSS,
                // then we need to adjust the MIN and MAX channel
                // timer's accordingly to the Quiet duration that
                // was specified
                if( eLIM_QUIET_RUNNING == pMac->lim.gLimSpecMgmt.quietState &&
                    pMac->lim.gLimTriggerBackgroundScanDuringQuietBss )
                {
                    // gLimQuietDuration is already cached in units of
                    // system ticks. No conversion is reqd...
                    val1 = pMac->lim.gLimSpecMgmt.quietDuration;
                }
                else
                {
                    val1 = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->maxChannelTime);
                }
#endif
#endif
                //Pick the longer stay time
                val = (val > val1) ? val : val1;
                MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_MAX_CHANNEL_TIMER));
                if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer,
                                val, 0) != TX_SUCCESS)
                {
                    // Could not change max channel timer.
                    // Log error
                    limLog(pMac, LOGP, FL("Unable to change max channel timer\n"));
                    return;
                }
                else if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) != TX_SUCCESS)
                {
                    limLog(pMac, LOGP, FL("could not start max channel timer\n"));
                    return;
                }
          
            }
        }
        // Wait for Beacons to arrive
    } // if (pMac->lim.gLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN)

    if( handleError )
    {
        //
        // FIXME - With this, LIM/SoftMAC will try and recover
        // state, but eWNI_SME_SCAN_CNF maybe reporting an
        // incorrect status back to the SME. Some of the possible
        // errors are:
        // eSIR_SME_HAL_SCAN_INIT_FAILED
        // eSIR_SME_RESOURCES_UNAVAILABLE
        //
        //Set the resume channel to Any valid channel (invalid). 
        //This will instruct HAL to set it to any previous valid channel.
        peSetResumeChannel(pMac, 0, 0);
        limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE );
        //limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
    }
    else
    {
        limAddScanChannelInfo(pMac, channelNum);
    }

    return;
}




/*
* Creates a Raw frame to be sent before every Scan, if required.
* If only infra link is active (mlmState = Link Estb), then send Data Null
* If only BT-AMP-AP link is active(mlmState = BSS_STARTED), then send CTS2Self frame.
* If only BT-AMP-STA link is active(mlmState = BSS_STARTED or Link Est) then send CTS2Self
* If Only IBSS link is active, then send CTS2Self
* for concurrent scenario: Infra+BT  or Infra+IBSS, always send CTS2Self, no need to send Data Null
*
*/
static void __limCreateInitScanRawFrame(tpAniSirGlobal pMac, 
                                        tpInitScanParams pInitScanParam)
{
    tANI_U8   i;
    pInitScanParam->scanEntry.activeBSScnt = 0;
    
    /* Don't send CTS to self as we have issue with BTQM queues where BTQM can 
     * not handle transmition of CTS2self frames.  Sending CTS 2 self at this 
     * juncture also doesn't serve much purpose as probe request frames go out 
     * immediately, No need to notify BSS in IBSS case.
     * */

    for(i =0; i < pMac->lim.maxBssId; i++)
    {
        if(pMac->lim.gpSession[i].valid == TRUE)
        {
            if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)
            {
               if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) &&
                   (pInitScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID))
                {
                    pInitScanParam->scanEntry.bssIdx[pInitScanParam->scanEntry.activeBSScnt] 
                        = pMac->lim.gpSession[i].bssIdx;
                    pInitScanParam->scanEntry.activeBSScnt++;

                }
            }
#ifdef WLAN_FEATURE_P2P
            else if( (eLIM_AP_ROLE == pMac->lim.gpSession[i].limSystemRole ) 
                    && ( VOS_P2P_GO_MODE == pMac->lim.gpSession[i].pePersona )
                   )
            {
                pInitScanParam->useNoA = TRUE;
            }
#endif
        }
    }
    if (pInitScanParam->scanEntry.activeBSScnt)
    {
        pInitScanParam->notifyBss = TRUE;
        pInitScanParam->frameType = SIR_MAC_DATA_FRAME;
        pInitScanParam->frameLength = 0;
    }
}

/*
* Creates a Raw frame to be sent during finish scan, if required.
* Send data null frame, only when there is just one session active and that session is
* in 'link Estb' state.
* if more than one session is active, don't send any frame.
* for concurrent scenario: Infra+BT  or Infra+IBSS, no need to send Data Null
*
*/
static void __limCreateFinishScanRawFrame(tpAniSirGlobal pMac, 
                                          tpFinishScanParams pFinishScanParam)
{
    tANI_U8   i;
    pFinishScanParam->scanEntry.activeBSScnt = 0;

    for(i =0; i < pMac->lim.maxBssId; i++)
    {
        if(pMac->lim.gpSession[i].valid == TRUE)
        {
            if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)
            {
                //BT-STA can either be in LINK-ESTB state or BSS_STARTED State
                //for BT, need to send CTS2Self
               if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) &&
                   (pFinishScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID))
                {
                    pFinishScanParam->scanEntry.bssIdx[pFinishScanParam->scanEntry.activeBSScnt] 
                        = pMac->lim.gpSession[i].bssIdx;
                    pFinishScanParam->scanEntry.activeBSScnt++;
                }
            }
        }
    }
    
    if (pFinishScanParam->scanEntry.activeBSScnt)
    {
        pFinishScanParam->notifyBss = TRUE;
        pFinishScanParam->frameType = SIR_MAC_DATA_FRAME;
        pFinishScanParam->frameLength = 0;
    }
}

void
limSendHalInitScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState, tSirLinkTrafficCheck trafficCheck)
{


    tSirMsgQ                msg;
    tpInitScanParams        pInitScanParam;
    tSirRetStatus           rc = eSIR_SUCCESS;

    if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pInitScanParam,
                sizeof(*pInitScanParam)))
    {
        PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
        goto error;
    }
    
    /*Initialize the pInitScanParam with 0*/
    palZeroMemory( pMac->hHdd, (tANI_U8 *)pInitScanParam, sizeof(*pInitScanParam));

    msg.type = WDA_INIT_SCAN_REQ;
    msg.bodyptr = pInitScanParam;
    msg.bodyval = 0;

    palZeroMemory( pMac->hHdd, (tANI_U8 *)&pInitScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr));
    if (nextState == eLIM_HAL_INIT_LEARN_WAIT_STATE)
    {
        pInitScanParam->notifyBss = TRUE;
        pInitScanParam->notifyHost = FALSE;
        pInitScanParam->scanMode = eHAL_SYS_MODE_LEARN;

        pInitScanParam->frameType = SIR_MAC_CTRL_CTS;
        __limCreateInitScanRawFrame(pMac, pInitScanParam);
        pInitScanParam->checkLinkTraffic = trafficCheck;
    }
    else
    {
        if(nextState == eLIM_HAL_SUSPEND_LINK_WAIT_STATE)
        {
            pInitScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK;
        }
        else
        {
            pInitScanParam->scanMode = eHAL_SYS_MODE_SCAN;
        }
        __limCreateInitScanRawFrame(pMac, pInitScanParam);
#ifdef WLAN_FEATURE_P2P
        if (pInitScanParam->useNoA)
        {
            pInitScanParam->scanDuration = pMac->lim.gTotalScanDuration;
        }
#endif       
        /* Inform HAL whether it should check for traffic on the link
         * prior to performing a background scan
         */
        pInitScanParam->checkLinkTraffic = trafficCheck;
    }

    pMac->lim.gLimHalScanState = nextState;
    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

    rc = wdaPostCtrlMsg(pMac, &msg);
    if (rc == eSIR_SUCCESS) {
        PELOG3(limLog(pMac, LOG3, FL("wdaPostCtrlMsg() return eSIR_SUCCESS pMac=%x nextState=%d\n"),
                    pMac, pMac->lim.gLimHalScanState);)
            return;
    }

    SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
    palFreeMemory(pMac->hHdd, (void *)pInitScanParam);
    PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)

error:
    switch(nextState)
    {
        case eLIM_HAL_START_SCAN_WAIT_STATE:
            limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
            break;

#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
        case eLIM_HAL_START_LEARN_WAIT_STATE:
            //            if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
            {
                limRestorePreLearnState(pMac);
                limReEnableLearnMode(pMac);
            }
            break;

#endif

            //WLAN_SUSPEND_LINK Related
        case eLIM_HAL_SUSPEND_LINK_WAIT_STATE:
            pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
            if( pMac->lim.gpLimSuspendCallback )
            {
                pMac->lim.gpLimSuspendCallback( pMac, rc, pMac->lim.gpLimSuspendData );
                pMac->lim.gpLimSuspendCallback = NULL;
                pMac->lim.gpLimSuspendData = NULL;
            }
            pMac->lim.gLimSystemInScanLearnMode = 0;
            break;
            //end WLAN_SUSPEND_LINK Related
        default:
            break;
    }
    pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;

    return ;
}

void
limSendHalStartScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState)
{
    tSirMsgQ            msg;
    tpStartScanParams   pStartScanParam;
    tSirRetStatus       rc = eSIR_SUCCESS;

    /**
     * The Start scan request to be sent only if Start Scan is not already requested
     */
    if(pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE) 
    { 

        if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, 
                    (void **)&pStartScanParam,
                    sizeof(*pStartScanParam)))
        {
            PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
                goto error;
        }

        msg.type = WDA_START_SCAN_REQ;
        msg.bodyptr = pStartScanParam;
        msg.bodyval = 0;
        pStartScanParam->status = eHAL_STATUS_SUCCESS;
        pStartScanParam->scanChannel = (tANI_U8)channelNum;

        pMac->lim.gLimHalScanState = nextState;
        SET_LIM_PROCESS_DEFD_MESGS(pMac, false);

        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
        limLog(pMac, LOG1, FL("Channel %d\n"), channelNum);

            rc = wdaPostCtrlMsg(pMac, &msg);
        if (rc == eSIR_SUCCESS) {
            return;
        }

        SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        palFreeMemory(pMac->hHdd, (void *)pStartScanParam);
        PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)

error:
        switch(nextState)
        {
            case eLIM_HAL_START_SCAN_WAIT_STATE:
                limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
                break;

#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
            case eLIM_HAL_START_LEARN_WAIT_STATE:
                //if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
                {
                    limRestorePreLearnState(pMac);
                    limReEnableLearnMode(pMac);
                }
                break;

#endif

            default:
                break;
        }
        pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;

    }
    else
    {
        PELOGW(limLog(pMac, LOGW, FL("Invalid state for START_SCAN_REQ message=%d\n"), pMac->lim.gLimHalScanState);)
    }

    return;
}

void limSendHalEndScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState)
{
    tSirMsgQ            msg;
    tpEndScanParams     pEndScanParam;
    tSirRetStatus       rc = eSIR_SUCCESS;

    /**
     * The End scan request to be sent only if End Scan is not already requested or
     * Start scan is not already requestd
     */
    if((pMac->lim.gLimHalScanState != eLIM_HAL_END_SCAN_WAIT_STATE)  &&
            (pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE))
    { 

        if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pEndScanParam,
                    sizeof(*pEndScanParam)))
        {
            PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
                goto error;
        }

        msg.type = WDA_END_SCAN_REQ;
        msg.bodyptr = pEndScanParam;
        msg.bodyval = 0;
        pEndScanParam->status = eHAL_STATUS_SUCCESS;
        pEndScanParam->scanChannel = (tANI_U8)channelNum;

        pMac->lim.gLimHalScanState = nextState;
        SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

        rc = wdaPostCtrlMsg(pMac, &msg);
        if (rc == eSIR_SUCCESS) {
            return;
        }

        SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
        palFreeMemory(pMac->hHdd, (void *)pEndScanParam);
        PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)

            error:
            switch(nextState)
            {
                case eLIM_HAL_END_SCAN_WAIT_STATE:
                    limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_END_FAILED);
                    break;

#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
                case eLIM_HAL_END_LEARN_WAIT_STATE:
                    //            if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
                    {
                        limRestorePreLearnState(pMac);
                        limReEnableLearnMode(pMac);
                    }
                    break;
#endif

                default:
                    PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg Rcvd invalid nextState %d\n"), nextState);)
                        break;
            }
        pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
        PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)    
    }
    else
    {
        PELOGW(limLog(pMac, LOGW, FL("Invalid state for END_SCAN_REQ message=%d\n"), pMac->lim.gLimHalScanState);)
    }


    return;
}

/**
 * limSendHalFinishScanReq()
 *
 *FUNCTION:
 * This function is called to finish scan/learn request..
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param  pMac    - Pointer to Global MAC structure
 * @param  nextState - this parameters determines whether this call is for scan or learn
 *
 * @return None
 */
void limSendHalFinishScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState)
{

    tSirMsgQ            msg;
    tpFinishScanParams  pFinishScanParam;
    tSirRetStatus       rc = eSIR_SUCCESS;

    if(pMac->lim.gLimHalScanState == nextState)
    {
        /*
         * PE may receive multiple probe responses, while waiting for HAL to send 'FINISH_SCAN_RSP' message
         * PE was sending multiple finish scan req messages to HAL
         * this check will avoid that.
         * If PE is already waiting for the 'finish_scan_rsp' message from HAL, it will ignore this request.
         */
        PELOGW(limLog(pMac, LOGW, FL("Next Scan State is same as the current state: %d \n"), nextState);)
            return;
    }


    if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pFinishScanParam,
                sizeof(*pFinishScanParam)))
    {
        PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
            goto error;
    }

    msg.type = WDA_FINISH_SCAN_REQ;
    msg.bodyptr = pFinishScanParam;
    msg.bodyval = 0;
    
    peGetResumeChannel(pMac, &pFinishScanParam->currentOperChannel, &pFinishScanParam->cbState);

    palZeroMemory( pMac->hHdd, (tANI_U8 *)&pFinishScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr));

    if (nextState == eLIM_HAL_FINISH_LEARN_WAIT_STATE)
    {
        //AP - No pkt need to be transmitted
        pFinishScanParam->scanMode = eHAL_SYS_MODE_LEARN;
        pFinishScanParam->notifyBss = FALSE;
        pFinishScanParam->notifyHost = FALSE;
        pFinishScanParam->frameType = 0;

        pFinishScanParam->frameLength = 0;
        pMac->lim.gLimHalScanState = nextState;
    }
    else
    {
        /* If STA is associated with an AP (ie. STA is in
         * LINK_ESTABLISHED state), then STA need to inform
         * the AP via either DATA-NULL
         */
        if (nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE)
        {
            pFinishScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK;
        }
        else
        {
            pFinishScanParam->scanMode = eHAL_SYS_MODE_SCAN;
        }
        pFinishScanParam->notifyHost = FALSE;
        __limCreateFinishScanRawFrame(pMac, pFinishScanParam);
        //WLAN_SUSPEND_LINK Related
        pMac->lim.gLimHalScanState = nextState;
        //end WLAN_SUSPEND_LINK Related
    }

    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

    rc = wdaPostCtrlMsg(pMac, &msg);
    if (rc == eSIR_SUCCESS) {
        return;
    }
    SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
    palFreeMemory(pMac->hHdd, (void *)pFinishScanParam);
    PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)

        error:
        if(nextState == eLIM_HAL_FINISH_SCAN_WAIT_STATE)
            limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_FINISH_FAILED);
    //WLAN_SUSPEND_LINK Related
        else if ( nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE )
        {
            if( pMac->lim.gpLimResumeCallback )
            {
                pMac->lim.gpLimResumeCallback( pMac, rc, pMac->lim.gpLimResumeData );
                pMac->lim.gpLimResumeCallback = NULL;
                pMac->lim.gpLimResumeData = NULL;
                pMac->lim.gLimSystemInScanLearnMode = 0;
            }
        }
    //end WLAN_SUSPEND_LINK Related
    pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
    return;
}

/**
 * limContinueChannelScan()
 *
 *FUNCTION:
 * This function is called by limPerformChannelScan().
 * This function is called to continue channel scanning when
 * Beacon/Probe Response frame are received.
 *
 *LOGIC:
 * Scan criteria stored in pMac->lim.gLimMlmScanReq is used
 * to perform channel scan. In this function MLM sub module
 * makes channel switch, sends PROBE REQUEST frame in case of
 * ACTIVE SCANNING, starts min/max channel timers, programs
 * NAV to probeDelay timer and waits for Beacon/Probe Response.
 * Once all required channels are scanned, LIM_MLM_SCAN_CNF
 * primitive is used to send Scan results to SME sub module.
 *
 *ASSUMPTIONS:
 * 1. In case of Active scanning, start MAX channel time iff
 *    MIN channel timer expired and activity is observed on
 *    the channel.
 *
 *NOTE:
 * NA
 *
 * @param pMac      Pointer to Global MAC structure
 * @return None
 */
void
limContinueChannelScan(tpAniSirGlobal pMac)
{
    tANI_U8                channelNum;

    PELOG1(limLog(pMac, LOG1, FL("Continue SCAN : chan %d tot %d\n"),
           pMac->lim.gLimCurrentScanChannelId,
           pMac->lim.gpLimMlmScanReq->channelList.numChannels);)

    if (pMac->lim.gLimCurrentScanChannelId >
        (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1) 
        || pMac->lim.abortScan)
    {
#ifndef ANI_SNIFFER
        pMac->lim.abortScan = 0;
        limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
        limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);

        //Set the resume channel to Any valid channel (invalid). 
        //This will instruct HAL to set it to any previous valid channel.
        peSetResumeChannel(pMac, 0, 0);

        /// Done scanning all required channels
        limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE);
#endif
        return;
    }

    /// Atleast one more channel is to be scanned

    if ((pMac->lim.gLimReturnAfterFirstMatch & 0x40) ||
        (pMac->lim.gLimReturnAfterFirstMatch & 0x80))
    {
        while (pMac->lim.gLimCurrentScanChannelId <=
               (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
        {
            if (((limGetCurrentScanChannel(pMac) <= 14) &&
                  pMac->lim.gLim24Band11dScanDone) ||
                ((limGetCurrentScanChannel(pMac) > 14) &&
                  pMac->lim.gLim50Band11dScanDone))
            {
                limLog(pMac, LOGW, FL("skipping chan %d\n"),
                       limGetCurrentScanChannel(pMac));
                pMac->lim.gLimCurrentScanChannelId++;
            }
            else
                break;
        }

        if (pMac->lim.gLimCurrentScanChannelId >
            (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
        {
            pMac->lim.abortScan = 0;
            limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
            limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
            /// Done scanning all required channels
            //Set the resume channel to Any valid channel (invalid). 
            //This will instruct HAL to set it to any previous valid channel.
            peSetResumeChannel(pMac, 0, 0);
            limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE);
            return;
        }
    }

    channelNum = limGetCurrentScanChannel(pMac);
    PELOG2(limLog(pMac, LOG2, FL("Current Channel to be scanned is %d\n"),
           channelNum);)

    limSendHalStartScanReq(pMac, channelNum, eLIM_HAL_START_SCAN_WAIT_STATE);
    return;
} /*** end limContinueChannelScan() ***/



/**
 * limRestorePreScanState()
 *
 *FUNCTION:
 * This function is called by limContinueChannelScan()
 * to restore HW state prior to entering 'scan state'
 *
 *LOGIC
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 * NA
 *
 * @param pMac      Pointer to Global MAC structure
 * @return None
 */
void
limRestorePreScanState(tpAniSirGlobal pMac)
{
    int i;
    
    /// Deactivate MIN/MAX channel timers if running
    limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
    limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);

    /* Re-activate Heartbeat timers for connected sessions as scan 
     * is done if the DUT is in active mode*/
    if((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) ||
       (ePMM_STATE_READY == pMac->pmm.gPmmState))
    {
      for(i=0;i<pMac->lim.maxBssId;i++)
      {
        if((peFindSessionBySessionId(pMac,i) != NULL) &&
           (pMac->lim.gpSession[i].valid == TRUE) && 
           (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState))
        {
          limReactivateHeartBeatTimer(pMac, peFindSessionBySessionId(pMac,i));
        }  
      }
    }

    /**
     * clean up message queue.
     * If SME messages, redirect to deferred queue.
     * The rest will be discarded.
     */
    //limCleanupMsgQ(pMac);

    pMac->lim.gLimSystemInScanLearnMode = 0;
    PELOG1(limLog(pMac, LOG1, FL("Scan ended, took %d tu\n"), (tx_time_get() - pMac->lim.scanStartTime));)
} /*** limRestorePreScanState() ***/

#ifdef FEATURE_OEM_DATA_SUPPORT

void limSendHalOemDataReq(tpAniSirGlobal pMac)
{
    tSirMsgQ msg;
    tpStartOemDataReq pStartOemDataReq = NULL;
    tSirRetStatus rc = eSIR_SUCCESS;
    tpLimMlmOemDataRsp pMlmOemDataRsp;
    tANI_U32 reqLen = 0;
    if(NULL == pMac->lim.gpLimMlmOemDataReq)
    {
        PELOGE(limLog(pMac, LOGE,  FL("Null pointer\n"));)
        goto error;
    }

    reqLen = sizeof(tStartOemDataReq);

    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd, (void**)&pStartOemDataReq, reqLen))
    {
        PELOGE(limLog(pMac, LOGE,  FL("OEM_DATA: Could not allocate memory for pStartOemDataReq\n"));)
        goto error;
    }

    palZeroMemory(pMac->hHdd, (tANI_U8*)(pStartOemDataReq), reqLen);

    //Now copy over the information to the OEM DATA REQ to HAL
    palCopyMemory(pMac->hHdd, pStartOemDataReq->selfMacAddr, pMac->lim.gpLimMlmOemDataReq->selfMacAddr, sizeof(tSirMacAddr));

    palCopyMemory(pMac->hHdd, pStartOemDataReq->oemDataReq, pMac->lim.gpLimMlmOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE);

    //Create the message to be passed to HAL
    msg.type = WDA_START_OEM_DATA_REQ;
    msg.bodyptr = pStartOemDataReq;
    msg.bodyval = 0;

    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));

    rc = wdaPostCtrlMsg(pMac, &msg);
    if(rc == eSIR_SUCCESS)
    {
        return;
    }

    SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
    palFreeMemory(pMac->hHdd, (void*)pStartOemDataReq);
    PELOGE(limLog(pMac, LOGE,  FL("OEM_DATA: posting WDA_START_OEM_DATA_REQ to HAL failed\n"));)

error:
    pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;

    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd, (void**)(&pMlmOemDataRsp), sizeof(tLimMlmOemDataRsp)))
    {
        limLog(pMac->hHdd, LOGP, FL("OEM_DATA: memory allocation for pMlmOemDataRsp failed under suspend link failure\n"));
        return;
    }

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

    limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp);

    return;
}
/**
 * limSetOemDataReqModeFailed()
 *
 * FUNCTION:
 *  This function is used as callback to resume link after the suspend fails while
 *  starting oem data req mode.
 * LOGIC:
 *  NA
 *
 * ASSUMPTIONS:
 *  NA
 *
 * NOTE:
 *
 * @param pMac - Pointer to Global MAC structure
 * @return None
 */

void limSetOemDataReqModeFailed(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data)
{
    tpLimMlmOemDataRsp pMlmOemDataRsp;

    pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;

    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd, (void**)(&pMlmOemDataRsp), sizeof(tLimMlmOemDataRsp)))
    {
        limLog(pMac->hHdd, LOGP, FL("OEM_DATA: memory allocation for pMlmOemDataRsp failed under suspend link failure\n"));
        return;
    }

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

    palZeroMemory(pMac->hHdd, pMlmOemDataRsp, sizeof(tLimMlmOemDataRsp));

    limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp);

    return;
}

/**
 * limSetOemDataReqMode()
 *
 *FUNCTION:
 * This function is called to setup system into OEM DATA REQ mode
 *
 *LOGIC:
 * NA
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 *
 * @param  pMac - Pointer to Global MAC structure
 * @return None
 */

void limSetOemDataReqMode(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data)
{
    if(status != eHAL_STATUS_SUCCESS)
    {
        limLog(pMac, LOGE, FL("OEM_DATA: failed in suspend link\n"));
        goto error;
    }
    else
    {
        PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: Calling limSendHalOemDataReq\n"));)
        limSendHalOemDataReq(pMac);
        return;
    }

error:
    limResumeLink(pMac, limSetOemDataReqModeFailed, NULL);
    return ;
} /*** end limSendHalOemDataReq() ***/

#endif //FEATURE_OEM_DATA_SUPPORT

static void
mlm_add_sta(
    tpAniSirGlobal  pMac,
    tpAddStaParams  pSta,
    tANI_U8        *pBssid,
    tANI_U8         htCapable,
    tpPESession     psessionEntry)  //psessionEntry  may required in future
{
    tANI_U32 val;
    int      i;
    

    pSta->staType = STA_ENTRY_SELF; // Identifying self

    palCopyMemory( pMac->hHdd,  pSta->bssId,   pBssid,  sizeof( tSirMacAddr ));
    palCopyMemory( pMac->hHdd,  pSta->staMac, psessionEntry->selfMacAddr, sizeof(tSirMacAddr));

    /* Configuration related parameters to be changed to support BT-AMP */

    if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_LISTEN_INTERVAL, &val ))
        limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL\n"));
    
    pSta->listenInterval = (tANI_U16) val;
    
    if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) )
        limLog(pMac, LOGP, FL("Couldn't get SHORT_PREAMBLE\n"));
    pSta->shortPreambleSupported = (tANI_U8)val;

    pSta->assocId               = 0; // Is SMAC OK with this?
    pSta->wmmEnabled            = 0;
    pSta->uAPSD                 = 0;
    pSta->maxSPLen              = 0;
    pSta->us32MaxAmpduDuration  = 0;
    pSta->maxAmpduSize          = 0; // 0: 8k, 1: 16k,2: 32k,3: 64k


    if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) 
    {
        pSta->htCapable         = htCapable;
#ifdef WLAN_SOFTAP_FEATURE
        pSta->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry);
        pSta->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry );
        pSta->mimoPS            = (tSirMacHTMIMOPowerSaveState)limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry );
        pSta->rifsMode          = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry );
        pSta->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry );
        pSta->delBASupport      = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry );
        pSta->maxAmpduDensity   = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry );
        pSta->maxAmsduSize      = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry );
        pSta->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry);
        pSta->fShortGI20Mhz     = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry);
        pSta->fShortGI40Mhz     = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry);
#else
        pSta->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD );
        pSta->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET );
        pSta->mimoPS            = (tSirMacHTMIMOPowerSaveState)limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE );
        pSta->rifsMode          = limGetHTCapability( pMac, eHT_RIFS_MODE );
        pSta->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION );
        pSta->delBASupport      = limGetHTCapability( pMac, eHT_DELAYED_BA );
        pSta->maxAmpduDensity   = limGetHTCapability( pMac, eHT_MPDU_DENSITY );
        pSta->maxAmsduSize      = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH );
        pSta->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ);
        pSta->fShortGI20Mhz     = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ);
        pSta->fShortGI40Mhz     = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ);

#endif
    }
#ifdef WLAN_FEATURE_11AC
    if (psessionEntry->vhtCapability)
    {
        pSta->vhtCapable = VOS_TRUE;
    }
#endif
#ifdef WLAN_FEATURE_11AC
    limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry,NULL);
#else
    limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry);
#endif
    limFillSupportedRatesInfo(pMac, NULL, &pSta->supportedRates,psessionEntry);
    
    limLog( pMac, LOGE, FL( "GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d, SGI20: %d, SGI40%d\n") ,
                                          pSta->greenFieldCapable, pSta->txChannelWidthSet, pSta->mimoPS, pSta->lsigTxopProtection, 
                                          pSta->fDsssCckMode40Mhz,pSta->fShortGI20Mhz, pSta->fShortGI40Mhz);

#ifdef WLAN_FEATURE_P2P
     if (VOS_P2P_GO_MODE == psessionEntry->pePersona)
     {
         pSta->p2pCapableSta = 1;
     }
#endif

    //Disable BA. It will be set as part of ADDBA negotiation.
    for( i = 0; i < STACFG_MAX_TC; i++ )
    {
        pSta->staTCParams[i].txUseBA = eBA_DISABLE;
        pSta->staTCParams[i].rxUseBA = eBA_DISABLE;
    }
    
}

//
// New HAL interface - WDA_ADD_BSS_REQ
// Package WDA_ADD_BSS_REQ to HAL, in order to start a BSS
//
tSirResultCodes
limMlmAddBss (
    tpAniSirGlobal      pMac,
    tLimMlmStartReq    *pMlmStartReq,
    tpPESession         psessionEntry)
{
    tSirMsgQ msgQ;
    tpAddBssParams pAddBssParams = NULL;
    tANI_U32 retCode;

    // Package WDA_ADD_BSS_REQ message parameters

    if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
                               (void **) &pAddBssParams, sizeof( tAddBssParams )))
    {
        limLog( pMac, LOGE, FL( "Unable to PAL allocate memory during ADD_BSS\n" ));
        // Respond to SME with LIM_MLM_START_CNF
        return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
    }

    palZeroMemory(pMac->hHdd, pAddBssParams, sizeof(tAddBssParams));

    // Fill in tAddBssParams members
    palCopyMemory( pMac->hHdd,  pAddBssParams->bssId, pMlmStartReq->bssId,
                   sizeof( tSirMacAddr ));

    // Fill in tAddBssParams selfMacAddr
    palCopyMemory ( pMac->hHdd,  pAddBssParams->selfMacAddr, 
                    psessionEntry->selfMacAddr,
                   sizeof( tSirMacAddr ));
    
    pAddBssParams->bssType = pMlmStartReq->bssType;
    if ((pMlmStartReq->bssType == eSIR_IBSS_MODE) || 
        (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE)|| 
        (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE)) {
        pAddBssParams->operMode                 = BSS_OPERATIONAL_MODE_STA;
    }
#ifdef WLAN_SOFTAP_FEATURE
    else if (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE){
#else
    else{
#endif
        pAddBssParams->operMode                 = BSS_OPERATIONAL_MODE_AP;
    }

#ifdef WLAN_SOFTAP_FEATURE  
    pAddBssParams->shortSlotTimeSupported = psessionEntry->shortSlotTimeSupported;
#endif

    pAddBssParams->beaconInterval               = pMlmStartReq->beaconPeriod;
    pAddBssParams->dtimPeriod                   = pMlmStartReq->dtimPeriod;
    pAddBssParams->cfParamSet.cfpCount          = pMlmStartReq->cfParamSet.cfpCount;
    pAddBssParams->cfParamSet.cfpPeriod         = pMlmStartReq->cfParamSet.cfpPeriod;
    pAddBssParams->cfParamSet.cfpMaxDuration    = pMlmStartReq->cfParamSet.cfpMaxDuration;
    pAddBssParams->cfParamSet.cfpDurRemaining   = pMlmStartReq->cfParamSet.cfpDurRemaining;

    pAddBssParams->rateSet.numRates = pMlmStartReq->rateSet.numRates;
    palCopyMemory( pMac->hHdd,  pAddBssParams->rateSet.rate,
                   pMlmStartReq->rateSet.rate, pMlmStartReq->rateSet.numRates );

    pAddBssParams->nwType = pMlmStartReq->nwType;

    pAddBssParams->htCapable            = pMlmStartReq->htCapable;
#ifdef WLAN_FEATURE_11AC
    pAddBssParams->vhtCapable           = psessionEntry->vhtCapability;
    pAddBssParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; 
#endif
    pAddBssParams->htOperMode           = pMlmStartReq->htOperMode;
    pAddBssParams->dualCTSProtection    = pMlmStartReq->dualCTSProtection;
    pAddBssParams->txChannelWidthSet    = pMlmStartReq->txChannelWidthSet;

    pAddBssParams->currentOperChannel   = pMlmStartReq->channelNumber;
    pAddBssParams->currentExtChannel    = pMlmStartReq->cbMode;

    /* Update PE sessionId*/
    pAddBssParams->sessionId            = pMlmStartReq->sessionId; 

    //Send the SSID to HAL to enable SSID matching for IBSS
    palCopyMemory( pMac->hHdd, &(pAddBssParams->ssId.ssId),
        pMlmStartReq->ssId.ssId,
        pMlmStartReq->ssId.length);
    pAddBssParams->ssId.length = pMlmStartReq->ssId.length;
#ifdef WLAN_SOFTAP_FEATURE
    pAddBssParams->bHiddenSSIDEn = pMlmStartReq->ssidHidden;
    limLog( pMac, LOGE, FL( "TRYING TO HIDE SSID %d\n" ),pAddBssParams->bHiddenSSIDEn);
    // CR309183. Disable Proxy Probe Rsp.  Host handles Probe Requests.  Until FW fixed. 
    pAddBssParams->bProxyProbeRespEn = 0;
    pAddBssParams->obssProtEnabled = pMlmStartReq->obssProtEnabled;

#endif
#if defined WLAN_FEATURE_VOWIFI  
    pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
#endif
    mlm_add_sta(pMac, &pAddBssParams->staContext,
                pAddBssParams->bssId, pAddBssParams->htCapable,psessionEntry);

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

    // Set a new state for MLME
    psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

    pAddBssParams->halPersona=psessionEntry->pePersona; //pass on the session persona to hal

    pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;

#if defined WLAN_FEATURE_VOWIFI_11R
    pAddBssParams->extSetStaKeyParamValid = 0;
#endif

    //
    // FIXME_GEN4
    // A global counter (dialog token) is required to keep track of
    // all PE <-> HAL communication(s)
    //
    msgQ.type       = WDA_ADD_BSS_REQ;
    msgQ.reserved   = 0;
    msgQ.bodyptr    = pAddBssParams;
    msgQ.bodyval    = 0;
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));

    limLog( pMac, LOGW, FL( "Sending WDA_ADD_BSS_REQ...\n" ));
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"), retCode );
        palFreeMemory(pMac->hHdd,(void *)pAddBssParams);
        return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
    }

    return eSIR_SME_SUCCESS;
}


/**
 * limProcessMlmStartReq()
 *
 *FUNCTION:
 * This function is called to process MLM_START_REQ message
 * from SME
 *
 *LOGIC:
 * 1) MLME receives LIM_MLM_START_REQ from LIM
 * 2) MLME sends WDA_ADD_BSS_REQ to HAL
 * 3) MLME changes state to eLIM_MLM_WT_ADD_BSS_RSP_STATE
 * MLME now waits for HAL to send WDA_ADD_BSS_RSP
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tLimMlmStartReq          *pMlmStartReq;
    tLimMlmStartCnf          mlmStartCnf;
    tpPESession              psessionEntry = NULL;
    
    if(pMsgBuf == NULL)
    {
        PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
        return;
    }
    
    pMlmStartReq = (tLimMlmStartReq *) pMsgBuf;
    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmStartReq->sessionId))==NULL)
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
        mlmStartCnf.resultCode = eSIR_SME_REFUSED;
        goto end;
    }

    if (psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE)
    {
        /**
         * Should not have received Start req in states other than idle.
         * Return Start confirm with failure code.
         */
        PELOGE(limLog(pMac, LOGE, FL("received unexpected MLM_START_REQ in state %X\n"),psessionEntry->limMlmState);)
        limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
        mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
        goto end;
    }
    
    #if 0
     if (cfgSetInt(pMac, WNI_CFG_CURRENT_CHANNEL, pMlmStartReq->channelNumber)!= eSIR_SUCCESS)
            limLog(pMac, LOGP, FL("could not set CURRENT_CHANNEL at CFG\n"));
     
        pMac->lim.gLimCurrentChannelId = pMlmStartReq->channelNumber;
    #endif //TO SUPPORT BT-AMP


    // Update BSSID & SSID at CFG database
    #if 0 //We are not using the BSSID and SSID from the config file, instead we are reading form the session table
     if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) pMlmStartReq->bssId, sizeof(tSirMacAddr))
        != eSIR_SUCCESS)
        limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));

   
    
    palCopyMemory( pMac->hHdd, pMac->lim.gLimCurrentBssId,
                   pMlmStartReq->bssId,
                   sizeof(tSirMacAddr));
    #endif //TO SUPPORT BT-AMP

    #if 0
    if (cfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *) &pMlmStartReq->ssId.ssId, pMlmStartReq->ssId.length)
        != eSIR_SUCCESS)
        limLog(pMac, LOGP, FL("could not update SSID at CFG\n"));
    #endif //To SUPPORT BT-AMP
   
         
   // pMac->lim.gLimCurrentSSID.length = pMlmStartReq->ssId.length;

        #if 0
        if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
           (tANI_U8 *) &pMac->lim.gpLimStartBssReq->operationalRateSet.rate,
           pMac->lim.gpLimStartBssReq->operationalRateSet.numRates)
        != eSIR_SUCCESS)
        limLog(pMac, LOGP, FL("could not update Operational Rateset at CFG\n"));
        #endif //TO SUPPORT BT-AMP
        

#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
    if (cfgSetInt(pMac, WNI_CFG_CURRENT_TX_POWER_LEVEL, pMac->lim.gpLimStartBssReq->powerLevel)
        != eSIR_SUCCESS)
        limLog(pMac, LOGP, FL("could not set WNI_CFG_CURRENT_TX_POWER_LEVEL at CFG\n"));
#endif

#ifdef WLAN_SOFTAP_FEATURE
#if 0 // Periodic timer for remove WPS PBC proble response entry in PE is disbaled now.
    if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
    {
        if(pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated == eANI_BOOLEAN_FALSE)
        {
            if (tx_timer_create(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer,
                            "PS OVERLAP Timer",
                            limWPSOverlapTimerHandler,
                            SIR_LIM_WPS_OVERLAP_TIMEOUT, // expiration_input
                            SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS),  // initial_ticks
                            SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS),                         // reschedule_ticks
                            TX_AUTO_ACTIVATE /* TX_NO_ACTIVATE*/) != TX_SUCCESS)
            {
                limLog(pMac, LOGP, FL("failed to create WPS overlap Timer\n"));
            }
            
            pMac->lim.limTimers.gLimWPSOverlapTimerObj.sessionId = pMlmStartReq->sessionId;
            pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated = eANI_BOOLEAN_TRUE;
            limLog(pMac, LOGE, FL("Create WPS overlap Timer, session=%d\n"), pMlmStartReq->sessionId);

            if (tx_timer_activate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS)
            {
                limLog(pMac, LOGP, FL("tx_timer_activate failed\n"));
            }    
       }
    }
#endif
#endif


   
    mlmStartCnf.resultCode = limMlmAddBss(pMac, pMlmStartReq,psessionEntry);

end:
    /* Update PE session Id */
     mlmStartCnf.sessionId = pMlmStartReq->sessionId;
    
    /// Free up buffer allocated for LimMlmScanReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf);

    //
    // Respond immediately to LIM, only if MLME has not been
    // successfully able to send WDA_ADD_BSS_REQ to HAL.
    // Else, LIM_MLM_START_CNF will be sent after receiving
    // WDA_ADD_BSS_RSP from HAL
    //
    if( eSIR_SME_SUCCESS != mlmStartCnf.resultCode )
      limPostSmeMessage(pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf);
} /*** limProcessMlmStartReq() ***/


/*
* This function checks if Scan is allowed or not.
* It checks each session and if any session is not in the normal state,
* it will return false.
* Note:  BTAMP_STA can be in LINK_EST as well as BSS_STARTED State, so
* both cases are handled below.
*/

static tANI_U8 __limMlmScanAllowed(tpAniSirGlobal pMac)
{
    int i;

    if(pMac->lim.gLimMlmState != eLIM_MLM_IDLE_STATE)
    {
        return FALSE;
    }
    for(i =0; i < pMac->lim.maxBssId; i++)
    {
        if(pMac->lim.gpSession[i].valid == TRUE)
        {
            if(!( ( (  (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) ||
                       (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
                       (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )||
                  
                  (    ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)||
                           (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)||
                           (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&&
                       (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) )
#ifdef WLAN_FEATURE_P2P
               ||  ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE) 
                      && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) )
                    || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) )
                  && (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) )
#endif
                ))
            {
                return FALSE;

            }
        }
    }

    return TRUE;
}



/**
 * limProcessMlmScanReq()
 *
 *FUNCTION:
 * This function is called to process MLM_SCAN_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tLimMlmScanCnf       mlmScanCnf;

    if (pMac->lim.gLimSystemInScanLearnMode)
    {
        PELOGE(limLog(pMac, LOGE,
               FL("Sending START_SCAN from LIM while one req is pending\n"));)
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf);
        return;
    }

 if(__limMlmScanAllowed(pMac) && 
    (((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels != 0))
        
    {
        /// Hold onto SCAN REQ criteria
        pMac->lim.gpLimMlmScanReq = (tLimMlmScanReq *) pMsgBuf;

       PELOG3(limLog(pMac, LOG3, FL("Number of channels to scan are %d \n"),
               pMac->lim.gpLimMlmScanReq->channelList.numChannels);)

        pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;

        if (pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN)
            pMac->lim.gLimMlmState = eLIM_MLM_WT_PROBE_RESP_STATE;
        else // eSIR_PASSIVE_SCAN
            pMac->lim.gLimMlmState = eLIM_MLM_PASSIVE_SCAN_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));

        pMac->lim.gLimSystemInScanLearnMode = 1;

#ifdef WLAN_FEATURE_P2P
        pMac->lim.gTotalScanDuration = 
                    pMac->lim.gpLimMlmScanReq->maxChannelTime*
                    pMac->lim.gpLimMlmScanReq->channelList.numChannels;
#endif
        limSetScanMode(pMac);
    }
    else
    {
        /**
         * Should not have received SCAN req in other states
         * OR should not have received LIM_MLM_SCAN_REQ with
         * zero number of channels
         * Log error
         */
        limLog(pMac, LOGW,
               FL("received unexpected MLM_SCAN_REQ in state %X OR zero number of channels: %X\n"),
               pMac->lim.gLimMlmState, ((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels);
        limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState);

        /// Free up buffer allocated for
        /// pMac->lim.gLimMlmScanReq
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf);

        /// Return Scan confirm with INVALID_PARAMETERS

        mlmScanCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
        mlmScanCnf.scanResultLength = 0;
        limPostSmeMessage(pMac,
                         LIM_MLM_SCAN_CNF,
                         (tANI_U32 *) &mlmScanCnf);
    }
} /*** limProcessMlmScanReq() ***/

#ifdef FEATURE_OEM_DATA_SUPPORT
static void limProcessMlmOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tLimMlmOemDataRsp*     pMlmOemDataRsp;
    
    if (((pMac->lim.gLimMlmState == eLIM_MLM_IDLE_STATE) ||
         (pMac->lim.gLimMlmState == eLIM_MLM_JOINED_STATE) ||
         (pMac->lim.gLimMlmState == eLIM_MLM_AUTHENTICATED_STATE) ||
         (pMac->lim.gLimMlmState == eLIM_MLM_BSS_STARTED_STATE) ||
         (pMac->lim.gLimMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)))
    {
        //Hold onto the oem data request criteria
        pMac->lim.gpLimMlmOemDataReq = (tLimMlmOemDataReq*)pMsgBuf;

        pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;

        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));

        //Now request for link suspension
        limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, limSetOemDataReqMode, NULL);
    }
    else
    {
        /**
         * Should not have received oem data req in other states
         * Log error
         */

        PELOGW(limLog(pMac, LOGW, FL("OEM_DATA: unexpected LIM_MLM_OEM_DATA_REQ in invalid state %X\n"),pMac->lim.gLimMlmState);)

        limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState);

        /// Free up buffer allocated
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf);

        /// Return Meas confirm with INVALID_PARAMETERS
        if(eHAL_STATUS_SUCCESS == palAllocateMemory(pMac->hHdd, (void**)&pMlmOemDataRsp, sizeof(tLimMlmOemDataRsp)))
        {
            limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp);
            palFreeMemory(pMac->hHdd, pMlmOemDataRsp);
        }
        else
        {
            limLog(pMac, LOGP, FL("Could not allocate memory for pMlmOemDataRsp\n"));
            return;
        }
    }

    return;
}
#endif //FEATURE_OEM_DATA_SUPPORT


/**
 * limProcessMlmPostJoinSuspendLink()
 *
 *FUNCTION:
 * This function is called after the suspend link while joining
 * off channel.
 *
 *LOGIC:
 * Check for suspend state. 
 * If success, proceed with setting link state to recieve the 
 * probe response/beacon from intended AP.
 * Switch to the APs channel.
 * On an error case, send the MLM_JOIN_CNF with error status.
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  status    status of suspend link.
 * @param  ctx       passed while calling suspend link(psessionEntry)
 * @return None
 */
static void
limProcessMlmPostJoinSuspendLink(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *ctx)
{
    tANI_U8             chanNum, secChanOffset;
    tLimMlmJoinCnf      mlmJoinCnf;
    tpPESession         psessionEntry = (tpPESession)ctx;
    tSirLinkState       linkState;

    if( eHAL_STATUS_SUCCESS != status )
    {
       limLog(pMac, LOGP, FL("Suspend link failed. Not proceeding with join\n"));
       goto error;
    }
    psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
    psessionEntry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

    limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);

    //assign appropriate sessionId to the timer object
    pMac->lim.limTimers.gLimJoinFailureTimer.sessionId = psessionEntry->peSessionId;

    linkState = ((psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ? eSIR_LINK_BTAMP_PREASSOC_STATE : eSIR_LINK_PREASSOC_STATE);
    limLog(pMac, LOG1, FL("[limProcessMlmJoinReq]: linkState:%d\n"),linkState);

    if (limSetLinkState(pMac, linkState, 
         psessionEntry->pLimMlmJoinReq->bssDescription.bssId, 
         psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
    {
        limLog(pMac, LOGE, FL("limSetLinkState to eSIR_LINK_PREASSOC_STATE Failed!!\n"));
        mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
        psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
        goto error;
    }

    /** Derive channel from BSS description and store it in the CFG */
    // chanNum = pMac->lim.gpLimMlmJoinReq->bssDescription.channelId;
    
    chanNum = psessionEntry->currentOperChannel;
    secChanOffset = psessionEntry->htSecondaryChannelOffset;
    //store the channel switch sessionEntry in the lim global var
    psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN;

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

    return;
error:
    mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
    mlmJoinCnf.sessionId = psessionEntry->peSessionId;
    mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
    limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);

}



/**
 * limProcessMlmJoinReq()
 *
 *FUNCTION:
 * This function is called to process MLM_JOIN_REQ message
 * from SME
 *
 *LOGIC:
 * 1) Initialize LIM, HAL, DPH
 * 2) Configure the BSS for which the JOIN REQ was received
 *   a) Send WDA_ADD_BSS_REQ to HAL -
 *   This will identify the BSS that we are interested in
 *   --AND--
 *   Add a STA entry for the AP (in a STA context)
 *   b) Wait for WDA_ADD_BSS_RSP
 *   c) Send WDA_ADD_STA_REQ to HAL
 *   This will add the "local STA" entry to the STA table
 * 3) Continue as before, i.e,
 *   a) Send a PROBE REQ
 *   b) Wait for PROBE RSP/BEACON containing the SSID that
 *   we are interested in
 *   c) Then start an AUTH seq
 *   d) Followed by the ASSOC seq
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tLimMlmJoinCnf      mlmJoinCnf;
    tANI_U8             sessionId;
    tpPESession         psessionEntry;

    sessionId = ((tpLimMlmJoinReq)pMsgBuf)->sessionId;

    if((psessionEntry = peFindSessionBySessionId(pMac,sessionId))== NULL)
    {
        limLog(pMac, LOGP, FL("session does not exist for given sessionId\n"));

        goto error;
    }

    if (( (psessionEntry->limSystemRole != eLIM_AP_ROLE ) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE )) &&
          ( (psessionEntry->limMlmState == eLIM_MLM_IDLE_STATE) ||
            (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE))  &&
        (SIR_MAC_GET_ESS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo) !=
             SIR_MAC_GET_IBSS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo)))
    {
        #if 0
        if (pMac->lim.gpLimMlmJoinReq)
            palFreeMemory( pMac->hHdd, pMac->lim.gpLimMlmJoinReq);
        #endif //TO SUPPORT BT-AMP , review 23sep

        /// Hold onto Join request parameters
        
        psessionEntry->pLimMlmJoinReq =(tpLimMlmJoinReq) pMsgBuf;
        
        if( isLimSessionOffChannel(pMac, sessionId) )
        {
          //suspend link
          limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN, 
                   limProcessMlmPostJoinSuspendLink, (tANI_U32*)psessionEntry );
        }
        else
        {
          //No need to suspend link.
          limProcessMlmPostJoinSuspendLink( pMac, eHAL_STATUS_SUCCESS,
                                                    (tANI_U32*) psessionEntry );
        }
                
        return;
    }
    else
    {
        /**
              * Should not have received JOIN req in states other than
              * Idle state or on AP.
              * Return join confirm with invalid parameters code.
              */
        PELOGE(limLog(pMac, LOGE,
               FL("Unexpected Join request for role %d state %X\n"),
               psessionEntry->limSystemRole,
               psessionEntry->limMlmState);)
        limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
        
        limLog(pMac, LOGE, FL("Unexpected Join request for role %d state %X\n"),
               psessionEntry->limSystemRole, psessionEntry->limMlmState);
    }

error: 

        
        mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
        mlmJoinCnf.sessionId = sessionId;
        mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
        limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);


} /*** limProcessMlmJoinReq() ***/



/**
 * limProcessMlmAuthReq()
 *
 *FUNCTION:
 * This function is called to process MLM_AUTH_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U32                numPreAuthContexts;
    tSirMacAddr             currentBssId;
    tSirMacAuthFrameBody    authFrameBody;
    tLimMlmAuthCnf          mlmAuthCnf;
    struct tLimPreAuthNode  *preAuthNode;
    tpDphHashNode           pStaDs;
    tANI_U8                 sessionId;
    tpPESession             psessionEntry;

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

    pMac->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) pMsgBuf;
    sessionId = pMac->lim.gpLimMlmAuthReq->sessionId;
    if((psessionEntry= peFindSessionBySessionId(pMac,sessionId) )== NULL)
    {
        limLog(pMac, LOGP, FL("Session Does not exist for given sessionId\n"));
        return;
    }

    /**
     * Expect Auth request only when:
     * 1. STA joined/associated with a BSS or
     * 2. STA is in IBSS mode
     * and STA is going to authenticate with a unicast
     * adress and requested authentication algorithm is
     * supported.
     */
     #if 0
    if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
                                eSIR_SUCCESS)
    {
        /// Could not get BSSID from CFG. Log error.
        limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
    }
    #endif //To SuppoRT BT-AMP

    sirCopyMacAddr(currentBssId,psessionEntry->bssId);

    if (((((psessionEntry->limSystemRole== eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
          ((psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) ||
           (psessionEntry->limMlmState ==
                                  eLIM_MLM_LINK_ESTABLISHED_STATE))) ||
         ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) &&
          (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE))) &&
        (limIsGroupAddr(pMac->lim.gpLimMlmAuthReq->peerMacAddr)
                                                   == false) &&
#ifdef WLAN_SOFTAP_FEATURE
        (limIsAuthAlgoSupported(
                        pMac,
                        pMac->lim.gpLimMlmAuthReq->authType,
                        psessionEntry) == true)
#else
        (limIsAuthAlgoSupported(
                        pMac,
                        pMac->lim.gpLimMlmAuthReq->authType) == true)
#endif
        )        
    {
        /**
         * This is a request for pre-authentication.
         * Check if there exists context already for
         * the requsted peer OR
         * if this request is for the AP we're currently
         * associated with.
         * If yes, return auth confirm immediately when
         * requested auth type is same as the one used before.
         */
        if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) )&&
             (psessionEntry->limMlmState ==
                                  eLIM_MLM_LINK_ESTABLISHED_STATE) &&
             (((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) != NULL) &&
              (pMac->lim.gpLimMlmAuthReq->authType ==
                                   pStaDs->mlmStaContext.authType)) &&
             (palEqualMemory( pMac->hHdd,pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                        currentBssId,
                        sizeof(tSirMacAddr)) )) ||
            (((preAuthNode =
               limSearchPreAuthList(
                     pMac,
                     pMac->lim.gpLimMlmAuthReq->peerMacAddr)) != NULL) &&
             (preAuthNode->authType ==
                                   pMac->lim.gpLimMlmAuthReq->authType)))
        {
           PELOG2(limLog(pMac, LOG2,
                   FL("Already have pre-auth context with peer\n"));
            limPrintMacAddr(pMac, pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                            LOG2);)

            mlmAuthCnf.resultCode = (tSirResultCodes)
                                    eSIR_MAC_SUCCESS_STATUS;
            

            goto end;
        }
        else
        {
            if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
                          (tANI_U32 *) &numPreAuthContexts) != eSIR_SUCCESS)
            {
                limLog(pMac, LOGP,
                   FL("Could not retrieve NumPreAuthLimit from CFG\n"));
            }
#ifdef ANI_AP_SDK_OPT
            if(numPreAuthContexts > SIR_SDK_OPT_MAX_NUM_PRE_AUTH)
                numPreAuthContexts = SIR_SDK_OPT_MAX_NUM_PRE_AUTH;
#endif // ANI_AP_SDK_OPT

            if (pMac->lim.gLimNumPreAuthContexts == numPreAuthContexts)
            {
                PELOGW(limLog(pMac, LOGW,
                       FL("Number of pre-auth reached max limit\n"));)

                /// Return Auth confirm with reject code
                mlmAuthCnf.resultCode =
                               eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED;

                goto end;
            }
        }

        // Delete pre-auth node if exists
        if (preAuthNode)
            limDeletePreAuthNode(pMac,
                                 pMac->lim.gpLimMlmAuthReq->peerMacAddr);

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

        /// Prepare & send Authentication frame
        authFrameBody.authAlgoNumber =
                                  (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType;
        authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
        authFrameBody.authStatusCode = 0;
        limSendAuthMgmtFrame(pMac,
                             &authFrameBody,
                             pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                             LIM_NO_WEP_IN_FC,psessionEntry);

        //assign appropriate sessionId to the timer object
        pMac->lim.limTimers.gLimAuthFailureTimer.sessionId = sessionId;
 
        // Activate Auth failure timer
        MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_AUTH_FAIL_TIMER));
        if (tx_timer_activate(&pMac->lim.limTimers.gLimAuthFailureTimer)
                                       != TX_SUCCESS)
        {
            /// Could not start Auth failure timer.
            // Log error
            limLog(pMac, LOGP,
                   FL("could not start Auth failure timer\n"));
            // Cleanup as if auth timer expired
            limProcessAuthFailureTimeout(pMac);
        }

        return;
    }
    else
    {
        /**
         * Unexpected auth request.
         * Return Auth confirm with Invalid parameters code.
         */
        mlmAuthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;

        goto end;
    }

end:
    palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmAuthCnf.peerMacAddr,
                  (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                  sizeof(tSirMacAddr));

    mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType;
    mlmAuthCnf.sessionId = sessionId;

    /// Free up buffer allocated
    /// for pMac->lim.gLimMlmAuthReq
    palFreeMemory( pMac->hHdd, pMac->lim.gpLimMlmAuthReq);
    pMac->lim.gpLimMlmAuthReq = NULL;
    limPostSmeMessage(pMac, LIM_MLM_AUTH_CNF, (tANI_U32 *) &mlmAuthCnf);
} /*** limProcessMlmAuthReq() ***/



/**
 * limProcessMlmAssocReq()
 *
 *FUNCTION:
 * This function is called to process MLM_ASSOC_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmAssocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tSirMacAddr              currentBssId;
    tLimMlmAssocReq          *pMlmAssocReq;
    tLimMlmAssocCnf          mlmAssocCnf;
    tpPESession               psessionEntry;
   // tANI_U8                  sessionId;

    if(pMsgBuf == NULL)
    {
        PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
        return;
    }
    pMlmAssocReq = (tLimMlmAssocReq *) pMsgBuf;

    if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmAssocReq->sessionId) )== NULL) 
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmAssocReq);
        return;
    }

    #if 0
    if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
                                eSIR_SUCCESS)
    {
        /// Could not get BSSID from CFG. Log error.
        limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
    }
    #endif //TO SUPPORT BT-AMP
    sirCopyMacAddr(currentBssId,psessionEntry->bssId);
    
    if ( (psessionEntry->limSystemRole != eLIM_AP_ROLE && psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE) &&
         (psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) &&
         (palEqualMemory(pMac->hHdd,pMlmAssocReq->peerMacAddr, currentBssId, sizeof(tSirMacAddr))) )
    {

        /// map the session entry pointer to the AssocFailureTimer 
        pMac->lim.limTimers.gLimAssocFailureTimer.sessionId = pMlmAssocReq->sessionId;

        psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
        psessionEntry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
 
        /// Prepare and send Association request frame
        limSendAssocReqMgmtFrame(pMac, pMlmAssocReq,psessionEntry);

  //Set the link state to postAssoc, so HW can start receiving frames from AP.
    if ((psessionEntry->bssType == eSIR_BTAMP_STA_MODE)||
        ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) && (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)))
    {
       if(limSetLinkState(pMac, eSIR_LINK_BTAMP_POSTASSOC_STATE, currentBssId, 
           psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
            PELOGE(limLog(pMac, LOGE,  FL("Failed to set the LinkState\n"));)
    } else {
       if(limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, currentBssId, 
           psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
            PELOGE(limLog(pMac, LOGE,  FL("Failed to set the LinkState\n"));)
    }
        /// Start association failure timer
        MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_ASSOC_FAIL_TIMER));
        if (tx_timer_activate(&pMac->lim.limTimers.gLimAssocFailureTimer)
                                              != TX_SUCCESS)
        {
            /// Could not start Assoc failure timer.
            // Log error
            limLog(pMac, LOGP,
                   FL("could not start Association failure timer\n"));
            // Cleanup as if assoc timer expired
            limProcessAssocFailureTimeout(pMac,LIM_ASSOC );
           
        }

        return;
    }
    else
    {
        /**
         * Received Association request either in invalid state
         * or to a peer MAC entity whose address is different
         * from one that STA is currently joined with or on AP.
         * Return Assoc confirm with Invalid parameters code.
         */

        // Log error
        PELOGW(limLog(pMac, LOGW,
           FL("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= "),
           psessionEntry->limMlmState,
           psessionEntry->limSystemRole);)
        limPrintMacAddr(pMac, pMlmAssocReq->peerMacAddr, LOGW);
        limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);

        mlmAssocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
        mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;

        goto end;
    }

end:
    /* Update PE session Id*/
    mlmAssocCnf.sessionId = pMlmAssocReq->sessionId;

    /// Free up buffer allocated for assocReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmAssocReq);

    limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
} /*** limProcessMlmAssocReq() ***/



/**
 * limProcessMlmReassocReq()
 *
 *FUNCTION:
 * This function is called to process MLM_REASSOC_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
    tANI_U8                       chanNum, secChannelOffset;
    struct tLimPreAuthNode  *pAuthNode;
    tLimMlmReassocReq       *pMlmReassocReq;
    tLimMlmReassocCnf       mlmReassocCnf;
    tpPESession             psessionEntry;

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

    pMlmReassocReq = (tLimMlmReassocReq *) pMsgBuf;
    
    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmReassocReq->sessionId)) == NULL)
    {
        PELOGE(limLog(pMac, LOGE,FL("Session Does not exist for given sessionId\n"));)
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmReassocReq);
        return;
    }
    
    if (((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) &&
         (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))
    {
        if (psessionEntry->pLimMlmReassocReq)
            palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmReassocReq);

        /* Hold Re-Assoc request as part of Session, knock-out pMac */
        /// Hold onto Reassoc request parameters
        psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
        
        // See if we have pre-auth context with new AP
        pAuthNode = limSearchPreAuthList(pMac, psessionEntry->limReAssocbssId);

        if (!pAuthNode &&
            (!palEqualMemory( pMac->hHdd,pMlmReassocReq->peerMacAddr,
                       psessionEntry->bssId,
                       sizeof(tSirMacAddr)) ))
        {
            // Either pre-auth context does not exist AND
            // we are not reassociating with currently
            // associated AP.
            // Return Reassoc confirm with not authenticated
            mlmReassocCnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
            mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;

            goto end;
        }

        //assign the sessionId to the timer object
        pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = pMlmReassocReq->sessionId;

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

#if 0
        // Update BSSID at CFG database
        if (wlan_cfgSetStr(pMac, WNI_CFG_BSSID,
                      pMac->lim.gLimReassocBssId,
                      sizeof(tSirMacAddr)) != eSIR_SUCCESS)
        {
            /// Could not update BSSID at CFG. Log error.
            limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
        }
#endif //TO SUPPORT BT-AMP

    /* Copy Global Reassoc ID*/
   // sirCopyMacAddr(psessionEntry->reassocbssId,pMac->lim.gLimReAssocBssId);

        /**
         * Derive channel from BSS description and
         * store it at CFG.
         */

        chanNum = psessionEntry->limReassocChannelId;
        secChannelOffset = psessionEntry->reAssocHtSecondaryChannelOffset;

        /* To Support BT-AMP .. read channel number from psessionEntry*/
        //chanNum = psessionEntry->currentOperChannel;

        // Apply previously set configuration at HW
        limApplyConfiguration(pMac,psessionEntry);

        //store the channel switch sessionEntry in the lim global var
        /* We have already saved the ReAssocreq Pointer abobe */
        //psessionEntry->pLimReAssocReq = (void *)pMlmReassocReq;
        psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_REASSOC;

        /** Switch channel to the new Operating channel for Reassoc*/
        limSetChannel(pMac, chanNum, secChannelOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId);

        return;
    }
    else
    {
        /**
         * Received Reassoc request in invalid state or
         * in AP role.Return Reassoc confirm with Invalid
         * parameters code.
         */

        // Log error
        PELOGW(limLog(pMac, LOGW,
           FL("received unexpected MLM_REASSOC_CNF in state %X for role=%d, MAC addr= "),
           psessionEntry->limMlmState,
           psessionEntry->limSystemRole);)
        limPrintMacAddr(pMac, pMlmReassocReq->peerMacAddr,
                        LOGW);
        limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);

        mlmReassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
        mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;

        goto end;
    }

end:
    mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
    /* Update PE sessio Id*/
    mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
    /// Free up buffer allocated for reassocReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmReassocReq);
    psessionEntry->pLimReAssocReq = NULL;

    limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
} /*** limProcessMlmReassocReq() ***/


static void
limProcessMlmDisassocReqPostSuspend(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf)
{
    tANI_U16                 aid;
    tSirMacAddr              currentBssId;
    tpDphHashNode            pStaDs;
    tLimMlmDisassocReq       *pMlmDisassocReq;
    tLimMlmDisassocCnf       mlmDisassocCnf;
    tpPESession              psessionEntry;
    extern tANI_BOOLEAN     sendDisassocFrame;

    if(eHAL_STATUS_SUCCESS != suspendStatus)
    {
        PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X\n"), suspendStatus);)
#if 0
        //It can ignore the status and proceed with the disassoc processing.
        mlmDisassocCnf.resultCode = eSIR_SME_REFUSED;
        goto end;
#endif
    }

    pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf;


    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL)
    {
    
        PELOGE(limLog(pMac, LOGE,
                  FL("session does not exist for given sessionId\n"));)
        mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
        goto end;
    }
    #if 0
    if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
                                eSIR_SUCCESS)
    {
        /// Could not get BSSID from CFG. Log error.
        limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
    }
    #endif //BT-AMP Support
    sirCopyMacAddr(currentBssId,psessionEntry->bssId);

    switch (psessionEntry->limSystemRole)
    {
        case eLIM_STA_ROLE:
        case eLIM_BT_AMP_STA_ROLE:    
            if ( !palEqualMemory( pMac->hHdd,pMlmDisassocReq->peerMacAddr,
                          currentBssId,
                          sizeof(tSirMacAddr)) )
            {
                PELOGW(limLog(pMac, LOGW,
                   FL("received MLM_DISASSOC_REQ with invalid BSS id "));)
                limPrintMacAddr(pMac, pMlmDisassocReq->peerMacAddr, LOGW);

                /// Prepare and Send LIM_MLM_DISASSOC_CNF

                mlmDisassocCnf.resultCode      =
                                       eSIR_SME_INVALID_PARAMETERS;

                goto end;
            }

            break;

        case eLIM_STA_IN_IBSS_ROLE:

            break;

        default: // eLIM_AP_ROLE

            // Fall through
            break;

    } // end switch (psessionEntry->limSystemRole)

    /**
     * Check if there exists a context for the peer entity
     * to be disassociated with.
     */
    pStaDs = dphLookupHashEntry(pMac, pMlmDisassocReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
    if ((pStaDs == NULL) ||
        (pStaDs &&
         ((pStaDs->mlmStaContext.mlmState !=
                             eLIM_MLM_LINK_ESTABLISHED_STATE) &&
          (pStaDs->mlmStaContext.mlmState !=
                             eLIM_MLM_WT_ASSOC_CNF_STATE) &&
          (pStaDs->mlmStaContext.mlmState !=
                             eLIM_MLM_ASSOCIATED_STATE))))
    {
        /**
         * Received LIM_MLM_DISASSOC_REQ for STA that does not
         * have context or in some transit state.
         * Log error
         */
        PELOGW(limLog(pMac, LOGW,
           FL("received MLM_DISASSOC_REQ for STA that either has no context or in some transit state, Addr= "));)
           limPrintMacAddr(pMac, pMlmDisassocReq->peerMacAddr, LOGW);

        /// Prepare and Send LIM_MLM_DISASSOC_CNF

        mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;

        goto end;
    }

    //pStaDs->mlmStaContext.rxPurgeReq = 1;
    pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)
                                           pMlmDisassocReq->reasonCode;
    pStaDs->mlmStaContext.cleanupTrigger = pMlmDisassocReq->disassocTrigger;

    /// Send Disassociate frame to peer entity
    if (sendDisassocFrame && (pMlmDisassocReq->reasonCode != eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON))
    {
    limSendDisassocMgmtFrame(pMac,
                             pMlmDisassocReq->reasonCode,
                             pMlmDisassocReq->peerMacAddr,psessionEntry);
    }
    else
    {
       sendDisassocFrame = 1;    
    }

    /// Receive path cleanup with dummy packet
    if(eSIR_SUCCESS != limCleanupRxPath(pMac, pStaDs,psessionEntry))
        {
            mlmDisassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
            goto end;
        }

#ifdef WLAN_FEATURE_VOWIFI_11R
    if  ( (psessionEntry->limSystemRole == eLIM_STA_ROLE ) && 
          ( 
#ifdef FEATURE_WLAN_CCX
          (psessionEntry->isCCXconnection ) || 
#endif
          (psessionEntry->is11Rconnection )) &&
          (pMlmDisassocReq->reasonCode != eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON))
    {
          PELOGE(limLog(pMac, LOGE, FL("FT Preauth Session Cleanup \n"));)
          limFTCleanup(pMac);
    }
#endif

    /// Free up buffer allocated for mlmDisassocReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDisassocReq);

    return;

end:
    palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDisassocCnf.peerMacAddr,
                  (tANI_U8 *) pMlmDisassocReq->peerMacAddr,
                  sizeof(tSirMacAddr));
    mlmDisassocCnf.aid = pMlmDisassocReq->aid;
    mlmDisassocCnf.disassocTrigger = pMlmDisassocReq->disassocTrigger;
    
    /* Update PE session ID*/
    mlmDisassocCnf.sessionId = pMlmDisassocReq->sessionId;

    /// Free up buffer allocated for mlmDisassocReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDisassocReq);

    limPostSmeMessage(pMac,
                      LIM_MLM_DISASSOC_CNF,
                      (tANI_U32 *) &mlmDisassocCnf);
}

/**
 * limProcessMlmDisassocReq()
 *
 *FUNCTION:
 * This function is called to process MLM_DISASSOC_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
//    tANI_U16                 aid;
//    tSirMacAddr              currentBssId;
//    tpDphHashNode            pStaDs;
    tLimMlmDisassocReq       *pMlmDisassocReq;
//    tLimMlmDisassocCnf       mlmDisassocCnf;
    tpPESession              psessionEntry;
//    extern tANI_BOOLEAN     sendDisassocFrame;

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

    pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf;

    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL)
    {
    
        PELOGE(limLog(pMac, LOGE,
                  FL("session does not exist for given sessionId\n"));)
        return;
    }

    if( (psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
        isLimSessionOffChannel(pMac, pMlmDisassocReq->sessionId) )
    {
      //suspend link
      limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN, 
          limProcessMlmDisassocReqPostSuspend, (tANI_U32*)pMsgBuf );
    }
    else
    {
      //No need to suspend link.
      limProcessMlmDisassocReqPostSuspend( pMac, eHAL_STATUS_SUCCESS,
          (tANI_U32*) pMsgBuf );
    }
} /*** limProcessMlmDisassocReq() ***/

static void
limProcessMlmDeauthReqPostSuspend(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf)
{
    tANI_U16                aid;
    tSirMacAddr             currentBssId;
    tpDphHashNode           pStaDs;
    struct tLimPreAuthNode  *pAuthNode;
    tLimMlmDeauthReq        *pMlmDeauthReq;
    tLimMlmDeauthCnf        mlmDeauthCnf;
    tpPESession             psessionEntry;


    if(eHAL_STATUS_SUCCESS != suspendStatus)
    {
        PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X\n"), suspendStatus);)
#if 0
        //It can ignore the status and proceed with the disassoc processing.
        mlmDisassocCnf.resultCode = eSIR_SME_REFUSED;
        goto end;
#endif
    }

    pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf;

    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL)
    {
    
        PELOGE(limLog(pMac, LOGE, FL("session does not exist for given sessionId\n"));)
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDeauthReq);
        return;
    }
    #if 0
    if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
                                eSIR_SUCCESS)
    {
        /// Could not get BSSID from CFG. Log error.
        limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
    }
    #endif //SUPPORT BT-AMP
    sirCopyMacAddr(currentBssId,psessionEntry->bssId);

    switch (psessionEntry->limSystemRole)
    {
        case eLIM_STA_ROLE:
        case eLIM_BT_AMP_STA_ROLE:
            switch (psessionEntry->limMlmState)
            {
                case eLIM_MLM_IDLE_STATE:
                    // Attempting to Deauthenticate
                    // with a pre-authenticated peer.
                    // Deauthetiate with peer if there
                    // exists a pre-auth context below.
                    break;

                case eLIM_MLM_AUTHENTICATED_STATE:
                case eLIM_MLM_WT_ASSOC_RSP_STATE:
                case eLIM_MLM_LINK_ESTABLISHED_STATE:
                    if (!palEqualMemory( pMac->hHdd,pMlmDeauthReq->peerMacAddr,
                                  currentBssId,
                                  sizeof(tSirMacAddr)) )
                    {
                        PELOGW(limLog(pMac, LOGW,
                           FL("received MLM_DEAUTH_REQ with invalid BSS id "));)
                        PELOGE(limLog(pMac, LOGE, FL("Peer MAC Addr : "));)
                        limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr,LOGE);

                        PELOGE(limLog(pMac, LOGE, FL("\n CFG BSSID Addr : "));)
                        limPrintMacAddr(pMac, currentBssId,LOGE);

                        /// Prepare and Send LIM_MLM_DEAUTH_CNF

                        mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;

                        goto end;
                    }

                    if ((psessionEntry->limMlmState ==
                                       eLIM_MLM_AUTHENTICATED_STATE) ||
                         (psessionEntry->limMlmState ==
                                       eLIM_MLM_WT_ASSOC_RSP_STATE))
                    {
                        // Send Deauthentication frame
                        // to peer entity
                        limSendDeauthMgmtFrame(
                                   pMac,
                                   pMlmDeauthReq->reasonCode,
                                   pMlmDeauthReq->peerMacAddr,psessionEntry);

                        /// Prepare and Send LIM_MLM_DEAUTH_CNF
                        mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS;
                        psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
                        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
                        goto end;
                    }
                    else
                    {
                        // LINK_ESTABLISED_STATE
                        // Cleanup RX & TX paths
                        // below
                    }

                    break;

                default:

                    PELOGW(limLog(pMac, LOGW,
                       FL("received MLM_DEAUTH_REQ with in state %d for peer "),
                       psessionEntry->limMlmState);)
                    limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr, LOGW);
                    limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);

                    /// Prepare and Send LIM_MLM_DEAUTH_CNF
                    mlmDeauthCnf.resultCode =
                                    eSIR_SME_STA_NOT_AUTHENTICATED;

                    goto end;
            }

            break;

        case eLIM_STA_IN_IBSS_ROLE:
            palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDeauthReq);

            return;

        default: // eLIM_AP_ROLE
            break;

    } // end switch (psessionEntry->limSystemRole)

    /**
     * Check if there exists a context for the peer entity
     * to be deauthenticated with.
     */
    pStaDs = dphLookupHashEntry(pMac, pMlmDeauthReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);

    if (pStaDs == NULL)
    {
        /// Check if there exists pre-auth context for this STA
        pAuthNode = limSearchPreAuthList(pMac,
                                pMlmDeauthReq->peerMacAddr);

        if (pAuthNode == NULL)
        {
            /**
             * Received DEAUTH REQ for a STA that is neither
             * Associated nor Pre-authenticated. Log error,
             * Prepare and Send LIM_MLM_DEAUTH_CNF
             */
            PELOGW(limLog(pMac, LOGW,
               FL("received MLM_DEAUTH_REQ for STA that does not have context, Addr="));)
            limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr, LOGW);

            mlmDeauthCnf.resultCode =
                                    eSIR_SME_STA_NOT_AUTHENTICATED;
        }
        else
        {
            mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS;

            /// Delete STA from pre-auth STA list
            limDeletePreAuthNode(pMac, pMlmDeauthReq->peerMacAddr);

            /// Send Deauthentication frame to peer entity
            limSendDeauthMgmtFrame(pMac,
                                   pMlmDeauthReq->reasonCode,
                                   pMlmDeauthReq->peerMacAddr,psessionEntry);
        }

        goto end;
    }
    else if ((pStaDs->mlmStaContext.mlmState !=
                                     eLIM_MLM_LINK_ESTABLISHED_STATE) &&
             (pStaDs->mlmStaContext.mlmState !=
                                          eLIM_MLM_WT_ASSOC_CNF_STATE))
    {
        /**
         * Received LIM_MLM_DEAUTH_REQ for STA that is n
         * some transit state. Log error.
         */
        PELOGW(limLog(pMac, LOGW,
           FL("received MLM_DEAUTH_REQ for STA that either has no context or in some transit state, Addr="));)
        limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr, LOGW);

        /// Prepare and Send LIM_MLM_DEAUTH_CNF

        mlmDeauthCnf.resultCode    = eSIR_SME_INVALID_PARAMETERS;

        goto end;
    }

    //pStaDs->mlmStaContext.rxPurgeReq     = 1;
    pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)
                                           pMlmDeauthReq->reasonCode;
    pStaDs->mlmStaContext.cleanupTrigger = pMlmDeauthReq->deauthTrigger;

    /// Send Deauthentication frame to peer entity
    limSendDeauthMgmtFrame(pMac, pMlmDeauthReq->reasonCode,
                           pMlmDeauthReq->peerMacAddr,psessionEntry);

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

    /// Free up buffer allocated for mlmDeauthReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDeauthReq);

    return;

end:
    palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDeauthCnf.peerMacAddr,
                  (tANI_U8 *) pMlmDeauthReq->peerMacAddr,
                  sizeof(tSirMacAddr));
    mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
    mlmDeauthCnf.aid           = pMlmDeauthReq->aid;
    mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;

    // Free up buffer allocated
    // for mlmDeauthReq
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDeauthReq);

    limPostSmeMessage(pMac,
                      LIM_MLM_DEAUTH_CNF,
                      (tANI_U32 *) &mlmDeauthCnf);

}

/**
 * limProcessMlmDeauthReq()
 *
 *FUNCTION:
 * This function is called to process MLM_DEAUTH_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
//    tANI_U16                aid;
//    tSirMacAddr             currentBssId;
//    tpDphHashNode           pStaDs;
//    struct tLimPreAuthNode  *pAuthNode;
    tLimMlmDeauthReq        *pMlmDeauthReq;
//    tLimMlmDeauthCnf        mlmDeauthCnf;
    tpPESession             psessionEntry;

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

    pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf;

    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL)
    {
    
        PELOGE(limLog(pMac, LOGE, FL("session does not exist for given sessionId\n"));)
        return;
    }

    if( (psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
        isLimSessionOffChannel(pMac, pMlmDeauthReq->sessionId) )
    {
      //suspend link
      limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN, 
          limProcessMlmDeauthReqPostSuspend, (tANI_U32*)pMsgBuf );
    }
    else
    {
      //No need to suspend link.
      limProcessMlmDeauthReqPostSuspend( pMac, eHAL_STATUS_SUCCESS,
          (tANI_U32*) pMsgBuf );
    }
} /*** limProcessMlmDeauthReq() ***/



/**
 * @function : limProcessMlmSetKeysReq()
 *
 * @brief : This function is called to process MLM_SETKEYS_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmSetKeysReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
tANI_U16           aid;
tANI_U16           staIdx = 0;
tANI_U32           defaultKeyId = 0;
tSirMacAddr        currentBssId;
tpDphHashNode      pStaDs;
tLimMlmSetKeysReq  *pMlmSetKeysReq;
tLimMlmSetKeysCnf  mlmSetKeysCnf;
tpPESession        psessionEntry;

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


  pMlmSetKeysReq = (tLimMlmSetKeysReq *) pMsgBuf;
  // Hold onto the SetKeys request parameters
  pMac->lim.gpLimMlmSetKeysReq = (void *) pMlmSetKeysReq;

  if((psessionEntry = peFindSessionBySessionId(pMac,pMlmSetKeysReq->sessionId))== NULL)
  {
    PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId\n"));)
    return;
  }

  limLog( pMac, LOGW,
      FL( "Received MLM_SETKEYS_REQ with parameters:\n"
        "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - "),
      pMlmSetKeysReq->aid,
      pMlmSetKeysReq->edType,
      pMlmSetKeysReq->numKeys );
  limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW );

    #if 0
    if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID, currentBssId, &cfg )) {
    limLog( pMac, LOGP, FL("Could not retrieve BSSID\n"));
        return;
    }
    #endif //TO SUPPORT BT-AMP
    sirCopyMacAddr(currentBssId,psessionEntry->bssId);

    switch( psessionEntry->limSystemRole ) {
    case eLIM_STA_ROLE:
    case eLIM_BT_AMP_STA_ROLE:
        if((!limIsAddrBC( pMlmSetKeysReq->peerMacAddr ) ) &&
          (!palEqualMemory( pMac->hHdd,pMlmSetKeysReq->peerMacAddr,
                         currentBssId, sizeof(tSirMacAddr))) ){
            limLog( pMac, LOGW, FL("Received MLM_SETKEYS_REQ with invalid BSSID\n"));
        limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW );

        // Prepare and Send LIM_MLM_SETKEYS_CNF with error code
        mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
        goto end;
      }
      // Fall thru' & 'Plumb' keys below
      break;
    case eLIM_STA_IN_IBSS_ROLE:
    default: // others
      // Fall thru...
      break;
  }

    /**
      * Use the "unicast" parameter to determine if the "Group Keys"
      * are being set.
      * pMlmSetKeysReq->key.unicast = 0 -> Multicast/broadcast
      * pMlmSetKeysReq->key.unicast - 1 -> Unicast keys are being set
      */
    if( limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) {
        limLog( pMac, LOG1, FL("Trying to set Group Keys...%d \n"), pMlmSetKeysReq->sessionId);
        /** When trying to set Group Keys for any
          * security mode other than WEP, use the
          * STA Index corresponding to the AP...
          */
        switch( pMlmSetKeysReq->edType ) {
      case eSIR_ED_CCMP:
         
#ifdef WLAN_FEATURE_11W
      case eSIR_ED_AES_128_CMAC:
#endif
        staIdx = psessionEntry->staId;
        break;

      default:
        break;
    }
    }else {
        limLog( pMac, LOG1, FL("Trying to set Unicast Keys...\n"));
    /**
     * Check if there exists a context for the
     * peer entity for which keys need to be set.
     */


    pStaDs = dphLookupHashEntry( pMac, pMlmSetKeysReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable);

#ifdef WLAN_SOFTAP_FEATURE
    if ((pStaDs == NULL) ||
           ((pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) && (psessionEntry->limSystemRole != eLIM_AP_ROLE))) {
#else
    if ((pStaDs == NULL) ||
           ((pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) )) {
#endif
        /**
         * Received LIM_MLM_SETKEYS_REQ for STA
         * that does not have context or in some
         * transit state. Log error.
         */
            limLog( pMac, LOG1,
            FL("Received MLM_SETKEYS_REQ for STA that either has no context or in some transit state, Addr = "));
        limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW );

        // Prepare and Send LIM_MLM_SETKEYS_CNF
        mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
        goto end;
        } else
      staIdx = pStaDs->staIndex;
  }

    if ((pMlmSetKeysReq->numKeys == 0) && (pMlmSetKeysReq->edType != eSIR_ED_NONE)) {
        //
        // Broadcast/Multicast Keys (for WEP!!) are NOT sent
        // via this interface!!
        //
        // This indicates to HAL that the WEP Keys need to be
        // extracted from the CFG and applied to hardware
        defaultKeyId = 0xff;
    }else if(pMlmSetKeysReq->key[0].keyId && 
             ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) || 
              (pMlmSetKeysReq->edType == eSIR_ED_WEP104))){
        /* If the Key Id is non zero and encryption mode is WEP, 
         * the key index is coming from the upper layers so that key only 
         * need to be used as the default tx key, This is being used only 
         * in case of WEP mode in HAL */
        defaultKeyId = pMlmSetKeysReq->key[0].keyId;
    }else
        defaultKeyId = 0;

    limLog( pMac, LOG1,
      FL( "Trying to set keys for STA Index [%d], using defaultKeyId [%d]\n" ),
      staIdx,
      defaultKeyId );

    if(limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) {
  psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
  psessionEntry->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE;
  MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
        limLog( pMac, LOG1, FL("Trying to set Group Keys...%d \n"), 
            psessionEntry->peSessionId);

    // Package WDA_SET_BSSKEY_REQ message parameters
        limSendSetBssKeyReq(pMac, pMlmSetKeysReq,psessionEntry);
    return;
    }else {
    // Package WDA_SET_STAKEY_REQ / WDA_SET_STA_BCASTKEY_REQ message parameters
        limSendSetStaKeyReq(pMac, pMlmSetKeysReq, staIdx, (tANI_U8) defaultKeyId,psessionEntry);
    return;
  }

end:
    mlmSetKeysCnf.sessionId= pMlmSetKeysReq->sessionId;
    limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf );

} /*** limProcessMlmSetKeysReq() ***/

/**
 * limProcessMlmRemoveKeyReq()
 *
 *FUNCTION:
 * This function is called to process MLM_REMOVEKEY_REQ message
 * from SME
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  *pMsgBuf  A pointer to the MLM message buffer
 * @return None
 */

static void
limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
{
tANI_U16           aid;
tANI_U16           staIdx = 0;
tSirMacAddr        currentBssId;
tpDphHashNode      pStaDs;
tLimMlmRemoveKeyReq  *pMlmRemoveKeyReq;
tLimMlmRemoveKeyCnf  mlmRemoveKeyCnf;
    tpPESession         psessionEntry;

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

    pMlmRemoveKeyReq = (tLimMlmRemoveKeyReq *) pMsgBuf;


    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyReq->sessionId))== NULL)
    {
        PELOGE(limLog(pMac, LOGE,
                    FL("session does not exist for given sessionId\n"));)
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
        return;
    }


    if( pMac->lim.gpLimMlmRemoveKeyReq != NULL )
    {
        // Free any previous requests.
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMac->lim.gpLimMlmRemoveKeyReq);
        pMac->lim.gpLimMlmRemoveKeyReq = NULL;
    }
    // Hold onto the RemoveKeys request parameters
    pMac->lim.gpLimMlmRemoveKeyReq = (void *) pMlmRemoveKeyReq; 

    #if 0
    if( eSIR_SUCCESS != wlan_cfgGetStr( pMac,
        WNI_CFG_BSSID,
        currentBssId,
        &cfg ))
    limLog( pMac, LOGP, FL("Could not retrieve BSSID\n"));
    #endif //TO-SUPPORT BT-AMP
    sirCopyMacAddr(currentBssId,psessionEntry->bssId);

    switch( psessionEntry->limSystemRole )
    {
        case eLIM_STA_ROLE:
        case eLIM_BT_AMP_STA_ROLE:
        if(( limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr ) != true ) &&
          (!palEqualMemory( pMac->hHdd,pMlmRemoveKeyReq->peerMacAddr,
                         currentBssId,
                         sizeof(tSirMacAddr))))
        {
            limLog( pMac, LOGW,
            FL("Received MLM_REMOVEKEY_REQ with invalid BSSID\n"));
            limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW );

            // Prepare and Send LIM_MLM_REMOVEKEY_CNF with error code
            mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
            goto end;
        }
        break;

        case eLIM_STA_IN_IBSS_ROLE:
        default: // eLIM_AP_ROLE
                 // Fall thru...
                break;
    }


    psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
    if(limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr )) //Second condition for IBSS or AP role.
    {
        psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_BSS_KEY_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));    
        // Package WDA_REMOVE_BSSKEY_REQ message parameters
        limSendRemoveBssKeyReq( pMac,pMlmRemoveKeyReq,psessionEntry);
        return;
    }

  /**
    * Check if there exists a context for the
    * peer entity for which keys need to be removed.
    */
  pStaDs = dphLookupHashEntry( pMac, pMlmRemoveKeyReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable );
  if ((pStaDs == NULL) ||
         (pStaDs &&
         (pStaDs->mlmStaContext.mlmState !=
                       eLIM_MLM_LINK_ESTABLISHED_STATE)))
  {
     /**
       * Received LIM_MLM_REMOVEKEY_REQ for STA
       * that does not have context or in some
       * transit state. Log error.
       */
      limLog( pMac, LOGW,
          FL("Received MLM_REMOVEKEYS_REQ for STA that either has no context or in some transit state, Addr = "));
      limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW );

      // Prepare and Send LIM_MLM_REMOVEKEY_CNF
      mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
      mlmRemoveKeyCnf.sessionId = pMlmRemoveKeyReq->sessionId;
      

      goto end;
  }
  else
    staIdx = pStaDs->staIndex;
  


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

    // Package WDA_REMOVE_STAKEY_REQ message parameters
    limSendRemoveStaKeyReq( pMac,pMlmRemoveKeyReq,staIdx,psessionEntry);
    return;
 
end:
    limPostSmeRemoveKeyCnf( pMac,
      psessionEntry,
      pMlmRemoveKeyReq,
      &mlmRemoveKeyCnf );

} /*** limProcessMlmRemoveKeyReq() ***/


/**
 * limProcessMinChannelTimeout()
 *
 *FUNCTION:
 * This function is called to process Min Channel Timeout
 * during channel scan.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessMinChannelTimeout(tpAniSirGlobal pMac)
{
    tANI_U8 channelNum;
    
#ifdef GEN6_TODO
    //if the min Channel is maintained per session, then use the below seesionEntry
    //priority - LOW/might not be needed
    
    //TBD-RAJESH HOW TO GET sessionEntry?????
    tpPESession psessionEntry;

    if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimMinChannelTimer.sessionId))== NULL) 
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
        return;
    }
#endif

    
    if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE)
    {
        PELOG1(limLog(pMac, LOG1, FL("Scanning : min channel timeout occurred\n"));)

        /// Min channel timer timed out
        pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff;
        limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
        limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER);
        if (pMac->lim.gLimCurrentScanChannelId <=
                (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
        {
            channelNum = (tANI_U8)limGetCurrentScanChannel(pMac);
        }
        else
        {
            // This shouldn't be the case, but when this happens, this timeout should be for the last channelId. 
            // Get the channelNum as close to correct as possible.
            if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber)
            {
                channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1];
            }
            else
            {
               channelNum = 1;
            }
        }

        limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE);
    }
    else
    {
    /**
         * MIN channel timer should not have timed out
         * in states other than wait_probe_response.
         * Log error.
         */
        limLog(pMac, LOGW,
           FL("received unexpected MIN channel timeout in state %X\n"),
           pMac->lim.gLimMlmState);
        limPrintMlmState(pMac, LOGE, pMac->lim.gLimMlmState);
    }
} /*** limProcessMinChannelTimeout() ***/



/**
 * limProcessMaxChannelTimeout()
 *
 *FUNCTION:
 * This function is called to process Max Channel Timeout
 * during channel scan.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessMaxChannelTimeout(tpAniSirGlobal pMac)
{
    tANI_U8 channelNum;

    
    if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE ||
        pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)
    {
        PELOG1(limLog(pMac, LOG1, FL("Scanning : Max channel timed out\n"));)
        /**
         * MAX channel timer timed out
         * Continue channel scan.
         */
        limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
        limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER);
        pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff;
        if (pMac->lim.gLimCurrentScanChannelId <=
                (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
        {
        channelNum = limGetCurrentScanChannel(pMac);
        }
        else
        {
            if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber)
            {
                channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1];
            }
            else
            {
               channelNum = 1;
            }
        }
        limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE);
    }
    else
    {
        /**
         * MAX channel timer should not have timed out
         * in states other than wait_scan.
         * Log error.
         */
        limLog(pMac, LOGW,
           FL("received unexpected MAX channel timeout in state %X\n"),
           pMac->lim.gLimMlmState);
        limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState);
    }
} /*** limProcessMaxChannelTimeout() ***/

/**
 * limProcessPeriodicProbeReqTimer()
 *
 *FUNCTION:
 * This function is called to process periodic probe request
 *  to send during scan.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac)
{
    tANI_U8 channelNum;
    tANI_U8 i = 0;
    tSirRetStatus status = eSIR_SUCCESS;
    TX_TIMER *pPeriodicProbeReqTimer;
    pPeriodicProbeReqTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer;

    if(vos_timer_getCurrentState(&pPeriodicProbeReqTimer->vosTimer)
         != VOS_TIMER_STATE_STOPPED)
    {
       PELOG1(limLog(pMac, LOG1, FL("Invalid state of timer\n"));)
       return;
    }

    if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) &&
        (pPeriodicProbeReqTimer->sessionId != 0xff))
    {
        tLimMlmScanReq *pLimMlmScanReq = pMac->lim.gpLimMlmScanReq;
        PELOG1(limLog(pMac, LOG1, FL("Scanning : Periodic scanning\n"));)
        /**
         * Periodic channel timer timed out
         * to send probe request.
         */
        channelNum = limGetCurrentScanChannel(pMac);
        do
        {
            /* Prepare and send Probe Request frame for all the SSIDs
             * present in the saved MLM
             */
             
            /*
             * PELOGE(limLog(pMac, LOGW, FL("sending ProbeReq number %d,"
             *                            " for SSID %s on channel: %d\n"),
             *                             i, pLimMlmScanReq->ssId[i].ssId,
             *                                                channelNum);)
             */
            status = limSendProbeReqMgmtFrame( pMac, &pLimMlmScanReq->ssId[i],
                     pLimMlmScanReq->bssId, channelNum, pMac->lim.gSelfMacAddr,
                     pLimMlmScanReq->dot11mode, pLimMlmScanReq->uIEFieldLen,
               (tANI_U8 *)(pLimMlmScanReq) + pLimMlmScanReq->uIEFieldOffset);


            if ( status != eSIR_SUCCESS)
            {
                PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID "
                                             "%s on channel: %d\n"),
                                              pLimMlmScanReq->ssId[i].ssId,
                                              channelNum);)
                return;
            }
            i++;
        } while (i < pLimMlmScanReq->numSsid);

        /* Activate timer again */
        if (tx_timer_activate(pPeriodicProbeReqTimer) != TX_SUCCESS)
        {
             limLog(pMac, LOGP, FL("could not start periodic probe"
                                                   " req timer\n"));
             return;
        }
    }
    else
    {
        /**
         * Periodic scan is timeout is happening in
         * in states other than wait_scan.
         * Log error.
         */
        limLog(pMac, LOG1,
           FL("received unexpected Periodic scan timeout in state %X\n"),
           pMac->lim.gLimMlmState);
    }
} /*** limProcessPeriodicProbeReqTimer() ***/

/**
 * limProcessJoinFailureTimeout()
 *
 *FUNCTION:
 * This function is called to process JoinFailureTimeout
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessJoinFailureTimeout(tpAniSirGlobal pMac)
{
    tLimMlmJoinCnf  mlmJoinCnf;
    tSirMacAddr bssid;
    tANI_U32 len;
    
    //fetch the sessionEntry based on the sessionId
    tpPESession psessionEntry;

    if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimJoinFailureTimer.sessionId))== NULL) 
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
        return;
    }
        
    if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)
    {
        len = sizeof(tSirMacAddr);

        if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, bssid, &len) !=
                            eSIR_SUCCESS)
        {
            /// Could not get BSSID from CFG. Log error.
            limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
            return;
        }

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

        /**
         * Issue MLM join confirm with timeout reason code
         */
        PELOGE(limLog(pMac, LOGE,  FL(" Join Failure Timeout occurred.\n"));)

        mlmJoinCnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE;
        mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;

        psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
        MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
        if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId, 
            psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
            PELOGE(limLog(pMac, LOGE,  FL("Failed to set the LinkState\n"));)
        /* Update PE session Id */
        mlmJoinCnf.sessionId = psessionEntry->peSessionId;
        
       
        // Freeup buffer allocated to join request
        if (psessionEntry->pLimMlmJoinReq)
        {
            palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq);
            psessionEntry->pLimMlmJoinReq = NULL;
        }
        
        limPostSmeMessage(pMac,
                          LIM_MLM_JOIN_CNF,
                          (tANI_U32 *) &mlmJoinCnf);

        return;
    }
    else
    {
        /**
         * Join failure timer should not have timed out
         * in states other than wait_join_beacon state.
         * Log error.
         */
        limLog(pMac, LOGW,
           FL("received unexpected JOIN failure timeout in state %X\n"),psessionEntry->limMlmState);
        limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
    }
} /*** limProcessJoinFailureTimeout() ***/



/**
 * limProcessAuthFailureTimeout()
 *
 *FUNCTION:
 * This function is called to process Min Channel Timeout
 * during channel scan.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessAuthFailureTimeout(tpAniSirGlobal pMac)
{
    //fetch the sessionEntry based on the sessionId
    tpPESession psessionEntry;

    if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAuthFailureTimer.sessionId))== NULL) 
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
        return;
    }
    
    switch (psessionEntry->limMlmState)
    {
        case eLIM_MLM_WT_AUTH_FRAME2_STATE:
        case eLIM_MLM_WT_AUTH_FRAME4_STATE:
            /**
             * Requesting STA did not receive next auth frame
             * before Auth Failure timeout.
             * Issue MLM auth confirm with timeout reason code
             */

             
            limRestoreFromAuthState(pMac,eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
            break;

        default:
            /**
             * Auth failure timer should not have timed out
             * in states other than wt_auth_frame2/4
             * Log error.
             */
            PELOGE(limLog(pMac, LOGE, FL("received unexpected AUTH failure timeout in state %X\n"), psessionEntry->limMlmState);)
            limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);

            break;
    }
} /*** limProcessAuthFailureTimeout() ***/



/**
 * limProcessAuthRspTimeout()
 *
 *FUNCTION:
 * This function is called to process Min Channel Timeout
 * during channel scan.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessAuthRspTimeout(tpAniSirGlobal pMac, tANI_U32 authIndex)
{
    struct tLimPreAuthNode *pAuthNode;
    tpPESession        psessionEntry;
    tANI_U8            sessionId;

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

    if((psessionEntry = peFindSessionByBssid(pMac, pAuthNode->peerMacAddr, &sessionId)) == NULL)
    {
        limLog(pMac, LOGW, FL("session does not exist for given BSSID \n"));
        return;
    } 

    if (psessionEntry->limSystemRole == eLIM_AP_ROLE ||
        psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)
    {
        // Check if there exists a context for the STA

        if (pAuthNode == NULL)
        {
            /**
             * Authentication response timer timedout for an STA
             * that does not have context at AP/STA in IBSS mode.
             */

            // Log error
            PELOGE(limLog(pMac, LOGE, FL("received unexpected message\n"));)
        }
        else
        {
            if (pAuthNode->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE)
            {
                /**
                 * Authentication response timer timedout
                 * in unexpected state. Log error
                 */
                PELOGE(limLog(pMac, LOGE,
                   FL("received unexpected AUTH rsp timeout for MAC address "));
                limPrintMacAddr(pMac, pAuthNode->peerMacAddr, LOGE);)
            }
            else
            {
                // Authentication response timer
                // timedout for an STA.
                pAuthNode->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE;
                pAuthNode->fTimerStarted = 0;
               PELOG1( limLog(pMac, LOG1,
                       FL("AUTH rsp timedout for MAC address "));
                limPrintMacAddr(pMac, pAuthNode->peerMacAddr, LOG1);)

                // Change timer to reactivate it in future
                limDeactivateAndChangePerStaIdTimer(pMac,
                                                    eLIM_AUTH_RSP_TIMER,
                                                    pAuthNode->authNodeIdx);

                limDeletePreAuthNode(pMac, pAuthNode->peerMacAddr);
            }
        }
    }
} /*** limProcessAuthRspTimeout() ***/


/**
 * limProcessAssocFailureTimeout()
 *
 *FUNCTION:
 * This function is called to process Min Channel Timeout
 * during channel scan.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @return None
 */

static void
limProcessAssocFailureTimeout(tpAniSirGlobal pMac, tANI_U32 MsgType)
{

    tLimMlmAssocCnf     mlmAssocCnf;
    tpPESession         psessionEntry;
    
    //to fetch the lim/mlm state based on the sessionId, use the below sessionEntry
    tANI_U8 sessionId;
    
    if(MsgType == LIM_ASSOC)
    {
        sessionId = pMac->lim.limTimers.gLimAssocFailureTimer.sessionId;
    }
    else
    {
        sessionId = pMac->lim.limTimers.gLimReassocFailureTimer.sessionId;
    }
    
    if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) 
    {
        limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
        return;
    }
    
    /**
     * Expected Re/Association Response frame
     * not received within Re/Association Failure Timeout.
     */




    /* CR: vos packet memory is leaked when assoc rsp timeouted/failed. */
    /* notify TL that association is failed so that TL can flush the cached frame  */
    WLANTL_AssocFailed (psessionEntry->staId);

    // Log error
    PELOG1(limLog(pMac, LOG1,
       FL("Re/Association Response not received before timeout \n"));)

    if (( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )||
        ( (psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
          (psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE)  && 
          (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE)))
    {
        /**
         * Re/Assoc failure timer should not have timedout on AP
         * or in a state other than wt_re/assoc_response.
         */

        // Log error
        limLog(pMac, LOGW,
           FL("received unexpected REASSOC failure timeout in state %X for role %d\n"),
           psessionEntry->limMlmState, psessionEntry->limSystemRole);
        limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
    }
    else
    {

        if ((MsgType == LIM_ASSOC) || 
            ((MsgType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)))
        {
            PELOGE(limLog(pMac, LOGE,  FL("(Re)Assoc Failure Timeout occurred.\n"));)

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

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

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

#if defined(ANI_PRODUCT_TYPE_CLIENT)
            //To remove the preauth node in case of fail to associate
            if (limSearchPreAuthList(pMac, psessionEntry->bssId))
            {
                PELOG1(limLog(pMac, LOG1, FL(" delete pre auth node for %02X-%02X-%02X-%02X-%02X-%02X\n"),
                    psessionEntry->bssId[0], psessionEntry->bssId[1], psessionEntry->bssId[2], 
                    psessionEntry->bssId[3], psessionEntry->bssId[4], psessionEntry->bssId[5]);)
                limDeletePreAuthNode(pMac, psessionEntry->bssId);
            }
#endif

            mlmAssocCnf.resultCode =
                            eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE;
            mlmAssocCnf.protStatusCode = 
                            eSIR_MAC_UNSPEC_FAILURE_STATUS;
            
            /* Update PE session Id*/
            mlmAssocCnf.sessionId = psessionEntry->peSessionId;
            if (MsgType == LIM_ASSOC)
                limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
            else 
            {
                /* Will come here only in case of 11r, CCx FT when reassoc rsp 
                   is not received and we receive a reassoc - timesout */
                mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE;
                limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
        }
        }
        else
        {
            /**
             * Restore pre-reassoc req state.
             * Set BSSID to currently associated AP address.
             */
            psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
            MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

            limRestorePreReassocState(pMac, 
                eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry);
        }
    }
} /*** limProcessAssocFailureTimeout() ***/



/**
 * limCompleteMlmScan()
 *
 *FUNCTION:
 * This function is called to send MLM_SCAN_CNF message
 * to SME state machine.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac      Pointer to Global MAC structure
 * @param  retCode   Result code to be sent
 * @return None
 */

void
limCompleteMlmScan(tpAniSirGlobal pMac, tSirResultCodes retCode)
{
    tLimMlmScanCnf    mlmScanCnf;

    /// Restore previous MLM state
    pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState));
    limRestorePreScanState(pMac);

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

    mlmScanCnf.resultCode       = retCode;
    mlmScanCnf.scanResultLength = pMac->lim.gLimMlmScanResultLength;

    limPostSmeMessage(pMac, LIM_MLM_SCAN_CNF, (tANI_U32 *) &mlmScanCnf);

} /*** limCompleteMlmScan() ***/

/**
 * \brief Setup an A-MPDU/BA session
 *
 * \sa limProcessMlmAddBAReq
 *
 * \param pMac The global tpAniSirGlobal object
 *
 * \param pMsgBuf The MLME ADDBA Req message buffer
 *
 * \return none
 */
void limProcessMlmAddBAReq( tpAniSirGlobal pMac,
    tANI_U32 *pMsgBuf )
{
tSirRetStatus status = eSIR_SUCCESS;
tpLimMlmAddBAReq pMlmAddBAReq;
tpLimMlmAddBACnf pMlmAddBACnf;
  tpPESession     psessionEntry;
    
  if(pMsgBuf == NULL)
  {
      PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
           return;
  }

  pMlmAddBAReq = (tpLimMlmAddBAReq) pMsgBuf;
  if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBAReq->sessionId))== NULL)
  {
      PELOGE(limLog(pMac, LOGE,
               FL("session does not exist for given sessionId\n"));)
      palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
      return;
  }
  

  // Send ADDBA Req over the air
  status = limSendAddBAReq( pMac, pMlmAddBAReq,psessionEntry);

  //
  // Respond immediately to LIM, only if MLME has not been
  // successfully able to send WDA_ADDBA_REQ to HAL.
  // Else, LIM_MLM_ADDBA_CNF will be sent after receiving
  // ADDBA Rsp from peer entity
  //
  if( eSIR_SUCCESS != status )
  {
    // Allocate for LIM_MLM_ADDBA_CNF
    if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
                                     (void **) &pMlmAddBACnf,
                                     sizeof( tLimMlmAddBACnf )))
    {
      limLog( pMac, LOGP,
          FL("palAllocateMemory failed with error code %d\n"));
      palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
      return;
    }
    else
    {
        palZeroMemory( pMac->hHdd, (void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ));
        palCopyMemory( pMac->hHdd,
          (void *) pMlmAddBACnf->peerMacAddr,
          (void *) pMlmAddBAReq->peerMacAddr,
          sizeof( tSirMacAddr ));

      pMlmAddBACnf->baDialogToken = pMlmAddBAReq->baDialogToken;
      pMlmAddBACnf->baTID = pMlmAddBAReq->baTID;
      pMlmAddBACnf->baPolicy = pMlmAddBAReq->baPolicy;
      pMlmAddBACnf->baBufferSize = pMlmAddBAReq->baBufferSize;
      pMlmAddBACnf->baTimeout = pMlmAddBAReq->baTimeout;
      pMlmAddBACnf->sessionId = pMlmAddBAReq->sessionId;

      // Update the result code
      pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;

      limPostSmeMessage( pMac,
          LIM_MLM_ADDBA_CNF,
          (tANI_U32 *) pMlmAddBACnf );
    }

    // Restore MLME state
    psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

  }

  // Free the buffer allocated for tLimMlmAddBAReq
  palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );

}

/**
 * \brief Send an ADDBA Rsp to peer STA in response
 * to an ADDBA Req received earlier
 *
 * \sa limProcessMlmAddBARsp
 *
 * \param pMac The global tpAniSirGlobal object
 *
 * \param pMsgBuf The MLME ADDBA Rsp message buffer
 *
 * \return none
 */
void limProcessMlmAddBARsp( tpAniSirGlobal pMac,
    tANI_U32 *pMsgBuf )
{
tpLimMlmAddBARsp pMlmAddBARsp;
   tANI_U16 aid;
   tpDphHashNode pSta;
   tpPESession  psessionEntry;

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

    pMlmAddBARsp = (tpLimMlmAddBARsp) pMsgBuf;

    if(( psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBARsp->sessionId))== NULL)
    {
        PELOGE(limLog(pMac, LOGE,
                  FL("session does not exist for given session ID\n"));)
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
        return;
    }
  

  // Send ADDBA Rsp over the air
  if( eSIR_SUCCESS != limSendAddBARsp( pMac,pMlmAddBARsp,psessionEntry))
  {
    limLog( pMac, LOGE,
    FL("Failed to send ADDBA Rsp to peer \n"));
    limPrintMacAddr( pMac, pMlmAddBARsp->peerMacAddr, LOGE );
    /* Clean the BA context maintained by HAL and TL on failure */
    pSta = dphLookupHashEntry( pMac, pMlmAddBARsp->peerMacAddr, &aid, 
            &psessionEntry->dph.dphHashTable);
     if( NULL != pSta )
    {
        limPostMsgDelBAInd( pMac, pSta, pMlmAddBARsp->baTID, eBA_RECIPIENT, 
                psessionEntry);
    }
  }

  // Time to post a WDA_DELBA_IND to HAL in order
  // to cleanup the HAL and SoftMAC entries


  // Free the buffer allocated for tLimMlmAddBARsp
  palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );

}

/**
 * \brief Setup an A-MPDU/BA session
 *
 * \sa limProcessMlmDelBAReq
 *
 * \param pMac The global tpAniSirGlobal object
 *
 * \param pMsgBuf The MLME DELBA Req message buffer
 *
 * \return none
 */
void limProcessMlmDelBAReq( tpAniSirGlobal pMac,
    tANI_U32 *pMsgBuf )
{
    tSirRetStatus status = eSIR_SUCCESS;
    tpLimMlmDelBAReq pMlmDelBAReq;
    tpLimMlmDelBACnf pMlmDelBACnf;
    tpPESession  psessionEntry;
  
    
    if(pMsgBuf == NULL)
    {
           PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
           return;
    }

  // TODO - Need to validate MLME state
    pMlmDelBAReq = (tpLimMlmDelBAReq) pMsgBuf;

    if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDelBAReq->sessionId))== NULL)
    {
        PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));)
        palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
        return;
    }

  // Send DELBA Ind over the air
  if( eSIR_SUCCESS !=
      (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry)))
    status = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
  else
  {
    tANI_U16 aid;
    tpDphHashNode pSta;

    // Time to post a WDA_DELBA_IND to HAL in order
    // to cleanup the HAL and SoftMAC entries
    pSta = dphLookupHashEntry( pMac, pMlmDelBAReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable);
    if( NULL != pSta )
    {
        status = limPostMsgDelBAInd( pMac,
         pSta,
          pMlmDelBAReq->baTID,
          pMlmDelBAReq->baDirection,psessionEntry);

    }
  }

  //
  // Respond immediately to SME with DELBA CNF using
  // LIM_MLM_DELBA_CNF with appropriate status
  //

  // Allocate for LIM_MLM_DELBA_CNF
  if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
                                   (void **) &pMlmDelBACnf,
                                   sizeof( tLimMlmDelBACnf )))
  {
    limLog( pMac, LOGP, FL("palAllocateMemory failed\n"));
    palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
    return;
  }
  else
  {
    palZeroMemory( pMac->hHdd, (void *) pMlmDelBACnf, sizeof( tLimMlmDelBACnf ));

    palCopyMemory( pMac->hHdd,
        (void *) pMlmDelBACnf,
        (void *) pMlmDelBAReq,
        sizeof( tLimMlmDelBAReq ));

    // Update DELBA result code
    pMlmDelBACnf->delBAReasonCode = pMlmDelBAReq->delBAReasonCode;
    
    /* Update PE session Id*/
    pMlmDelBACnf->sessionId = pMlmDelBAReq->sessionId;

    limPostSmeMessage( pMac,
        LIM_MLM_DELBA_CNF,
        (tANI_U32 *) pMlmDelBACnf );
  }

  // Free the buffer allocated for tLimMlmDelBAReq
  palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );

}

/**
 * @function :  limSMPowerSaveStateInd( )
 *
 * @brief  : This function is called upon receiving the PMC Indication to update the STA's MimoPs State.
 *
 *      LOGIC:
 *
 *      ASSUMPTIONS:
 *          NA
 *
 *      NOTE:
 *          NA
 *
 * @param  pMac - Pointer to Global MAC structure
 * @param  limMsg - Lim Message structure object with the MimoPSparam in body
 * @return None
 */
 
tSirRetStatus
limSMPowerSaveStateInd(tpAniSirGlobal pMac, tSirMacHTMIMOPowerSaveState state)
{
#if 0
    tSirRetStatus           retStatus = eSIR_SUCCESS;  
#if 0
    tANI_U32                  cfgVal1;          
    tANI_U16                   cfgVal2;                 
    tSirMacHTCapabilityInfo *pHTCapabilityInfo;         
    tpDphHashNode pSta = NULL;

    tpPESession psessionEntry  = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
    /** Verify the Mode of operation */    
    if (pMac->lim.gLimSystemRole != eSYSTEM_STA_ROLE) {  
        PELOGE(limLog(pMac, LOGE, FL("Got PMC indication when System not in the STA Role\n"));)       
        return eSIR_FAILURE;       
    }      

    if ((pMac->lim.gHTMIMOPSState == state) || (state == eSIR_HT_MIMO_PS_NA )) { 
        PELOGE(limLog(pMac, LOGE, FL("Got Indication when already in the same mode or State passed is NA:%d \n"),  state);)      
        return eSIR_FAILURE;      
    }     

    if (!pMac->lim.htCapability){        
        PELOGW(limLog(pMac, LOGW, FL(" Not in 11n or HT capable mode\n"));)        
        return eSIR_FAILURE;   
    }        

    /** Update the CFG about the default MimoPS State */
    if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &cfgVal1) != eSIR_SUCCESS) {  
            limLog(pMac, LOGP, FL("could not retrieve HT Cap CFG \n"));    
            return eSIR_FAILURE;     
    }          

    cfgVal2 = (tANI_U16)cfgVal1;            
    pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &cfgVal2;          
    pHTCapabilityInfo->mimoPowerSave = state;

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

    PELOG2(limLog(pMac, LOG2, FL(" The HT Capability for Mimo Pwr is updated to State: %u  \n"),state);)  
    if (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) { 
        PELOG2(limLog(pMac, LOG2,FL(" The STA is not in the Connected/Link Est Sme_State: %d  \n"), pMac->lim.gLimSmeState);)          
        /** Update in the LIM the MIMO PS state of the SELF */   
        pMac->lim.gHTMIMOPSState = state;          
        return eSIR_SUCCESS;    
    }              

    pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);    
    if (!pSta->mlmStaContext.htCapability) {
        limLog( pMac, LOGE,FL( "limSendSMPowerState: Peer is not HT Capable \n" ));
        return eSIR_FAILURE;
    }
     
    if (isEnteringMimoPS(pMac->lim.gHTMIMOPSState, state)) {    
        tSirMacAddr             macAddr;      
        /** Obtain the AP's Mac Address */    
        palCopyMemory(pMac ->hHdd, (tANI_U8 *)macAddr, psessionEntry->bssId, sizeof(tSirMacAddr)); 
        /** Send Action Frame with the corresponding mode */       
        retStatus = limSendSMPowerStateFrame(pMac, macAddr, state);       
        if (retStatus != eSIR_SUCCESS) {         
            PELOGE(limLog(pMac, LOGE, "Update SM POWER: Sending Action Frame has failed\n");)        
            return retStatus;         
        }   
    }    

    /** Update MlmState about the SetMimoPS State */
    pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
    pMac->lim.gLimMlmState = eLIM_MLM_WT_SET_MIMOPS_STATE;
    MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));

    /** Update the HAL and s/w mac about the mode to be set */    
    retStatus = limPostSMStateUpdate( pMac,psessionEntry->staId, state);     

    PELOG2(limLog(pMac, LOG2, " Updated the New SMPS State");)
    /** Update in the LIM the MIMO PS state of the SELF */   
    pMac->lim.gHTMIMOPSState = state;          
#endif
    return retStatus;
#endif
return eSIR_SUCCESS;
}

#ifdef WLAN_FEATURE_11AC
ePhyChanBondState limGet11ACPhyCBState(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 htSecondaryChannelOffset )
{
    ePhyChanBondState cbState = PHY_SINGLE_CHANNEL_CENTERED;

    if(!pMac->lim.apChanWidth)
    {
        return htSecondaryChannelOffset;
    }

    if ( (htSecondaryChannelOffset 
                 == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
       )
    {
        if ((channel + 2 ) == pMac->lim.apCenterChan )
            cbState =  PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
        else if ((channel + 6 ) == pMac->lim.apCenterChan )
            cbState =  PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
        else if ((channel - 2 ) == pMac->lim.apCenterChan )
            cbState =  PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
        else 
            limLog (pMac, LOGP, 
                       FL("Invalid Channel Number = %d Center Chan = %d \n"), 
                                 channel, pMac->lim.apCenterChan);
    }
    if ( (htSecondaryChannelOffset 
                 == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
       )
    {
        if ((channel - 2 ) == pMac->lim.apCenterChan )
            cbState =  PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
        else if ((channel + 2 ) == pMac->lim.apCenterChan )
            cbState =  PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
        else if ((channel - 6 ) == pMac->lim.apCenterChan )
            cbState =  PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
        else 
           limLog (pMac, LOGP, 
                         FL("Invalid Channel Number = %d Center Chan = %d \n"),
                                            channel, pMac->lim.apCenterChan);
    }
    return cbState;
}

#endif

void 
limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId)
{
#if !defined WLAN_FEATURE_VOWIFI
    tANI_U32 localPwrConstraint;
#endif
    tpPESession peSession;

    peSession = peFindSessionBySessionId (pMac, peSessionId);

    if ( NULL == peSession)
    {
       limLog (pMac, LOGP, FL("Invalid PE session = %d\n"), peSessionId);
       return;
    }
#if defined WLAN_FEATURE_VOWIFI  
#ifdef WLAN_FEATURE_11AC
    if ( peSession->vhtCapability )
    {
        limSendSwitchChnlParams( pMac, channel, limGet11ACPhyCBState( pMac,channel,secChannelOffset ), maxTxPower, peSessionId);
    }
    else
#endif
    {
        limSendSwitchChnlParams( pMac, channel, secChannelOffset, maxTxPower, peSessionId);
    }
#else
    if (wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
           limLog(pMac, LOGP, FL("could not read WNI_CFG_LOCAL_POWER_CONSTRAINT from CFG\n"));
           return;
    }
    // Send WDA_CHNL_SWITCH_IND to HAL
#ifdef WLAN_FEATURE_11AC
    if ( peSession->vhtCapability && pMac->lim.vhtCapabilityPresentInBeacon)
    {
        limSendSwitchChnlParams( pMac, channel, limGet11ACPhyCBState( pMac,channel,secChannelOffset ), maxTxPower, peSessionId);
    }
    else
#endif
    {
        limSendSwitchChnlParams( pMac, channel, secChannelOffset, (tPowerdBm)localPwrConstraint, peSessionId);
    }
#endif

 }
