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

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

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


    \file csrApiScan.c

    Implementation for the Common Scan interfaces.
   ========================================================================== */

#include "aniGlobal.h"

#include "palApi.h"
#include "csrInsideApi.h"
#include "smeInside.h"
#include "smsDebug.h"

#include "csrSupport.h"
#include "wlan_qct_tl.h"

#include "vos_diag_core_log.h"
#include "vos_diag_core_event.h"

#include "vos_nvitem.h"
#include "vos_memory.h"
#include "wlan_qct_wda.h"
#include "vos_utils.h"

#define MIN_CHN_TIME_TO_FIND_GO 100
#define MAX_CHN_TIME_TO_FIND_GO 100
#define DIRECT_SSID_LEN 7


/* Purpose of HIDDEN_TIMER 
** When we remove hidden ssid from the profile i.e., forget the SSID via GUI that SSID shouldn't see in the profile
** For above requirement we used timer limit, logic is explained below
** Timer value is initialsed to current time  when it receives corresponding probe response of hidden SSID (The probe request is
** received regularly till SSID in the profile. Once it is removed from profile probe request is not sent.) when we receive probe response
** for broadcast probe request, during update SSID with saved SSID we will diff current time with saved SSID time if it is greater than 1 min
** then we are not updating with old one
*/
                                                                     
#define HIDDEN_TIMER (1*60*1000)                                                                     
#define CSR_SCAN_RESULT_RSSI_WEIGHT     80 // must be less than 100, represent the persentage of new RSSI
                                                                     
/*---------------------------------------------------------------------------
  PER filter constant fraction: it is a %
---------------------------------------------------------------------------*/  
#define CSR_SCAN_PER_FILTER_FRAC 100
                                                                     
/*---------------------------------------------------------------------------
  RSSI filter constant fraction: it is a %
---------------------------------------------------------------------------*/  
#define CSR_SCAN_RSSI_FILTER_FRAC 100

/*---------------------------------------------------------------------------
Convert RSSI into overall score: Since RSSI is in -dBm values, and the 
overall needs to be weighted inversely (where greater value means better
system), we convert.
RSSI *cannot* be more than 0xFF or less than 0 for meaningful WLAN operation
---------------------------------------------------------------------------*/
#define CSR_SCAN_MAX_SCORE_VAL 0xFF
#define CSR_SCAN_MIN_SCORE_VAL 0x0
#define CSR_SCAN_HANDOFF_DELTA 10

#define CSR_PURGE_RSSI_THRESHOLD -70

#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL 140
#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL 120

#ifndef QCA_WIFI_ISOC
#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 30
#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 20
#endif

#define CSR_SCAN_OVERALL_SCORE( rssi )                          \
    (( rssi < CSR_SCAN_MAX_SCORE_VAL )                          \
     ? (CSR_SCAN_MAX_SCORE_VAL-rssi) : CSR_SCAN_MIN_SCORE_VAL)
                                                                     

#define CSR_SCAN_IS_OVER_BSS_LIMIT(pMac)  \
   ( (pMac)->scan.nBssLimit <= (csrLLCount(&(pMac)->scan.scanResultList)) )

#define THIRTY_PERCENT(x)  (x*30/100);

#define MANDATORY_BG_CHANNEL 11

#ifndef CONFIG_ENABLE_LINUX_REG
tCsrIgnoreChannels countryIgnoreList[MAX_COUNTRY_IGNORE] = {
    { {'U','A'}, { 136, 140}, 2},
    { {'T','W'}, { 36, 40, 44, 48, 52}, 5},
    { {'I','D'}, { 165}, 1 },
    { {'A','U'}, { 120, 124, 128}, 3 },
    { {'A','R'}, { 120, 124, 128}, 3 }
    };
#else
tCsrIgnoreChannels countryIgnoreList[MAX_COUNTRY_IGNORE] = { };
#endif //CONFIG_ENABLE_LINUX_REG

//*** This is temporary work around. It need to call CCM api to get to CFG later
/// Get string parameter value
extern tSirRetStatus wlan_cfgGetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32*);

void csrScanGetResultTimerHandler(void *);
void csr_handle_disable_scan(void *pv);
static void csrPurgeScanResultByAge(void *pv);
void csrScanIdleScanTimerHandler(void *);
static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest);
#ifdef WLAN_AP_STA_CONCURRENCY
static void csrStaApConcTimerHandler(void *);
#endif
tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId);
eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand );
void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels );
void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId );
void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode );
void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList );
//if bgPeriod is 0, background scan is disabled. It is in millisecond units
eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod);
eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus);
static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels, 
                                               tANI_U8 numChn, tSirBssDescription *pBssDesc, 
                                               tDot11fBeaconIEs **ppIes );
eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels);
void csrReleaseCmdSingle(tpAniSirGlobal pMac, tSmeCmd *pCommand);
tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel );
void csrPruneChannelListForMode( tpAniSirGlobal pMac, tCsrChannel *pChannelList );
void csrPurgeScanResults(tpAniSirGlobal pMac);




static void csrReleaseScanCmdPendingList(tpAniSirGlobal pMac)
{
    tListElem *pEntry;
    tSmeCmd *pCommand;

    while((pEntry = csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK)) != NULL)
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        if ( eSmeCsrCommandMask & pCommand->command )
        {
            csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_TRUE );
        }
        else
        {
            smsLog(pMac, LOGE, FL("Error: Received command : %d"),pCommand->command);
        }
    }
}
//pResult is invalid calling this function.
void csrFreeScanResultEntry( tpAniSirGlobal pMac, tCsrScanResult *pResult )
{
    if( NULL != pResult->Result.pvIes )
    {
        vos_mem_free(pResult->Result.pvIes);
    }
    vos_mem_free(pResult);
}


static eHalStatus csrLLScanPurgeResult(tpAniSirGlobal pMac, tDblLinkList *pList)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry;
    tCsrScanResult *pBssDesc;
    
    csrLLLock(pList);
    
    while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL)
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        csrFreeScanResultEntry( pMac, pBssDesc );
    }
    
    csrLLUnlock(pList);   
     
    return (status);
}

eHalStatus csrScanOpen( tpAniSirGlobal pMac )
{
    eHalStatus status;
    
    do
    {
        csrLLOpen(pMac->hHdd, &pMac->scan.scanResultList);
        csrLLOpen(pMac->hHdd, &pMac->scan.tempScanResults);
        csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList24);
        csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList5G);
#ifdef WLAN_AP_STA_CONCURRENCY
        csrLLOpen(pMac->hHdd, &pMac->scan.scanCmdPendingList);
#endif
        pMac->scan.fFullScanIssued = eANI_BOOLEAN_FALSE;
        pMac->scan.nBssLimit = CSR_MAX_BSS_SUPPORT;
        status = vos_timer_init(&pMac->scan.hTimerGetResult, VOS_TIMER_TYPE_SW, csrScanGetResultTimerHandler, pMac);
        if (!HAL_STATUS_SUCCESS(status))
        {
            smsLog(pMac, LOGE, FL("cannot allocate memory for getResult timer"));
            break;
        }
#ifdef WLAN_AP_STA_CONCURRENCY
        status = vos_timer_init(&pMac->scan.hTimerStaApConcTimer, VOS_TIMER_TYPE_SW, csrStaApConcTimerHandler, pMac);
        if (!HAL_STATUS_SUCCESS(status))
        {
            smsLog(pMac, LOGE, FL("cannot allocate memory for hTimerStaApConcTimer timer"));
            break;
        }
#endif        
        status = vos_timer_init(&pMac->scan.hTimerIdleScan, VOS_TIMER_TYPE_SW, csrScanIdleScanTimerHandler, pMac);
        if (!HAL_STATUS_SUCCESS(status))
        {
            smsLog(pMac, LOGE, FL("cannot allocate memory for idleScan timer"));
            break;
        }
        status = vos_timer_init(&pMac->scan.disable_scan_during_sco_timer,
                                VOS_TIMER_TYPE_SW,
                                csr_handle_disable_scan,
                                pMac);
        if (!HAL_STATUS_SUCCESS(status)) {
            smsLog(pMac, LOGE,
                   FL("cannot allocate memory for disable_scan_during_sco_timer"));
            break;
        }
    }while(0);
    
    return (status);
}


eHalStatus csrScanClose( tpAniSirGlobal pMac )
{
    csrLLScanPurgeResult(pMac, &pMac->scan.tempScanResults);
    csrLLScanPurgeResult(pMac, &pMac->scan.scanResultList);
#ifdef WLAN_AP_STA_CONCURRENCY
    csrReleaseScanCmdPendingList(pMac);
#endif
    csrLLClose(&pMac->scan.scanResultList);
    csrLLClose(&pMac->scan.tempScanResults);
#ifdef WLAN_AP_STA_CONCURRENCY
    csrLLClose(&pMac->scan.scanCmdPendingList);
#endif
    csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList24);
    csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList5G);
    csrLLClose(&pMac->scan.channelPowerInfoList24);
    csrLLClose(&pMac->scan.channelPowerInfoList5G);
    csrScanDisable(pMac);
    vos_timer_destroy(&pMac->scan.hTimerGetResult);
#ifdef WLAN_AP_STA_CONCURRENCY
    vos_timer_destroy(&pMac->scan.hTimerStaApConcTimer);
#endif
    vos_timer_destroy(&pMac->scan.hTimerIdleScan);
    vos_timer_destroy(&pMac->scan.disable_scan_during_sco_timer);
    return eHAL_STATUS_SUCCESS;
}


eHalStatus csrScanEnable( tpAniSirGlobal pMac )
{
    
    pMac->scan.fScanEnable = eANI_BOOLEAN_TRUE;
    pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
    
    return eHAL_STATUS_SUCCESS;
}


eHalStatus csrScanDisable( tpAniSirGlobal pMac )
{
    
    csrScanStopTimers(pMac);
    pMac->scan.fScanEnable = eANI_BOOLEAN_FALSE;
    
    return eHAL_STATUS_SUCCESS;
}


//Set scan timing parameters according to state of other driver sessions 
//No validation of the parameters is performed. 
static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest)
{
#ifdef WLAN_AP_STA_CONCURRENCY
    if(csrIsAnySessionConnected(pMac))
    {
        //Reset passive scan time as per ini parameter.
        ccmCfgSetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
                     pMac->roam.configParam.nPassiveMaxChnTimeConc,
                     NULL,eANI_BOOLEAN_FALSE);
        //If multi-session, use the appropriate default scan times 
        if(scanType == eSIR_ACTIVE_SCAN)
        {
            pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTimeConc;
            pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTimeConc;
        }
        else
        {
            pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTimeConc;
            pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTimeConc;
        }
        pScanRequest->max_chntime_btc_esco =
            pMac->roam.configParam.max_chntime_btc_esco;
        pScanRequest->min_chntime_btc_esco =
            pMac->roam.configParam.min_chntime_btc_esco;

        pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc;
        
        //Return so that fields set above will not be overwritten.
        return;
    }
#endif

    //This portion of the code executed if multi-session not supported
    //(WLAN_AP_STA_CONCURRENCY not defined) or no multi-session.
    //Use the "regular" (non-concurrency) default scan timing.
    ccmCfgSetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
                     pMac->roam.configParam.nPassiveMaxChnTime,
                     NULL,eANI_BOOLEAN_FALSE);
    if(pScanRequest->scanType == eSIR_ACTIVE_SCAN)
    {
        pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
        pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTime;
    }
    else
    {
        pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
        pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
    }
        pScanRequest->max_chntime_btc_esco =
              pMac->roam.configParam.max_chntime_btc_esco;
        pScanRequest->min_chntime_btc_esco =
              pMac->roam.configParam.min_chntime_btc_esco;

#ifdef WLAN_AP_STA_CONCURRENCY
    //No rest time if no sessions are connected.
    pScanRequest->restTime = 0;
#endif
}

#ifdef WLAN_AP_STA_CONCURRENCY
//Return SUCCESS is the command is queued, else returns eHAL_STATUS_FAILURE 
eHalStatus csrQueueScanRequest( tpAniSirGlobal pMac, tSmeCmd *pScanCmd )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;

    tANI_BOOLEAN fNoCmdPending;
    tSmeCmd *pQueueScanCmd=NULL;
    tSmeCmd *pSendScanCmd=NULL;
    tANI_U8  nNumChanCombinedConc = 0;
    if (NULL == pScanCmd)
    {
        smsLog (pMac, LOGE, FL("Scan Req cmd is NULL"));
        return eHAL_STATUS_FAILURE;
    }
    /* split scan if any one of the following:
     * - STA session is connected and the scan is not a P2P search
     * - any P2P session is connected
     * - STA+SAP. In STA+SAP concurrency, scan requests received on
     *   STA interface when not in connected state are not split.
     *   This can result in large time gap between successive beacons
     *   sent by SAP.
     * Do not split scans if no concurrent infra connections are 
     * active and if the scan is a BG scan triggered by LFR (OR)
     * any scan if LFR is in the middle of a BG scan. Splitting
     * the scan is delaying the time it takes for LFR to find
     * candidates and resulting in disconnects.
     */

    if (csrIsInfraApStarted(pMac) && !csrIsP2pGoSessionConnected(pMac))
    {
      nNumChanCombinedConc = 1;
    }
    else if(csrIsStaSessionConnected(pMac) &&
       !csrIsP2pSessionConnected(pMac))
    {
      nNumChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc;
    }
    else if(csrIsP2pSessionConnected(pMac))
    {
      nNumChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc;
    }
    if ( (csrIsStaSessionConnected(pMac) && 
#ifdef FEATURE_WLAN_LFR
         (csrIsConcurrentInfraConnected(pMac) ||
          ((pScanCmd->u.scanCmd.reason != eCsrScanBgScan) &&
           (pMac->roam.neighborRoamInfo.neighborRoamState != 
            eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) &&
#endif
         (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
            (csrIsP2pSessionConnected(pMac)) )
    {
        tCsrScanRequest scanReq;
        tANI_U8 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
        tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
        tANI_U8    channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
        tANI_BOOLEAN bMemAlloc = eANI_BOOLEAN_FALSE;

        if (numChn == 0)
        {

            numChn = pMac->scan.baseChannels.numChannels;

            pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(numChn);
            if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList  )
            {
                smsLog( pMac, LOGE, FL(" Failed to get memory for channel list ") );
                return eHAL_STATUS_FAILURE;
            }
            bMemAlloc = eANI_BOOLEAN_TRUE;
            vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
                         pMac->scan.baseChannels.channelList, numChn);
            status = eHAL_STATUS_SUCCESS;
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
                pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
                smsLog( pMac, LOGE, FL(" Failed to copy memory to channel list ") );
                return eHAL_STATUS_FAILURE;
            }
            pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn;
        }
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                 "%s: Total Number of channels to scan : %d "
                 "Splitted in group of %d ", __func__, numChn,
                  nNumChanCombinedConc);
        //Whenever we get a scan request with multiple channels we break it up into 2 requests
        //First request  for first channel to scan and second request to scan remaining channels
        if ( numChn > nNumChanCombinedConc)
        {
            vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0);

            pQueueScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
            if (!pQueueScanCmd)
            {
                if (bMemAlloc)
                {
                    vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
                    pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;

                }
                smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer") );
                return eHAL_STATUS_FAILURE;
            }
            pQueueScanCmd->command = pScanCmd->command;
            pQueueScanCmd->sessionId = pScanCmd->sessionId;
            pQueueScanCmd->u.scanCmd.callback = pScanCmd->u.scanCmd.callback;
            pQueueScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
            pQueueScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
            pQueueScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around

            /* First copy all the parameters to local variable of scan request */
            csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);

            /* Now modify the elements of local var scan request required to be modified for split scan */
            if(scanReq.ChannelInfo.ChannelList != NULL)
            {
                vos_mem_free(scanReq.ChannelInfo.ChannelList);
                scanReq.ChannelInfo.ChannelList = NULL;
            }

            pChnInfo->numOfChannels = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels - nNumChanCombinedConc;

            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
                    FL(" &channelToScan %pK pScanCmd(%pK) pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList(%pK)numChn(%d)"),
                    &channelToScan[0], pScanCmd,
                    pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn);

            vos_mem_copy(&channelToScan[0],
                     &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[
                     nNumChanCombinedConc],
                     pChnInfo->numOfChannels * sizeof(tANI_U8));

            pChnInfo->ChannelList = &channelToScan[0];

            scanReq.BSSType = eCSR_BSS_TYPE_ANY;

            //Use concurrency values for min/maxChnTime.
            //We know csrIsAnySessionConnected(pMac) returns TRUE here
            csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);

            status = csrScanCopyRequest(pMac, &pQueueScanCmd->u.scanCmd.u.scanRequest, &scanReq);

            if(!HAL_STATUS_SUCCESS(status))
            {
                if (bMemAlloc)
                {
                    vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
                    pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;

                }
                if( scanReq.pIEField != NULL)
                {
                    vos_mem_free(scanReq.pIEField);
                    scanReq.pIEField = NULL;
                }
                smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d"), status );
                return eHAL_STATUS_FAILURE;
            }
            /* Clean the local scan variable */
            scanReq.ChannelInfo.ChannelList = NULL;
            scanReq.ChannelInfo.numOfChannels = 0;
            csrScanFreeRequest(pMac, &scanReq);

            /* setup the command to scan 2 channels */
            pSendScanCmd = pScanCmd;
            pSendScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nNumChanCombinedConc;
            pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY;

            //Use concurrency values for min/maxChnTime.
            //We know csrIsAnySessionConnected(pMac) returns TRUE here
            csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest);
            pSendScanCmd->u.scanCmd.callback = NULL;
        } else {
            pSendScanCmd = pScanCmd;
            pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY;

            //Use concurrency values for min/maxChnTime.
            //We know csrIsAnySessionConnected(pMac) returns TRUE here
            csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest);
        }

        fNoCmdPending = csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK );

        //Logic Below is as follows
        // If the scanCmdPendingList is empty then we directly send that command
        // to smeCommandQueue else we buffer it in our scanCmdPendingList Queue
        if( fNoCmdPending )
        {
            if (pQueueScanCmd != NULL)
            {            
                csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
            }

            if (pSendScanCmd != NULL)
            {            
                return csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE);
            }
        }
        else
        {
            if (pSendScanCmd != NULL)
            {
                csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pSendScanCmd->Link, LL_ACCESS_LOCK );
            }

            if (pQueueScanCmd != NULL)
            {
                csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
            }
        }
    }
    else
    {  //No concurrency case
        smsLog( pMac, LOG2, FL("Queuing scan command (reason=%d, roamState=%d"
                " numOfChannels=%d)"),
                pScanCmd->u.scanCmd.reason, 
                pMac->roam.neighborRoamInfo.neighborRoamState,
                pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels);
        return csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
    }

    return ( status );
}
#endif

/* ---------------------------------------------------------------------------
    \fn csrScan2GOnyRequest
    \brief This function will update the scan request with only 
           2.4GHz valid channel list.
    \param pMac
    \param pScanCmd
    \param pScanRequest
    \return None
  -------------------------------------------------------------------------------*/
static void csrScan2GOnyRequest(tpAniSirGlobal pMac,tSmeCmd *pScanCmd, 
                                tCsrScanRequest *pScanRequest)
{
    tANI_U8 index, channelId, channelListSize = 0;
    tANI_U8 channelList2G[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
    static tANI_U8 validchannelList[CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS] = {0};

    VOS_ASSERT(pScanCmd && pScanRequest);
    /* To silence the KW tool null check is added */
    if((pScanCmd == NULL) || (pScanRequest == NULL))
    { 
        smsLog( pMac, LOGE, FL(" pScanCmd or pScanRequest is NULL "));
        return;
    }    

    if (pScanCmd->u.scanCmd.scanID ||
       (eCSR_SCAN_REQUEST_FULL_SCAN != pScanRequest->requestType))
           return;

    //Contsruct valid Supported 2.4 GHz Channel List
    for( index = 0; index < ARRAY_SIZE(channelList2G); index++ )
    {
        channelId = channelList2G[index];
        if ( csrIsSupportedChannel( pMac, channelId ) )
        {
            validchannelList[channelListSize++] = channelId;
        }
    }

    pScanRequest->ChannelInfo.numOfChannels = channelListSize;
    pScanRequest->ChannelInfo.ChannelList = validchannelList;
}

eHalStatus csrScanRequest(tpAniSirGlobal pMac, tANI_U16 sessionId, 
              tCsrScanRequest *pScanRequest, tANI_U32 *pScanRequestID, 
              csrScanCompleteCallback callback, void *pContext)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tSmeCmd *pScanCmd = NULL;
    eCsrConnectState ConnectState;

    if(pScanRequest == NULL)
    {
        smsLog( pMac, LOGE, FL(" pScanRequest is NULL"));
        VOS_ASSERT(0);
        return eHAL_STATUS_FAILURE ;
    }

    /* During group formation, the P2P client scans for GO with the specific SSID.
     * There will be chances of GO switching to other channels because of scan or
     * to STA channel in case of STA+GO MCC scenario. So to increase the possibility
     * of client to find the GO, the dwell time of scan is increased to 100ms.
     */
    if(pScanRequest->p2pSearch)
    {
        if(pScanRequest->SSIDs.numOfSSIDs)
        {
            //If the scan request is for specific SSId the length of SSID will be
            //greater than 7 as SSID for p2p search contains "DIRECT-")
            if(pScanRequest->SSIDs.SSIDList->SSID.length > DIRECT_SSID_LEN)
            {
                smsLog( pMac, LOG1, FL("P2P: Increasing the min and max Dwell"
                        " time to %d for specific SSID scan %.*s"),
                        MAX_CHN_TIME_TO_FIND_GO,
                        pScanRequest->SSIDs.SSIDList->SSID.length,
                        pScanRequest->SSIDs.SSIDList->SSID.ssId);
                pScanRequest->maxChnTime = MAX_CHN_TIME_TO_FIND_GO;
                pScanRequest->minChnTime = MIN_CHN_TIME_TO_FIND_GO;
            }
        }
    }

    do
    {
        if(pMac->scan.fScanEnable)
        {
            pScanCmd = csrGetCommandBuffer(pMac);
            if(pScanCmd)
            {
                vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
                pScanCmd->command = eSmeCommandScan; 
                pScanCmd->sessionId = sessionId;
                pScanCmd->u.scanCmd.callback = callback;
                pScanCmd->u.scanCmd.pContext = pContext;
                if(eCSR_SCAN_REQUEST_11D_SCAN == pScanRequest->requestType)
                {
                    pScanCmd->u.scanCmd.reason = eCsrScan11d1;
                }
                else if((eCSR_SCAN_REQUEST_FULL_SCAN == pScanRequest->requestType) ||
                        (eCSR_SCAN_P2P_DISCOVERY == pScanRequest->requestType)
#ifdef SOFTAP_CHANNEL_RANGE
                        ||(eCSR_SCAN_SOFTAP_CHANNEL_RANGE == pScanRequest->requestType)
#endif
                 )
                {
                    pScanCmd->u.scanCmd.reason = eCsrScanUserRequest;
                }
                else if(eCSR_SCAN_HO_BG_SCAN == pScanRequest->requestType)
                {
                    pScanCmd->u.scanCmd.reason = eCsrScanBgScan;
                }
                else if(eCSR_SCAN_HO_PROBE_SCAN == pScanRequest->requestType)
                {
                    pScanCmd->u.scanCmd.reason = eCsrScanProbeBss;
                }
                else if(eCSR_SCAN_P2P_FIND_PEER == pScanRequest->requestType)
                {
                    pScanCmd->u.scanCmd.reason = eCsrScanP2PFindPeer;
                }
                else
                {
                    pScanCmd->u.scanCmd.reason = eCsrScanIdleScan;
                }
                if(pScanRequest->minChnTime == 0 && pScanRequest->maxChnTime == 0)
                {
                    //The caller doesn't set the time correctly. Set it here
                    csrSetDefaultScanTiming(pMac, pScanRequest->scanType,
                                             pScanRequest);
                    smsLog(pMac, LOG1, FL("Setting default min %d and max %d"
                            " ChnTime"), pScanRequest->minChnTime,
                              pScanRequest->maxChnTime);
                }
#ifdef WLAN_AP_STA_CONCURRENCY
                if(pScanRequest->restTime == 0)
                {
                    //Need to set restTime only if at least one session is connected
                    if(csrIsAnySessionConnected(pMac))
                    {
                        pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc;
                    }
                }
#endif
                 /*For Standalone wlan : channel time will remain the same.
                   For BTC with A2DP up: Channel time = Channel time * 2, if station is not already associated.
                   This has been done to provide a larger scan window for faster connection during btc.Else Scan is seen
                   to take a long time.
                   For BTC with A2DP up: Channel time will not be doubled, if station is already associated.
                 */
                status = csrRoamGetConnectState(pMac,sessionId,&ConnectState);
                if (HAL_STATUS_SUCCESS(status) &&
                    pMac->btc.fA2DPUp &&
                   (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED != ConnectState) &&
                   (eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED != ConnectState))
                {
                    pScanRequest->maxChnTime = pScanRequest->maxChnTime << 1;
                    pScanRequest->minChnTime = pScanRequest->minChnTime << 1;
                    smsLog( pMac, LOG1, FL("BTC A2DP up, doubling max and min"
                            " ChnTime (Max=%d Min=%d)"),
                            pScanRequest->maxChnTime,
                            pScanRequest->minChnTime);
                }  

                pScanRequest->max_chntime_btc_esco =
                    pMac->roam.configParam.max_chntime_btc_esco;
                pScanRequest->min_chntime_btc_esco =
                    pMac->roam.configParam.min_chntime_btc_esco;
                //Need to make the following atomic
                pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
                
                if(pScanRequestID)
                {
                    *pScanRequestID = pScanCmd->u.scanCmd.scanID; 
                }

                // If it is the first scan request from HDD, CSR checks if it is for 11d. 
                // If it is not, CSR will save the scan request in the pending cmd queue 
                // & issue an 11d scan request to PE.
                if (((0 == pScanCmd->u.scanCmd.scanID)
                   && (eCSR_SCAN_REQUEST_11D_SCAN != pScanRequest->requestType))
#ifdef SOFTAP_CHANNEL_RANGE
                   && (eCSR_SCAN_SOFTAP_CHANNEL_RANGE != pScanRequest->requestType)
#endif                   
                   && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d)
                   )
                {
                    tSmeCmd *p11dScanCmd;
                    tCsrScanRequest scanReq;
                    tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;

                    vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0);

                    p11dScanCmd = csrGetCommandBuffer(pMac);
                    if (p11dScanCmd)
                    {
                        tANI_U32 numChn = pMac->scan.baseChannels.numChannels;

                        vos_mem_set(&p11dScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
                        pChnInfo->ChannelList = vos_mem_malloc(numChn);
                        if ( NULL == pChnInfo->ChannelList )
                        {
                            smsLog(pMac, LOGE, FL("Failed to allocate memory"));
                            status = eHAL_STATUS_FAILURE;
                            break;
                        }
                        vos_mem_copy(pChnInfo->ChannelList,
                                     pMac->scan.baseChannels.channelList,
                                     numChn);
                        pChnInfo->numOfChannels = (tANI_U8)numChn;

                        p11dScanCmd->command = eSmeCommandScan;
                        p11dScanCmd->u.scanCmd.callback = pMac->scan.callback11dScanDone;
                        p11dScanCmd->u.scanCmd.pContext = NULL;
                        p11dScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID;
                        scanReq.BSSType = eCSR_BSS_TYPE_ANY;

                        if ( csrIs11dSupported(pMac) )
                        {
                            scanReq.scanType = eSIR_PASSIVE_SCAN;
                            scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
                            p11dScanCmd->u.scanCmd.reason = eCsrScan11d1;
                            scanReq.maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
                            scanReq.minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
                        }
                        else
                        {
                            scanReq.scanType = pScanRequest->scanType;
                            scanReq.requestType = eCSR_SCAN_IDLE_MODE_SCAN;
                            p11dScanCmd->u.scanCmd.reason = eCsrScanIdleScan;
                            scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
                            scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime;

                            scanReq.max_chntime_btc_esco =
                                 pMac->roam.configParam.max_chntime_btc_esco;
                            scanReq.min_chntime_btc_esco =
                                 pMac->roam.configParam.min_chntime_btc_esco;
                        }
                        if (pMac->roam.configParam.nInitialDwellTime)
                        {
                            scanReq.maxChnTime =
                                     pMac->roam.configParam.nInitialDwellTime;
                            smsLog(pMac, LOG1, FL("11d scan, updating"
                                   "dwell time for first scan %u"),
                                    scanReq.maxChnTime);
                        }
                        if ((pScanCmd->u.scanCmd.reason == eCsrScanUserRequest)
                           && !(pScanRequest->p2pSearch)
                           &&(pScanRequest->ChannelInfo.numOfChannels
                           < pMac->roam.configParam.
                                 max_chan_for_dwell_time_cfg))
                        {
                            pScanRequest->maxChnTime =
                                    pScanRequest->maxChnTime << 1;
                            pScanRequest->minChnTime =
                                    pScanRequest->minChnTime << 1;
                            smsLog(pMac, LOG1,
                                    FL("Double ChnTime (Max=%d Min=%d) numOfChannels=%d max_chan_for_dwell_time_cfg=%d"),
                                    pScanRequest->maxChnTime,
                                    pScanRequest->minChnTime,
                                    pScanRequest->ChannelInfo.numOfChannels,
                                    pMac->roam.configParam.
                                        max_chan_for_dwell_time_cfg);
                        }

                        status = csrScanCopyRequest(pMac, &p11dScanCmd->u.scanCmd.u.scanRequest, &scanReq);
                        //Free the channel list
                        vos_mem_free(pChnInfo->ChannelList);
                        pChnInfo->ChannelList = NULL;

                        if (HAL_STATUS_SUCCESS(status))
                        {
                             pMac->scan.scanProfile.numOfChannels =
                               p11dScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
                            //Start process the command
#ifdef WLAN_AP_STA_CONCURRENCY
                            if (!pMac->fScanOffload)
                                status = csrQueueScanRequest(pMac, p11dScanCmd);
                            else
                                status = csrQueueSmeCommand(pMac, p11dScanCmd,
                                                            eANI_BOOLEAN_FALSE);
#else
                            status = csrQueueSmeCommand(pMac, p11dScanCmd, eANI_BOOLEAN_FALSE);
#endif                   
                            if( !HAL_STATUS_SUCCESS( status ) )
                            {
                                smsLog(pMac, LOGE, FL("Failed to send message"
                                        " status = %d"), status);
                                break;
                            }
                        }
                        else 
                        {
                            smsLog(pMac, LOGE, FL("csrScanCopyRequest failed"));
                            break;
                        }
                    }
                    else
                    {
                        //error
                        smsLog( pMac, LOGE, FL("p11dScanCmd failed") );
                        break;
                    }
                }

                //Scan only 2G Channels if set in ini file
                //This is mainly to reduce the First Scan duration
                //Once we turn on Wifi
                if(pMac->scan.fFirstScanOnly2GChnl)
                {
                    smsLog( pMac, LOG1, FL("Scanning only 2G Channels during first scan"));
                    csrScan2GOnyRequest(pMac, pScanCmd, pScanRequest);
                }

                if (pMac->roam.configParam.nInitialDwellTime)
                {
                    pScanRequest->maxChnTime =
                            pMac->roam.configParam.nInitialDwellTime;
                    pMac->roam.configParam.nInitialDwellTime = 0;
                    smsLog(pMac, LOG1,
                                 FL("updating dwell time for first scan %u"),
                                 pScanRequest->maxChnTime);
                }

                if ((pScanCmd->u.scanCmd.reason == eCsrScanUserRequest)
                         && !(pScanRequest->p2pSearch)
                         && (pScanRequest->ChannelInfo.numOfChannels
                         < pMac->roam.configParam.max_chan_for_dwell_time_cfg))
                {
                    pScanRequest->maxChnTime = pScanRequest->maxChnTime << 1;
                    pScanRequest->minChnTime = pScanRequest->minChnTime << 1;
                    smsLog(pMac, LOG1,
                            FL("Double ChnTime (Max=%d Min=%d) numOfChannels=%d max_chan_for_dwell_time_cfg=%d"),
                            pScanRequest->maxChnTime,
                            pScanRequest->minChnTime,
                            pScanRequest->ChannelInfo.numOfChannels,
                            pMac->roam.configParam.max_chan_for_dwell_time_cfg);
                }
                status = csrScanCopyRequest(pMac, &pScanCmd->u.scanCmd.u.scanRequest, pScanRequest);
                if(HAL_STATUS_SUCCESS(status))
                {
                    tCsrScanRequest *pTempScanReq =
                     &pScanCmd->u.scanCmd.u.scanRequest;
                    pMac->scan.scanProfile.numOfChannels =
                     pTempScanReq->ChannelInfo.numOfChannels;

                    smsLog( pMac, LOG1, FL(" SId=%d scanId=%d"
                             " Scan reason=%u numSSIDs=%d"
                             " numChan=%d P2P search=%d minCT=%d maxCT=%d"
                             " minCBtc=%d maxCBtx=%d"),
                             sessionId, pScanCmd->u.scanCmd.scanID,
                             pScanCmd->u.scanCmd.reason,
                             pTempScanReq->SSIDs.numOfSSIDs,
                             pTempScanReq->ChannelInfo.numOfChannels,
                             pTempScanReq->p2pSearch,
                             pTempScanReq->minChnTime,
                             pTempScanReq->maxChnTime,
                             pTempScanReq->min_chntime_btc_esco,
                             pTempScanReq->max_chntime_btc_esco);
                    //Start process the command
#ifdef WLAN_AP_STA_CONCURRENCY
                    if (!pMac->fScanOffload)
                        status = csrQueueScanRequest(pMac,pScanCmd);
                    else
                        status = csrQueueSmeCommand(pMac, pScanCmd,
                                                    eANI_BOOLEAN_FALSE);
#else
                    status = csrQueueSmeCommand(pMac, pScanCmd,
                                                 eANI_BOOLEAN_FALSE);
#endif
                    if( !HAL_STATUS_SUCCESS( status ) )
                    {
                        smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                        break;
                    }
                }
                else 
                {
                    smsLog( pMac, LOGE, FL(" fail to copy request status = %d"), status );
                    break;
                }
            }
            else 
            {
                smsLog( pMac, LOGE, FL(" pScanCmd is NULL"));
                break;
            }
        }
        else
        {
            smsLog( pMac, LOGE, FL("SId: %d Scanning not enabled"
                     " Scan type=%u, numOfSSIDs=%d P2P search=%d"),
                     sessionId, pScanRequest->requestType,
                     pScanRequest->SSIDs.numOfSSIDs,
                     pScanRequest->p2pSearch );
        }
    } while(0);


    if(!HAL_STATUS_SUCCESS(status) && pScanCmd)
    {
        if( eCsrScanIdleScan == pScanCmd->u.scanCmd.reason )
        {
            //Set the flag back for restarting idle scan
            pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
        }
        smsLog( pMac, LOGE, FL(" SId: %d Failed with status=%d"
                 " Scan reason=%u numOfSSIDs=%d"
                 " P2P search=%d scanId=%d"),
                 sessionId, status, pScanCmd->u.scanCmd.reason,
                 pScanRequest->SSIDs.numOfSSIDs, pScanRequest->p2pSearch,
                 pScanCmd->u.scanCmd.scanID );
        csrReleaseCommandScan(pMac, pScanCmd);
    }

    return (status);
}


eHalStatus csrScanRequestResult(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pScanCmd;
    
    if(pMac->scan.fScanEnable)
    {
        pScanCmd = csrGetCommandBuffer(pMac);
        if(pScanCmd)
        {
            pScanCmd->command = eSmeCommandScan;
            vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
            pScanCmd->u.scanCmd.callback = NULL;
            pScanCmd->u.scanCmd.pContext = NULL;
            pScanCmd->u.scanCmd.reason = eCsrScanGetResult;
            //Need to make the following atomic
            pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around
            status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                csrReleaseCommandScan(pMac, pScanCmd);
            }
        }
        else 
        {
            //log error
            smsLog(pMac, LOGE, FL("can not obtain a common buffer"));
            status = eHAL_STATUS_RESOURCES;
        }
    }
    
    return (status);
}

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
eHalStatus csrScanRequestLfrResult(tpAniSirGlobal pMac, tANI_U32 sessionId,
                                   csrScanCompleteCallback callback, void *pContext)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pScanCmd;

    if (pMac->scan.fScanEnable)
    {
        pScanCmd = csrGetCommandBuffer(pMac);
        if (pScanCmd)
        {
            pScanCmd->command = eSmeCommandScan;
            pScanCmd->sessionId = sessionId;
            vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
            pScanCmd->u.scanCmd.callback = callback;
            pScanCmd->u.scanCmd.pContext = pContext;
            pScanCmd->u.scanCmd.reason = eCsrScanGetLfrResult;
            //Need to make the following atomic
            pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around
            status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_TRUE);
            if ( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
                csrReleaseCommandScan(pMac, pScanCmd);
            }
        }
        else
        {
            //log error
            smsLog(pMac, LOGE, FL("can not obtain a common buffer\n"));
            status = eHAL_STATUS_RESOURCES;
        }
    }

    return (status);
}
#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD

eHalStatus csrScanAllChannels(tpAniSirGlobal pMac, eCsrRequestType reqType)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_U32 scanId;
    tCsrScanRequest scanReq;

    vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0);
    scanReq.BSSType = eCSR_BSS_TYPE_ANY;
    scanReq.scanType = eSIR_ACTIVE_SCAN;
    scanReq.requestType = reqType;
    scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
    scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
    scanReq.max_chntime_btc_esco =
           pMac->roam.configParam.max_chntime_btc_esco;
    scanReq.min_chntime_btc_esco =
           pMac->roam.configParam.min_chntime_btc_esco;
    //Scan with invalid sessionId. 
    //This results in SME using the first available session to scan.
    status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq, 
                            &scanId, NULL, NULL);

    return (status);
}




eHalStatus csrIssueRoamAfterLostlinkScan(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamReason reason)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tScanResultHandle hBSSList = NULL;
    tCsrScanResultFilter *pScanFilter = NULL;
    tANI_U32 roamId = 0;
    tCsrRoamProfile *pProfile = NULL;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    do
    {
        smsLog(pMac, LOG1, " csrIssueRoamAfterLostlinkScan called");
        if(pSession->fCancelRoaming)
        {
            smsLog(pMac, LOGW, " lostlink roaming is cancelled");
            csrScanStartIdleScan(pMac);
            status = eHAL_STATUS_SUCCESS;
            break;
        }
        //Here is the profile we need to connect to
        pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
        if ( NULL == pScanFilter)
                status = eHAL_STATUS_FAILURE;
        else
                status = eHAL_STATUS_SUCCESS;
        if (!HAL_STATUS_SUCCESS(status))
            break;
        vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
        if(NULL == pSession->pCurRoamProfile)
        {
            pScanFilter->EncryptionType.numEntries = 1;
            pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
        }
        else
        {
            //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect
            pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile));
            if ( NULL == pProfile )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if (!HAL_STATUS_SUCCESS(status))
                  break;
            vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
            status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile);
            if(!HAL_STATUS_SUCCESS(status))
                break;
            status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter);
        }//We have a profile
        roamId = GET_NEXT_ROAM_ID(&pMac->roam);
        if(HAL_STATUS_SUCCESS(status))
        {
            status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
            if(HAL_STATUS_SUCCESS(status))
            {
                if(eCsrLostLink1 == reason)
                {
                    //we want to put the last connected BSS to the very beginning, if possible
                    csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList);
                }
                status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, reason, 
                                                roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
                if(!HAL_STATUS_SUCCESS(status))
                {
                    csrScanResultPurge(pMac, hBSSList);
                }
            }//Have scan result
        }
    }while(0);
    if(pScanFilter)
    {
        //we need to free memory for filter if profile exists
        csrFreeScanFilter(pMac, pScanFilter);
        vos_mem_free(pScanFilter);
    }
    if(NULL != pProfile)
    {
        csrReleaseProfile(pMac, pProfile);
        vos_mem_free(pProfile);
    }

    return (status);
}


eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pScanCmd;
    
    if(pMac->scan.fScanEnable)
    {
        pScanCmd = csrGetCommandBuffer(pMac);
        if(pScanCmd)
        {
            pScanCmd->command = eSmeCommandScan;
            vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
            pScanCmd->u.scanCmd.reason = eCsrScanGetScanChnInfo;
            //Need to make the following atomic
            pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
            pScanCmd->sessionId = pCommand->sessionId;
            if( pCommand->u.scanCmd.reason == eCsrScanUserRequest)
            {
                 pScanCmd->u.scanCmd.callback = NULL;
                 pScanCmd->u.scanCmd.pContext = NULL;
            } else {
                 pScanCmd->u.scanCmd.callback = pCommand->u.scanCmd.callback;
                 pScanCmd->u.scanCmd.pContext = pCommand->u.scanCmd.pContext;
                 pScanCmd->u.scanCmd.abortScanIndication =
                           pCommand->u.scanCmd.abortScanIndication;
            }
            status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                csrReleaseCommandScan(pMac, pScanCmd);
            }
        }
        else 
        {
            //log error
            smsLog(pMac, LOGE, FL("can not obtain a common buffer"));
            status = eHAL_STATUS_RESOURCES;
        }
    }
    
    return (status);
}


eHalStatus csrScanHandleFailedLostlink1(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, "  Lostlink scan 1 failed");
    if(pSession->fCancelRoaming)
    {
        csrScanStartIdleScan(pMac);
    }
    else if(pSession->pCurRoamProfile)
    {
        //We fail lostlink1 but there may be other BSS in the cached result fit the profile. Give it a try first
        if(pSession->pCurRoamProfile->SSIDs.numOfSSIDs == 0 ||
            pSession->pCurRoamProfile->SSIDs.numOfSSIDs > 1)
        {
            //try lostlink scan2
            status = csrScanRequestLostLink2(pMac, sessionId);
        }
        else if(!pSession->pCurRoamProfile->ChannelInfo.ChannelList || 
                pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0)
        {
            //go straight to lostlink scan3
            status = csrScanRequestLostLink3(pMac, sessionId);
        }
        else
        {
            //we are done with lostlink
            if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
            {
                csrScanStartIdleScan(pMac);
            }
            status = eHAL_STATUS_SUCCESS;
        }
    }
    else
    {
        status = csrScanRequestLostLink3(pMac, sessionId);
    }

    return (status);    
}



eHalStatus csrScanHandleFailedLostlink2(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, "  Lostlink scan 2 failed");
    if(pSession->fCancelRoaming)
    {
        csrScanStartIdleScan(pMac);
    }
    else if(!pSession->pCurRoamProfile || !pSession->pCurRoamProfile->ChannelInfo.ChannelList || 
                pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0)
    {
        //try lostlink scan3
        status = csrScanRequestLostLink3(pMac, sessionId);
    }
    else
    {
        //we are done with lostlink
        if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
        {
            csrScanStartIdleScan(pMac);
        }
    }

    return (status);    
}



eHalStatus csrScanHandleFailedLostlink3(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;

    smsLog(pMac, LOGW, "  Lostlink scan 3 failed");
    if(eANI_BOOLEAN_TRUE == csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
    {
        //we are done with lostlink
        csrScanStartIdleScan(pMac);
    }
    
    return (status);    
}




//Lostlink1 scan is to actively scan the last connected profile's SSID on all matched BSS channels.
//If no roam profile (it should not), it is like lostlinkscan3
eHalStatus csrScanRequestLostLink1( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pCommand = NULL;
    tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    tCsrScanResultFilter *pScanFilter = NULL;
    tScanResultHandle hBSSList = NULL;
    tCsrScanResultInfo *pScanResult = NULL;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, FL(" called"));
    do
    {
        pCommand = csrGetCommandBuffer(pMac);
        if(!pCommand)
        {
            status = eHAL_STATUS_RESOURCES;
            break;
        }
        vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
        pCommand->command = eSmeCommandScan;
        pCommand->sessionId = (tANI_U8)sessionId;
        pCommand->u.scanCmd.reason = eCsrScanLostLink1;
        pCommand->u.scanCmd.callback = NULL;
        pCommand->u.scanCmd.pContext = NULL;
        pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
        pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
        pCommand->u.scanCmd.u.scanRequest.max_chntime_btc_esco =
               pMac->roam.configParam.max_chntime_btc_esco;
        pCommand->u.scanCmd.u.scanRequest.min_chntime_btc_esco =
               pMac->roam.configParam.min_chntime_btc_esco;
        pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
        if(pSession->connectedProfile.SSID.length)
        {
            pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
            if ( NULL == pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if(!HAL_STATUS_SUCCESS(status))
            {
                break;
            }
            pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1;
            vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID,
                         &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
        }
        else
        {
            pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 0;
        }
        if(pSession->pCurRoamProfile)
        {
            pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
            if ( NULL == pScanFilter )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if(!HAL_STATUS_SUCCESS(status))
            {
                break;
            }
            vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
            status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
            if(!HAL_STATUS_SUCCESS(status))
            {
                break;
            }
            //Don't change variable status here because whether we can get result or not, the command goes to PE.
            //The status is also used to indicate whether the command is queued. Not success meaning not queue
            if(HAL_STATUS_SUCCESS((csrScanGetResult(pMac, pScanFilter, &hBSSList))) && hBSSList)
            {
                tANI_U8 i, nChn = 0;
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList =
                               vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN);
                if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList )
                        status = eHAL_STATUS_FAILURE;
                else
                        status = eHAL_STATUS_SUCCESS;
                if(!HAL_STATUS_SUCCESS(status))
                {
                    break;
                }
                while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) &&
                    nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN)
                {
                    for(i = 0; i < nChn; i++)
                    {
                        if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == 
                                        pScanResult->BssDescriptor.channelId)
                        {
                            break;
                        }
                    }
                    if(i == nChn)
                    {
                        pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId;
                    }
                }
                //Include the last connected BSS' channel
                if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel))
                {
                    for(i = 0; i < nChn; i++)
                    {
                        if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == 
                                        pSession->connectedProfile.operationChannel)
                        {
                            break;
                        }
                    }
                    if(i == nChn)
                    {
                        pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pSession->connectedProfile.operationChannel;
                    }
                }
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn;
            }
            else
            {
                if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel))
                {
                    pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(1);
                    if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList )
                        status = eHAL_STATUS_FAILURE;
                    else
                        status = eHAL_STATUS_SUCCESS;
                    //just try the last connected channel
                    if(HAL_STATUS_SUCCESS(status))
                    {
                        pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0] = pSession->connectedProfile.operationChannel;
                        pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 1;
                    }
                    else 
                    {
                        break;
                    }
                }
            }
        }
        vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid));
        status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
        if( !HAL_STATUS_SUCCESS( status ) )
        {
            smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
            break;
        }
    } while( 0 );

    if(!HAL_STATUS_SUCCESS(status))
    {
        smsLog(pMac, LOGW, " csrScanRequestLostLink1 failed with status %d", status);
        if(pCommand)
        {
            csrReleaseCommandScan(pMac, pCommand);
        }
        status = csrScanHandleFailedLostlink1( pMac, sessionId );
    }
    if(pScanFilter)
    {
        csrFreeScanFilter(pMac, pScanFilter);
        vos_mem_free(pScanFilter);
    }
    if(hBSSList)
    {
        csrScanResultPurge(pMac, hBSSList);
    }

    return( status );
}


//Lostlink2 scan is to actively scan the all SSIDs of the last roaming profile's on all matched BSS channels.
//Since MAC doesn't support multiple SSID, we scan all SSIDs and filter them afterwards
eHalStatus csrScanRequestLostLink2( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    tCsrScanResultFilter *pScanFilter = NULL;
    tScanResultHandle hBSSList = NULL;
    tCsrScanResultInfo *pScanResult = NULL;
    tSmeCmd *pCommand = NULL;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, FL(" called"));
    do
    {
        pCommand = csrGetCommandBuffer(pMac);
        if(!pCommand)
        {
            status = eHAL_STATUS_RESOURCES;
            break;
        }
        vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
        pCommand->command = eSmeCommandScan;
        pCommand->sessionId = (tANI_U8)sessionId;
        pCommand->u.scanCmd.reason = eCsrScanLostLink2;
        pCommand->u.scanCmd.callback = NULL;
        pCommand->u.scanCmd.pContext = NULL;
        pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
        pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
        pCommand->u.scanCmd.u.scanRequest.max_chntime_btc_esco =
                  pMac->roam.configParam.max_chntime_btc_esco;
        pCommand->u.scanCmd.u.scanRequest.min_chntime_btc_esco =
                  pMac->roam.configParam.min_chntime_btc_esco;
        pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
        if(pSession->pCurRoamProfile)
        {
            pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
            if ( NULL == pScanFilter )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if (!HAL_STATUS_SUCCESS(status))
            {
                break;
            }
            vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
            status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
            if(!HAL_STATUS_SUCCESS(status))
            {
                break;
            }
            status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
            if(!HAL_STATUS_SUCCESS(status))
            {
                break;
            }
            if(hBSSList)
            {
                tANI_U8 i, nChn = 0;
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList =
                                   vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN);
                if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList )
                        status = eHAL_STATUS_FAILURE;
                else
                        status = eHAL_STATUS_SUCCESS;
                if (!HAL_STATUS_SUCCESS(status))
                {
                    break;
                }
                while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) &&
                    nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN)
                {
                    for(i = 0; i < nChn; i++)
                    {
                        if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == 
                                        pScanResult->BssDescriptor.channelId)
                        {
                            break;
                        }
                    }
                    if(i == nChn)
                    {
                        pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId;
                    }
                }
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn;
            }
        }
        vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid));
        //Put to the head in pending queue
        status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE);
        if( !HAL_STATUS_SUCCESS( status ) )
        {
            smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
            break;
        }
    } while( 0 );

    if(!HAL_STATUS_SUCCESS(status))
    {
        smsLog(pMac, LOGW, " csrScanRequestLostLink2 failed with status %d", status);
        if(pCommand)
        {
            csrReleaseCommandScan(pMac, pCommand);
        }
        status = csrScanHandleFailedLostlink2( pMac, sessionId );
    }
    if(pScanFilter)
    {
        csrFreeScanFilter(pMac, pScanFilter);
        vos_mem_free(pScanFilter);
    }
    if(hBSSList)
    {
        csrScanResultPurge(pMac, hBSSList);
    }

    return( status );
}


//To actively scan all valid channels
eHalStatus csrScanRequestLostLink3( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pCommand;
    tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

    smsLog(pMac, LOGW, FL(" called"));
    do
    {
        pCommand = csrGetCommandBuffer(pMac);
        if(!pCommand)
        {
            status = eHAL_STATUS_RESOURCES;
            break;
        }
        vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
        pCommand->command = eSmeCommandScan;
        pCommand->sessionId = (tANI_U8)sessionId;
        pCommand->u.scanCmd.reason = eCsrScanLostLink3;
        pCommand->u.scanCmd.callback = NULL;
        pCommand->u.scanCmd.pContext = NULL;
        pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
        pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
        pCommand->u.scanCmd.u.scanRequest.max_chntime_btc_esco =
               pMac->roam.configParam.max_chntime_btc_esco;
        pCommand->u.scanCmd.u.scanRequest.min_chntime_btc_esco =
               pMac->roam.configParam.min_chntime_btc_esco;
        pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
        vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid));
        //Put to the head of pending queue
        status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE);
        if( !HAL_STATUS_SUCCESS( status ) )
        {
            smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
            break;
        }
    } while( 0 );
    if(!HAL_STATUS_SUCCESS(status))
    {
        smsLog(pMac, LOGW, " csrScanRequestLostLink3 failed with status %d", status);
        if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
        {
            csrScanStartIdleScan(pMac);
        }
        if(pCommand)
        {
            csrReleaseCommandScan(pMac, pCommand);
        }
    }

    return( status );
}


eHalStatus csrScanHandleSearchForSSID(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
    tCsrScanResultFilter *pScanFilter = NULL;
    tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
    tANI_U32 sessionId = pCommand->sessionId;
    tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

    do
    {
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
        //if this scan is for LFR
        if(pMac->roam.neighborRoamInfo.uOsRequestedHandoff)
        {
            //notify LFR state m/c
            if(eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, eHAL_STATUS_SUCCESS))
            {
                csrNeighborRoamStartLfrScan(pMac, REASON_OS_REQUESTED_ROAMING_NOW);
            }
            status = eHAL_STATUS_SUCCESS;
            break;
        }
#endif
        if (!pSession)
        {
            smsLog(pMac, LOGE, FL("session %d not found"), sessionId);
            break;
        }
        /* If Disconnect is already issued from HDD no need to issue connect */
        if (pSession->abortConnection)
        {
           smsLog(pMac, LOGE,
              FL("Disconnect in progress, no need to issue connect"));
           break;
        }
        //If there is roam command waiting, ignore this roam because the newer roam command is the one to execute
        if(csrIsRoamCommandWaitingForSession(pMac, sessionId))
        {
            smsLog(pMac, LOGW, FL(" aborts because roam command waiting"));
            break;
        }
        if(pProfile == NULL)
            break;
        pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
        if ( NULL == pScanFilter )
                status = eHAL_STATUS_FAILURE;
        else
                status = eHAL_STATUS_SUCCESS;
        if (!HAL_STATUS_SUCCESS(status))
            break;
        vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
        status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter);
        if(!HAL_STATUS_SUCCESS(status))
            break;
        status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
        if(!HAL_STATUS_SUCCESS(status))
            break;
        status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, 
                                    pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
        if(!HAL_STATUS_SUCCESS(status))
        {
            break;
        }
    }while(0);
    if(!HAL_STATUS_SUCCESS(status))
    {
        if(CSR_INVALID_SCANRESULT_HANDLE != hBSSList)
        {
            csrScanResultPurge(pMac, hBSSList);
        }
        //We haven't done anything to this profile
        csrRoamCallCallback(pMac, sessionId, NULL,
                     pCommand->u.scanCmd.roamId,
                     eCSR_ROAM_ASSOCIATION_FAILURE,
                     eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
        //In case we have nothing else to do, restart idle scan
        if(csrIsConnStateDisconnected(pMac, sessionId) && !csrIsRoamCommandWaiting(pMac))
        {
            status = csrScanStartIdleScan(pMac);
        }
#ifdef FEATURE_WLAN_BTAMP_UT_RF
        //In case of WDS station, let it retry.
        if( CSR_IS_WDS_STA(pProfile) )
        {
            //Save the roma profile so we can retry
            csrFreeRoamProfile( pMac, sessionId );
            pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile));
            if ( NULL != pSession->pCurRoamProfile )
            {
                vos_mem_set(pSession->pCurRoamProfilee, sizeof(tCsrRoamProfile), 0);
                csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile);
            }
            csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD);
        }
#endif
    }
    if (pScanFilter)
    {
        csrFreeScanFilter(pMac, pScanFilter);
        vos_mem_free(pScanFilter);
    }

    return (status);
}


eHalStatus csrScanHandleSearchForSSIDFailure(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_U32 sessionId = pCommand->sessionId;
    tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    //if this scan is for LFR
    if(pMac->roam.neighborRoamInfo.uOsRequestedHandoff)
    {
        //notify LFR state m/c
        if(eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, eHAL_STATUS_FAILURE))
        {
            csrNeighborRoamStartLfrScan(pMac, REASON_OS_REQUESTED_ROAMING_NOW);
        }
        return eHAL_STATUS_SUCCESS;
    }
#endif
    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

#if defined(WLAN_DEBUG)
    if(pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs == 1)
    {
        char str[36];
        vos_mem_copy(str,
                     pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.ssId,
                     pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length);
        str[pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length] = 0;
        smsLog(pMac, LOGW, FL(" SSID = %s"), str);
    }
#endif
    //Check whether it is for start ibss. No need to do anything if it is a JOIN request
    if(pProfile && CSR_IS_START_IBSS(pProfile))
    {
        status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, 
                                        pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
        if(!HAL_STATUS_SUCCESS(status))
        {
            smsLog(pMac, LOGE, FL("failed to issue startIBSS command with status = 0x%08X"), status);
            csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.scanCmd.roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
        }
    }
    else 
    {
        eCsrRoamResult roamResult = eCSR_ROAM_RESULT_FAILURE;

        if(csrIsConnStateDisconnected(pMac, sessionId) &&
          !csrIsRoamCommandWaitingForSession(pMac, sessionId))
        {
            status = csrScanStartIdleScan(pMac);
        }
        if((NULL == pProfile) || !csrIsBssTypeIBSS(pProfile->BSSType))
        {
            //Only indicate assoc_completion if we indicate assoc_start.
            if(pSession->bRefAssocStartCnt > 0)
            {
                tCsrRoamInfo *pRoamInfo = NULL, roamInfo;
                vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
                pRoamInfo = &roamInfo;
                if(pCommand->u.roamCmd.pRoamBssEntry)
                {
                    tCsrScanResult *pScanResult = 
                                GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry,
                                tCsrScanResult, Link);
                    roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor;
                }
                roamInfo.statusCode = pSession->joinFailStatusCode.statusCode;
                roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
                pSession->bRefAssocStartCnt--;
                csrRoamCallCallback(pMac, sessionId, pRoamInfo,
                                    pCommand->u.scanCmd.roamId,
                                    eCSR_ROAM_ASSOCIATION_COMPLETION,
                                    eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
            }
            else
            {
                csrRoamCallCallback(pMac, sessionId, NULL,
                                    pCommand->u.scanCmd.roamId,
                                    eCSR_ROAM_ASSOCIATION_FAILURE,
                                    eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
            }
#ifdef FEATURE_WLAN_BTAMP_UT_RF
            //In case of WDS station, let it retry.
            if( CSR_IS_WDS_STA(pProfile) )
            {
                //Save the roma profile so we can retry
                csrFreeRoamProfile( pMac, sessionId );
                pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile));
                if ( NULL != pSession->pCurRoamProfile )
                {
                    vos_mem_set(pSession->pCurRoamProfile, sizeof(tCsrRoamProfile), 0);
                    csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile);
                }
                csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD);
            }
#endif
        }
        else
        {
            roamResult = eCSR_ROAM_RESULT_IBSS_START_FAILED;
        }
        csrRoamCompletion(pMac, sessionId, NULL, pCommand, roamResult, eANI_BOOLEAN_FALSE);
    }

    return (status);
}


//After scan for cap changes, issue a roaming command to either reconnect to the AP or pick another one to connect
eHalStatus csrScanHandleCapChangeScanComplete(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tScanResultHandle hBSSList = NULL;
    tCsrScanResultFilter *pScanFilter = NULL;
    tANI_U32 roamId = 0;
    tCsrRoamProfile *pProfile = NULL;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    do
    {
        //Here is the profile we need to connect to
        pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
        if ( NULL == pScanFilter )
                status = eHAL_STATUS_FAILURE;
        else
                status = eHAL_STATUS_SUCCESS;
        if (!HAL_STATUS_SUCCESS(status))
            break;
        vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
        if (NULL == pSession) break;
        if (NULL == pSession->pCurRoamProfile)
        {
            pScanFilter->EncryptionType.numEntries = 1;
            pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
        }
        else
        {
            //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect
            pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile));
            if ( NULL == pProfile )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if(!HAL_STATUS_SUCCESS(status))
                break;
            status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile);
            if(!HAL_STATUS_SUCCESS(status))
                break;
            status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter);
        }//We have a profile
        roamId = GET_NEXT_ROAM_ID(&pMac->roam);
        if(HAL_STATUS_SUCCESS(status))
        {
            status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
            if(HAL_STATUS_SUCCESS(status))
            {
                //we want to put the last connected BSS to the very beginning, if possible
                csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList);
                status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, 
                                            eCsrCapsChange, 0, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
                if(!HAL_STATUS_SUCCESS(status))
                {
                    csrScanResultPurge(pMac, hBSSList);
                }
            }//Have scan result
            else
            {
                smsLog(pMac, LOGW, FL("cannot find matching BSS of "
                       MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pSession->connectedProfile.bssid));
                //Disconnect
                csrRoamDisconnectInternal(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
            }
        }
    }while(0);
    if(pScanFilter)
    {
        csrFreeScanFilter(pMac, pScanFilter);
        vos_mem_free(pScanFilter);
    }
    if(NULL != pProfile)
    {
        csrReleaseProfile(pMac, pProfile);
        vos_mem_free(pProfile);
    }

    return (status);
}



eHalStatus csrScanResultPurge(tpAniSirGlobal pMac, tScanResultHandle hScanList)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    tScanResultList *pScanList = (tScanResultList *)hScanList;
     
    if(pScanList)
    {
        status = csrLLScanPurgeResult(pMac, &pScanList->List);
        csrLLClose(&pScanList->List);
        vos_mem_free(pScanList);
    }
    return (status);
}


static tANI_U32 csrGetBssPreferValue(tpAniSirGlobal pMac, int rssi)
{
    tANI_U32 ret = 0;
    int i = CSR_NUM_RSSI_CAT - 1;

    while(i >= 0)
    {
        if(rssi >= pMac->roam.configParam.RSSICat[i])
        {
            ret = pMac->roam.configParam.BssPreferValue[i];
            break;
        }
        i--;
    };

    return (ret);
}


//Return a CapValue base on the capabilities of a BSS
static tANI_U32 csrGetBssCapValue(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes)
{
    tANI_U32 ret = CSR_BSS_CAP_VALUE_NONE;
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
    if(CSR_IS_ROAM_PREFER_5GHZ(pMac))
    {
        if((pBssDesc) && CSR_IS_CHANNEL_5GHZ(pBssDesc->channelId))
        {
            ret += CSR_BSS_CAP_VALUE_5GHZ;
        }
    }
#endif
    /* if strict select 5GHz is non-zero then ignore the capability checking */
    if (pIes && !CSR_IS_SELECT_5GHZ_MARGIN(pMac))
    {
        //We only care about 11N capability
        if(pIes->HTCaps.present)
        {
            ret += CSR_BSS_CAP_VALUE_HT;
        }
        if(CSR_IS_QOS_BSS(pIes))
        {
            ret += CSR_BSS_CAP_VALUE_WMM;
            //Give advantage to UAPSD
            if(CSR_IS_UAPSD_BSS(pIes))
            {
                ret += CSR_BSS_CAP_VALUE_UAPSD;
            }
        }
    }

    return (ret);
}

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD

/* Calculate channel weight based on other APs RSSI and count for
 * PER based roaming */
static tANI_U32 GetPERRoamRssiCountWeight(tANI_S32 rssi, tANI_S32 count)
{
    tANI_S32 rssiWeight=0;
    tANI_S32 countWeight=0;
    tANI_S32 rssicountWeight=0;

    rssiWeight = ROAMING_RSSI_WEIGHT * (rssi - MIN_RSSI)
                 /(MAX_RSSI - MIN_RSSI);

    if(rssiWeight > ROAMING_RSSI_WEIGHT)
        rssiWeight = ROAMING_RSSI_WEIGHT;
    else if (rssiWeight < 0)
        rssiWeight = 0;

    countWeight = ROAM_AP_COUNT_WEIGHT * (count + ROAM_MIN_COUNT)
                  /(ROAM_MAX_COUNT + ROAM_MIN_COUNT);

    if(countWeight > ROAM_AP_COUNT_WEIGHT)
        countWeight = ROAM_AP_COUNT_WEIGHT;

    rssicountWeight =  ROAM_MAX_WEIGHT - (rssiWeight + countWeight);

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
       FL("rssiWeight=%d, countWeight=%d, rssicountWeight=%d rssi=%d count=%d"),
       rssiWeight, countWeight, rssicountWeight, rssi, count);

    return rssicountWeight;
}

/* Calculate BSS score based on AP capabilty and channel condition
 * for PER based roaming */
static tANI_U32 calculateBssScore(tSirBssDescription *bssInfo,
                             tANI_S32 best_rssi, tANI_S32 ap_cnt, tANI_S32 cca)
{
    tANI_S32 score = 0;
    tANI_S32 ap_load = 0;
    tANI_S32 normalised_width = PER_ROAM_20MHZ;
    tANI_S32 normalised_rssi = 0;
    tANI_S32 channel_weight;
    if (bssInfo->rssi) {
        /* Calculate % of rssi we are getting
         * max = 100
         * min = 0
         * less than -40 = 100%
         * -40 - -55 = 80%
         * -55 - -65 = 60%
         * below that = 100 - value
         * TODO: a linear decrement function after PER_ROAM_GOOD_RSSI_WEIGHT
         * since throughput decrements linearly after PER_ROAM_GOOD_RSSI_WEIGHT
         **/
        if (bssInfo->rssi >= PER_EXCELENT_RSSI)
            normalised_rssi = PER_ROAM_EXCELLENT_RSSI_WEIGHT;
        else if (bssInfo->rssi >= PER_GOOD_RSSI)
            normalised_rssi = PER_ROAM_GOOD_RSSI_WEIGHT;
        else if (bssInfo->rssi >= PER_POOR_RSSI)
            normalised_rssi = PER_ROAM_BAD_RSSI_WEIGHT;
        else
            normalised_rssi = bssInfo->rssi - MIN_RSSI;

        /* Calculate score part for rssi */
        score += (normalised_rssi * RSSI_WEIGHTAGE);
    }

    if (bssInfo->HTCapsPresent) {
        score += PER_ROAM_MAX_WEIGHT * HT_CAPABILITY_WEIGHTAGE;
    }
    /* VHT caps are available */
    if (bssInfo->vhtCapsPresent) {
        score += PER_ROAM_MAX_WEIGHT * VHT_CAP_WEIGHTAGE;
    }

    if (bssInfo->beacomformingCapable)
        score += PER_ROAM_MAX_WEIGHT * BEAMFORMING_CAP_WEIGHTAGE;

    /* Channel width  20Mhz=30, 40Mhz=70, 80Mhz=100 */
    if (bssInfo->chanWidth == eHT_CHANNEL_WIDTH_80MHZ)
        normalised_width = PER_ROAM_80MHZ;
    else if (bssInfo->chanWidth == eHT_CHANNEL_WIDTH_40MHZ)
        normalised_width = PER_ROAM_40MHZ;
    else
        normalised_width = PER_ROAM_20MHZ;
    score += normalised_width * CHAN_WIDTH_WEIGHTAGE;

    /* Channel Band, Channel Number */
    if (GetRFBand(bssInfo->channelId) == SIR_BAND_5_GHZ)
        score += PER_ROAM_MAX_WEIGHT * CHAN_BAND_WEIGHTAGE;

    /* WMM emabled */
    if (bssInfo->wmeInfoPresent)
        score += PER_ROAM_MAX_WEIGHT * WMM_WEIGHTAGE;

#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD)
    /* AP load Ie */
    if (bssInfo->QBSSLoad_present) {
        /* calculate value in % */
        ap_load = (bssInfo->QBSS_ChanLoad * PER_ROAM_MAX_WEIGHT) / MAX_AP_LOAD;
    }
#endif
    /* if CCA consideration is off in configuration, FW will send 50% for
       every channel which should be considered as it is */
    if (ap_load)
        score += (100 - ap_load) * CCA_WEIGHTAGE;
    else
        score +=  (100 - cca) * CCA_WEIGHTAGE;

    channel_weight = GetPERRoamRssiCountWeight(best_rssi, ap_cnt);

    score += channel_weight * OTHER_AP_WEIGHT;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW,
        FL("rssi=%d normalized_rssi=%d htcaps=%d vht=%d bw=%d channel=%d wmm=%d beamforming=%d ap_load=%d channel_weight=%d"),
                 bssInfo->rssi, normalised_rssi, bssInfo->HTCapsPresent,
                 bssInfo->vhtCapsPresent, bssInfo->chanWidth,
                 bssInfo->channelId, bssInfo->wmeInfoPresent,
                 bssInfo->beacomformingCapable, ap_load, channel_weight);
    return score;
}

/* Calculate candidate AP score for PER based roaming */
static tANI_S32 csrFindCongestionScore (tpAniSirGlobal pMac, tCsrScanResult *pBss)
{
    tANI_S32 score = 0;
    tANI_S32 i;
    tANI_S32 candidateApCnt, best_rssi, other_ap_cnt;
    tANI_U32 current_timestamp;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
        &pMac->roam.neighborRoamInfo;

    tSirBssDescription *bssInfo = &(pBss->Result.BssDescriptor);
    pBss->congestionScore = 0;
    for (i = 0; i < pMac->PERroamCandidatesCnt; i++)
        if (pMac->candidateChannelInfo[i].channelNumber ==
            pBss->Result.BssDescriptor.channelId)
            break;

    if (i == SIR_PER_ROAM_MAX_CANDIDATE_CNT) {
        smsLog(pMac, LOGE,
               FL("candidate chan info not found for channel %d bssid "
               MAC_ADDRESS_STR), pBss->Result.BssDescriptor.channelId,
               MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId));
        return -1;
    }

    if (bssInfo->rssi < pMac->roam.configParam.PERMinRssiThresholdForRoam) {
        smsLog(pMac, LOG1,
               FL("discarding candidate due to low rssi=%d than %d, bssid "
               MAC_ADDRESS_STR), bssInfo->rssi,
               pMac->roam.configParam.PERMinRssiThresholdForRoam,
               MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId));
        return 0;
    }
    /* find best RSSI of other AP in this channel */
    best_rssi = MIN_RSSI;
    for (other_ap_cnt = 0; other_ap_cnt <
             pMac->candidateChannelInfo[i].otherApCount; other_ap_cnt++) {
        if (pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt] > best_rssi)
            best_rssi = pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt];
    }

    score = calculateBssScore(bssInfo, best_rssi,
                              pMac->candidateChannelInfo[i].otherApCount,
                              pMac->candidateChannelInfo[i].channelCCA);
    current_timestamp = jiffies_to_msecs(jiffies);

    /* penalty logic */

    /* In the previous list */
    for (candidateApCnt = 0; candidateApCnt <
             SIR_PER_ROAM_MAX_CANDIDATE_CNT; candidateApCnt++) {
        if (sirCompareMacAddr(pMac->previousRoamApInfo[candidateApCnt].bssAddr,
                pBss->Result.BssDescriptor.bssId) &&
           ((current_timestamp - pMac->previousRoamApInfo[candidateApCnt].timeStamp) <
                PENALTY_TIMEOUT)) {
            score = (score * PENALTY_REMAINING_SCORE)/PENALTY_TOTAL_SCORE;
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                 FL("AP BSSID " MAC_ADDRESS_STR "adding penalty(in previous list)new score %d"),
                 MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId),
                 score);
            break;
        }
    }
    /* preauth failed last time */
    for (candidateApCnt = 0; candidateApCnt <
             MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS; candidateApCnt++) {
        if (sirCompareMacAddr(pNeighborRoamInfo->FTRoamInfo.
                preAuthFailList.macAddress[candidateApCnt],
                pBss->Result.BssDescriptor.bssId)) {
            score = (score * PENALTY_REMAINING_SCORE)/PENALTY_TOTAL_SCORE;
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                 FL("AP BSSID " MAC_ADDRESS_STR "adding penalty(previously auth failed)new score %d"),
                 MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId),
                 score);
            break;
        }
    }
    pBss->congestionScore = score;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                 FL("AP BSSID " MAC_ADDRESS_STR " score  %d channel %d"),
                 MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId),
                 score, pBss->Result.BssDescriptor.channelId);
    return 0;
}

/* Calculate current AP score for PER based roaming */
static tANI_S32 csrFindSelfCongestionScore(tpAniSirGlobal pMac,
                                      tSirBssDescription *bssInfo)
{
    tANI_S32 i, best_rssi, other_ap_cnt;
    tANI_S32 score = 0;
    tCsrRoamSession *pSession = CSR_GET_SESSION(pMac,
                                    pMac->roam.roamSession->sessionId);

    if (pSession == NULL)
        return -1;

    if (bssInfo->rssi < pMac->roam.configParam.PERMinRssiThresholdForRoam) {
        smsLog(pMac, LOG1,
               FL("Current AP has low rssi=%d than %d"), bssInfo->rssi,
               pMac->roam.configParam.PERMinRssiThresholdForRoam);
        /*
         * Make Current candidate score as zero which will cause roaming
         * in low RSSI scenarios
         */
        pMac->currentBssScore = 0;
        return 0;
    }

    for (i = 0; i <= pMac->PERroamCandidatesCnt; i++)
        if (pMac->candidateChannelInfo[i].channelNumber == bssInfo->channelId)
            break;
    if (i > pMac->PERroamCandidatesCnt) {
        /* home channel info is not present, no need to roam */
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("home channel %d congestion info not present"),
                  bssInfo->channelId);
        pMac->currentBssScore = PER_ROAM_MAX_BSS_SCORE;
        return -1;
    }

    /* find best RSSI of other AP in this channel */
    best_rssi = MIN_RSSI;
    for (other_ap_cnt = 0; other_ap_cnt <
             pMac->candidateChannelInfo[i].otherApCount; other_ap_cnt++) {
        if (pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt] > best_rssi)
            best_rssi = pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt];
    }

    /* update latest RSSI for current AP */
    WLANTL_GetRssi(vos_get_global_context(VOS_MODULE_ID_SME, NULL),
                   pSession->connectedInfo.staId,
                   &bssInfo->rssi);

    score = calculateBssScore(bssInfo, best_rssi,
                              pMac->candidateChannelInfo[i].otherApCount,
                              pMac->candidateChannelInfo[i].channelCCA);
    pMac->currentBssScore = score;
    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                 FL("PER Roam Current AP score  %d channel %d"),
                 score, bssInfo->channelId);
    return 0;
}


static tANI_BOOLEAN csrIsBetterBssInCongestion(tCsrScanResult *pBss1,
                                               tCsrScanResult *pBss2)
{
    tANI_BOOLEAN ret;

    if(CSR_IS_BETTER_PREFER_VALUE(pBss1->congestionScore,
                                  pBss2->congestionScore))
        ret = eANI_BOOLEAN_TRUE;
    else
        ret = eANI_BOOLEAN_FALSE;

    return (ret);
}
#endif

//To check whther pBss1 is better than pBss2
static tANI_BOOLEAN csrIsBetterBss(tCsrScanResult *pBss1, tCsrScanResult *pBss2)
{
    tANI_BOOLEAN ret;

    if(CSR_IS_BETTER_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue))
    {
        ret = eANI_BOOLEAN_TRUE;
    }
    else if(CSR_IS_EQUAL_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue))
    {
        if(CSR_IS_BETTER_CAP_VALUE(pBss1->capValue, pBss2->capValue))
        {
            ret = eANI_BOOLEAN_TRUE;
        }
        else
        {
            ret = eANI_BOOLEAN_FALSE;
        }
    }
    else
    {
        ret = eANI_BOOLEAN_FALSE;
    }

    return (ret);
}


#ifdef FEATURE_WLAN_LFR 
//Add the channel to the occupiedChannels array
static void csrScanAddToOccupiedChannels(
        tpAniSirGlobal pMac, 
        tCsrScanResult *pResult, 
        tCsrChannel *pOccupiedChannels, 
        tDot11fBeaconIEs *pIes)
{
    eHalStatus status;
    tANI_U8   channel;
    tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels;
    tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList;

    channel = pResult->Result.BssDescriptor.channelId;

    if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, channel)
        && csrNeighborRoamConnectedProfileMatch(pMac, pResult, pIes))
    {
        status = csrAddToChannelListFront(pOccupiedChannelList, numOccupiedChannels, channel); 
        if(HAL_STATUS_SUCCESS(status))
        { 
            pOccupiedChannels->numChannels++;
            smsLog(pMac, LOG2, FL("%s: added channel %d to the list (count=%d)"),
              __func__, channel, pOccupiedChannels->numChannels);
            if (pOccupiedChannels->numChannels > CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN) 
                pOccupiedChannels->numChannels = CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN; 
        } 
    }
}

void csrAddChannelToOccupiedChannelList(tpAniSirGlobal pMac,
                                     tANI_U8   channel)
{
    eHalStatus status;
    tCsrChannel *pOccupiedChannels = &pMac->scan.occupiedChannels;
    tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels;
    tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList;
    if (!csrIsChannelPresentInList(pOccupiedChannelList,
         numOccupiedChannels, channel))
    {
        status = csrAddToChannelListFront(pOccupiedChannelList,
                                          numOccupiedChannels, channel);
        if(HAL_STATUS_SUCCESS(status))
        {
            pOccupiedChannels->numChannels++;
            smsLog(pMac, LOG2, FL("added channel %d to the list (count=%d)"),
                channel, pOccupiedChannels->numChannels);
            if (pOccupiedChannels->numChannels >
                CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN)
            {
                pOccupiedChannels->numChannels =
                    CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN;
                smsLog(pMac, LOG2,
                       FL("trim no of Channels for Occ channel list"));
            }
        }
    }
}
#endif

//Put the BSS into the scan result list
//pIes can not be NULL
static void csrScanAddResult(tpAniSirGlobal pMac, tCsrScanResult *pResult, tDot11fBeaconIEs *pIes)
{
#ifdef FEATURE_WLAN_LFR 
    tpCsrNeighborRoamControlInfo    pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
#endif

    pResult->preferValue = csrGetBssPreferValue(pMac, (int)pResult->Result.BssDescriptor.rssi);
    pResult->capValue = csrGetBssCapValue(pMac, &pResult->Result.BssDescriptor, pIes);
    csrLLInsertTail( &pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_LOCK );
#ifdef FEATURE_WLAN_LFR 
    if(0 == pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
    {
        /* Build the occupied channel list, only if "gNeighborScanChannelList" is 
           NOT set in the cfg.ini file */
        csrScanAddToOccupiedChannels(pMac, pResult, &pMac->scan.occupiedChannels, pIes);
    }
#endif
}


eHalStatus csrScanGetResult(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter, tScanResultHandle *phResult)
{
    eHalStatus status;
    tScanResultList *pRetList;
    tCsrScanResult *pResult, *pBssDesc;
    tANI_U32 count = 0;
    tListElem *pEntry;
    tANI_U32 bssLen, allocLen;
    eCsrEncryptionType uc = eCSR_ENCRYPT_TYPE_NONE, mc = eCSR_ENCRYPT_TYPE_NONE;
    eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
    tDot11fBeaconIEs *pIes, *pNewIes;
    tANI_BOOLEAN fMatch;
    tANI_U16 i = 0;
    tCsrRoamSession *pSession = CSR_GET_SESSION(pMac,
                                    pMac->roam.roamSession->sessionId);

    if(phResult)
    {
        *phResult = CSR_INVALID_SCANRESULT_HANDLE;
    }

    if (pMac->roam.configParam.nSelect5GHzMargin)
    {
        pMac->scan.inScanResultBestAPRssi = -128;
        csrLLLock(&pMac->scan.scanResultList);

        /* Find out the best AP Rssi going thru the scan results */
        pEntry = csrLLPeekHead(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
        while ( NULL != pEntry)
        {
            pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
            fMatch = FALSE;

            if (pFilter)
            for(i = 0; i < pFilter->SSIDs.numOfSSIDs; i++)
            {
                fMatch = csrIsSsidMatch( pMac, pFilter->SSIDs.SSIDList[i].SSID.ssId, pFilter->SSIDs.SSIDList[i].SSID.length,
                                        pBssDesc->Result.ssId.ssId,
                                        pBssDesc->Result.ssId.length, eANI_BOOLEAN_TRUE );
                if (fMatch)
                {
                    pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes );

                    //At this time, pBssDescription->Result.pvIes may be NULL
                    if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
                                  &pBssDesc->Result.BssDescriptor, &pIes))) )
                    {
                        continue;
                    }

                    smsLog(pMac, LOG1, FL("SSID Matched"));

                    if ( pFilter->bOSENAssociation )
                    {
                        fMatch = TRUE;
                    }
                    else
                    {
#ifdef WLAN_FEATURE_11W
                        fMatch = csrIsSecurityMatch(pMac, &pFilter->authType,
                                                &pFilter->EncryptionType,
                                                &pFilter->mcEncryptionType,
                                                &pFilter->MFPEnabled,
                                                &pFilter->MFPRequired,
                                                &pFilter->MFPCapable,
                                                &pBssDesc->Result.BssDescriptor,
                                                pIes, NULL, NULL, NULL );
#else
                        fMatch = csrIsSecurityMatch(pMac, &pFilter->authType,
                                                &pFilter->EncryptionType,
                                                &pFilter->mcEncryptionType,
                                                NULL, NULL, NULL,
                                                &pBssDesc->Result.BssDescriptor,
                                                pIes, NULL, NULL, NULL );
#endif
                    }
                    if ((pBssDesc->Result.pvIes == NULL) && pIes)
                         vos_mem_free(pIes);

                    if (fMatch)
                        smsLog(pMac, LOG1, FL(" Security Matched"));
                }
            }

            if (fMatch && (pBssDesc->Result.BssDescriptor.rssi > pMac->scan.inScanResultBestAPRssi))
            {
                smsLog(pMac, LOG1, FL("Best AP Rssi changed from %d to %d"),
                                       pMac->scan.inScanResultBestAPRssi,
                                       pBssDesc->Result.BssDescriptor.rssi);
                pMac->scan.inScanResultBestAPRssi = pBssDesc->Result.BssDescriptor.rssi;
            }
            pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
        }

        if ( -128 != pMac->scan.inScanResultBestAPRssi)
        {
            smsLog(pMac, LOG1, FL("Best AP Rssi is %d"), pMac->scan.inScanResultBestAPRssi);
            /* Modify Rssi category based on best AP Rssi */
            csrAssignRssiForCategory(pMac, pMac->scan.inScanResultBestAPRssi, pMac->roam.configParam.bCatRssiOffset);
            pEntry = csrLLPeekHead(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
            while ( NULL != pEntry)
            {
                pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );

                /* re-assign preference value based on modified rssi bucket */
                pBssDesc->preferValue = csrGetBssPreferValue(pMac, (int)pBssDesc->Result.BssDescriptor.rssi);

                smsLog(pMac, LOG2, FL("BSSID("MAC_ADDRESS_STR
                       ") Rssi(%d) Chnl(%d) PrefVal(%u) SSID=%.*s"),
                       MAC_ADDR_ARRAY(pBssDesc->Result.BssDescriptor.bssId),
                       pBssDesc->Result.BssDescriptor.rssi,
                       pBssDesc->Result.BssDescriptor.channelId,
                       pBssDesc->preferValue,
                       pBssDesc->Result.ssId.length, pBssDesc->Result.ssId.ssId);

                pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
            }
        }

        csrLLUnlock(&pMac->scan.scanResultList);
    }

    pRetList = vos_mem_malloc(sizeof(tScanResultList));
    if ( NULL == pRetList )
        status = eHAL_STATUS_FAILURE;
    else
        status = eHAL_STATUS_SUCCESS;
    if(HAL_STATUS_SUCCESS(status))
    {
        vos_mem_set(pRetList, sizeof(tScanResultList), 0);
        csrLLOpen(pMac->hHdd, &pRetList->List);
        pRetList->pCurEntry = NULL;
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
        if (pFilter && pFilter->isPERRoamScan)
            if (pSession && pSession->pConnectBssDesc)
               csrFindSelfCongestionScore(pMac,
                                          pSession->pConnectBssDesc);
#endif

        csrLLLock(&pMac->scan.scanResultList);
        pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
        while( pEntry ) 
        {
            pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
            pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes );
            //if pBssDesc->Result.pvIes is NULL, we need to free any memory allocated by csrMatchBSS
            //for any error condition, otherwiase, it will be freed later.
            //reset
            fMatch = eANI_BOOLEAN_FALSE;
            pNewIes = NULL;

            if(pFilter)
            {
                fMatch = csrMatchBSS(pMac, &pBssDesc->Result.BssDescriptor, pFilter, &auth, &uc, &mc, &pIes);
                if( NULL != pIes )
                {
                    //Only save it when matching
                    if(fMatch)
                    {
                        if( !pBssDesc->Result.pvIes )
                        {
                            //csrMatchBSS allocates the memory. Simply pass it and it is freed later
                            pNewIes = pIes;
                        }
                        else
                        {
                            //The pIes is allocated by someone else. make a copy
                            //Only to save parsed IEs if caller provides a filter. Most likely the caller
                            //is using to for association, hence save the parsed IEs
                            pNewIes = vos_mem_malloc(sizeof(tDot11fBeaconIEs));
                            if ( NULL == pNewIes )
                                status = eHAL_STATUS_FAILURE;
                            else
                                status = eHAL_STATUS_SUCCESS;
                            if ( HAL_STATUS_SUCCESS( status ) )
                            {
                                vos_mem_copy(pNewIes, pIes, sizeof( tDot11fBeaconIEs ));
                            }
                            else
                            {
                                smsLog(pMac, LOGE, FL(" fail to allocate memory for IEs"));
                                //Need to free memory allocated by csrMatchBSS
                                if( !pBssDesc->Result.pvIes )
                                {
                                    vos_mem_free(pIes);
                                }
                                break;
                            }
                        }
                    }//fMatch
                    else if( !pBssDesc->Result.pvIes )
                    {
                        vos_mem_free(pIes);
                    }
                }
            }
            if(NULL == pFilter || fMatch)
            {
                bssLen = pBssDesc->Result.BssDescriptor.length + sizeof(pBssDesc->Result.BssDescriptor.length);
                allocLen = sizeof( tCsrScanResult ) + bssLen;
                pResult = vos_mem_malloc(allocLen);
                if ( NULL == pResult )
                        status = eHAL_STATUS_FAILURE;
                else
                        status = eHAL_STATUS_SUCCESS;
                if(!HAL_STATUS_SUCCESS(status))
                {
                    smsLog(pMac, LOGE, FL("  fail to allocate memory for scan result, len=%d"), allocLen);
                    if(pNewIes)
                    {
                        vos_mem_free(pNewIes);
                    }
                    break;
                }
                vos_mem_set(pResult, allocLen, 0);
                pResult->capValue = pBssDesc->capValue;
                pResult->preferValue = pBssDesc->preferValue;
                pResult->ucEncryptionType = uc;
                pResult->mcEncryptionType = mc;
                pResult->authType = auth;
                pResult->Result.ssId = pBssDesc->Result.ssId;
                pResult->Result.timer = pBssDesc->Result.timer;
                //save the pIes for later use
                pResult->Result.pvIes = pNewIes;
                //save bss description
                vos_mem_copy(&pResult->Result.BssDescriptor,
                             &pBssDesc->Result.BssDescriptor, bssLen);
                //No need to lock pRetList because it is locally allocated and no outside can access it at this time
                if(csrLLIsListEmpty(&pRetList->List, LL_ACCESS_NOLOCK))
                {
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
                    if (pFilter && pFilter->isPERRoamScan) {
                         csrFindCongestionScore(pMac, pResult);
                         if (pResult->congestionScore > pMac->currentBssScore) {
                             csrLLInsertTail(&pRetList->List, &pResult->Link,
                                             LL_ACCESS_NOLOCK);
                             smsLog(pMac, LOGW,
                                  FL("added one entry in LL in PER Roam list"));
                         }
                    }
                    else
#endif
                    {
                        csrLLInsertTail(&pRetList->List, &pResult->Link,
                                        LL_ACCESS_NOLOCK);
                    }
                }
                /* bssid hint AP should be on head */
                else if (pFilter &&
                     vos_mem_compare(pResult->Result.BssDescriptor.bssId,
                     pFilter->bssid_hint, VOS_MAC_ADDR_SIZE))
                {
                     csrLLInsertHead(&pRetList->List,
                            &pResult->Link, LL_ACCESS_NOLOCK);
                }
                else
                {
                    //To sort the list
                    tListElem *pTmpEntry;
                    tCsrScanResult *pTmpResult;
                    
                    pTmpEntry = csrLLPeekHead(&pRetList->List, LL_ACCESS_NOLOCK);
                    while(pTmpEntry)
                    {
                        pTmpResult = GET_BASE_ADDR( pTmpEntry, tCsrScanResult, Link );
                        /* Skip the bssid hint AP, as it should be on head */
                        if (pFilter && vos_mem_compare(
                           pTmpResult->Result.BssDescriptor.bssId,
                           pFilter->bssid_hint, VOS_MAC_ADDR_SIZE)) {
                           pTmpEntry = csrLLNext(&pRetList->List,
                                                  pTmpEntry, LL_ACCESS_NOLOCK);
                           continue;
                        }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
                        if (pFilter && pFilter->isPERRoamScan) {
                            csrFindCongestionScore(pMac, pResult);
                            if(csrIsBetterBssInCongestion(pResult, pTmpResult)&&
                             (pResult->congestionScore > pMac->currentBssScore))
                            {
                                csrLLInsertEntry(&pRetList->List, pTmpEntry,
                                              &pResult->Link, LL_ACCESS_NOLOCK);
                                smsLog(pMac, LOGW,
                                    FL("added another entry in LL in PER Roam list"));
                                pResult = NULL;
                                break;
                            }
                            pTmpEntry = csrLLNext(&pRetList->List,
                                                  pTmpEntry, LL_ACCESS_NOLOCK);
                        }
                        else
#endif
                        {
                            if(csrIsBetterBss(pResult, pTmpResult))
                            {
                                csrLLInsertEntry(&pRetList->List, pTmpEntry,
                                              &pResult->Link, LL_ACCESS_NOLOCK);
                                //To indicate we are done
                                pResult = NULL;
                                break;
                            }
                            pTmpEntry = csrLLNext(&pRetList->List,
                                                  pTmpEntry, LL_ACCESS_NOLOCK);
                       }
                    }
                    if(pResult != NULL)
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
                        if ((pFilter && !pFilter->isPERRoamScan) ||
                            (pFilter == NULL) ||
                            (pResult->congestionScore > pMac->currentBssScore))
#endif
                        {
                            //This one is not better than any one
                            csrLLInsertTail(&pRetList->List,
                                            &pResult->Link, LL_ACCESS_NOLOCK);
                        }
                }
                count++;
            }
            pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK );
        }//while
        csrLLUnlock(&pMac->scan.scanResultList);
        
        smsLog(pMac, LOG2, FL("return %d BSS"), csrLLCount(&pRetList->List));
        
        if( !HAL_STATUS_SUCCESS(status) || (phResult == NULL) )
        {
            //Fail or No one wants the result.
            csrScanResultPurge(pMac, (tScanResultHandle)pRetList);
        }
        else
        {
            if(0 == count)
            {
                //We are here meaning the there is no match
                csrLLClose(&pRetList->List);
                vos_mem_free(pRetList);
                status = eHAL_STATUS_E_NULL_VALUE;
                smsLog(pMac, LOGW,
                       FL("Nil scan results or no matching AP found"));
            }
            else if(phResult)
            {
                *phResult = pRetList;
            }
        }
    }//Allocated pRetList
    
    return (status);
}

/*
 * NOTE: This routine is being added to make
 * sure that scan results are not being flushed
 * while roaming. If the scan results are flushed,
 * we are unable to recover from
 * csrRoamRoamingStateDisassocRspProcessor.
 * If it is needed to remove this routine,
 * first ensure that we recover gracefully from 
 * csrRoamRoamingStateDisassocRspProcessor if 
 * csrScanGetResult returns with a failure because 
 * of not being able to find the roaming BSS.
 */
tANI_U8 csrScanFlushDenied(tpAniSirGlobal pMac)
{
    switch(pMac->roam.neighborRoamInfo.neighborRoamState) {
        case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
        case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
        case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
        case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
            return (pMac->roam.neighborRoamInfo.neighborRoamState);
        default:
            return 0;
    }
}

eHalStatus csrScanFlushResult(tpAniSirGlobal pMac)
{
    tANI_U8 isFlushDenied = csrScanFlushDenied(pMac);
    eHalStatus status = eHAL_STATUS_SUCCESS;
    if (isFlushDenied) {
        smsLog(pMac, LOGW, "%s: scan flush denied in roam state %d",
                __func__, isFlushDenied);
        return eHAL_STATUS_FAILURE;
    }
    csrLLScanPurgeResult( pMac, &pMac->scan.tempScanResults );
    csrLLScanPurgeResult( pMac, &pMac->scan.scanResultList );
    return( status );
}

eHalStatus csrScanFlushSelectiveResultForBand(tpAniSirGlobal pMac, v_BOOL_t flushP2P, tSirRFBand band)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry,*pFreeElem;
    tCsrScanResult *pBssDesc;
    tDblLinkList *pList = &pMac->scan.scanResultList;

    csrLLLock(pList);

    pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK );
    while( pEntry != NULL)
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        if( (flushP2P == vos_mem_compare( pBssDesc->Result.ssId.ssId,
                                         "DIRECT-", 7)) &&
            (GetRFBand(pBssDesc->Result.BssDescriptor.channelId) == band)
          )
        {
            pFreeElem = pEntry;
            pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
            csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK);
            csrFreeScanResultEntry( pMac, pBssDesc );
            continue;
        }
        pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
    }

    csrLLUnlock(pList);

    return (status);
}

eHalStatus csrScanFlushSelectiveResult(tpAniSirGlobal pMac, v_BOOL_t flushP2P)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry,*pFreeElem;
    tCsrScanResult *pBssDesc;
    tDblLinkList *pList = &pMac->scan.scanResultList;

    csrLLLock(pList);

    pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK );
    while( pEntry != NULL)
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        if( flushP2P == vos_mem_compare( pBssDesc->Result.ssId.ssId, 
                                         "DIRECT-", 7) )
        {
            pFreeElem = pEntry;
            pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
            csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK);
            csrFreeScanResultEntry( pMac, pBssDesc );
            continue;
        }
        pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
    }

    csrLLUnlock(pList);

    return (status);
}

eHalStatus csrScanFlushSelectiveSsid(tpAniSirGlobal pMac, tANI_U8 *ssId,
                                     tANI_U8 ssIdLen)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry,*pFreeElem;
    tCsrScanResult *pBssDesc;
    tDblLinkList *pList = &pMac->scan.scanResultList;

    csrLLLock(pList);

    pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK );
    while( pEntry != NULL)
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        if(vos_mem_compare(pBssDesc->Result.ssId.ssId,
                            ssId, ssIdLen) )
        {
            pFreeElem = pEntry;
            pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
            csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK);
            csrFreeScanResultEntry( pMac, pBssDesc );
            continue;
        }
        pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
    }

    csrLLUnlock(pList);

    return (status);
}

/**
 * csrCheck11dChannel
 *
 *FUNCTION:
 * This function is called from csrScanFilterResults function and
 * compare channel number with given channel list.
 *
 *LOGIC:
 * Check Scan result channel number with CFG channel list
 *
 *ASSUMPTIONS:
 *
 *
 *NOTE:
 *
 * @param  channelId      channel number
 * @param  pChannelList   Pointer to channel list
 * @param  numChannels    Number of channel in channel list
 *
 * @return Status
 */

eHalStatus csrCheck11dChannel(tANI_U8 channelId, tANI_U8 *pChannelList, tANI_U32 numChannels)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tANI_U8 i = 0;

    for (i = 0; i < numChannels; i++)
    {
        if(pChannelList[ i ] == channelId)
        {
            status = eHAL_STATUS_SUCCESS;
            break;
        }
    }
    return status;
}

/**
 * csrScanFilterResults
 *
 *FUNCTION:
 * This function is called from csrApplyCountryInformation function and
 * filter scan result based on valid channel list number.
 *
 *LOGIC:
 * Get scan result from scan list and Check Scan result channel number
 * with 11d channel list if channel number is found in 11d channel list
 * then do not remove scan result entry from scan list
 *
 *ASSUMPTIONS:
 *
 *
 *NOTE:
 *
 * @param  pMac        Pointer to Global MAC structure
 *
 * @return Status
 */

eHalStatus csrScanFilterResults(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry,*pTempEntry;
    tCsrScanResult *pBssDesc;
    tANI_U32 len = sizeof(pMac->roam.validChannelList);

    /* Get valid channels list from CFG */
    if (!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac,
                                      pMac->roam.validChannelList, &len)))
    {
        smsLog( pMac, LOGE, "Failed to get Channel list from CFG");
    }

    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
    while( pEntry )
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry,
                                                            LL_ACCESS_LOCK );
        if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId,
                              pMac->roam.validChannelList, len))
        {
            /* Remove Scan result which does not have 11d channel */
            if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry,
                                                              LL_ACCESS_LOCK ))
            {
                csrFreeScanResultEntry( pMac, pBssDesc );
            }
        }
        pEntry = pTempEntry;
    }

    pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK );
    while( pEntry )
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        pTempEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry,
                                                            LL_ACCESS_LOCK );
        if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId,
                              pMac->roam.validChannelList, len))
        {
            /* Remove Scan result which does not have 11d channel */
            if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry,
                        LL_ACCESS_LOCK ))
            {
                csrFreeScanResultEntry( pMac, pBssDesc );
            }
        }
        else
        {
            smsLog( pMac, LOG1, FL("%d is a Valid channel"),
                    pBssDesc->Result.BssDescriptor.channelId);
        }
        pEntry = pTempEntry;
    }
    return status;
}

/**
 * csrScanFilterDFSResults
 *
 *FUNCTION:
 * This function filter BSSIDs on DFS channels from the scan results.
 *
 *LOGIC:
 * Get scan result from scan list and Check Scan result channel number
 * with 11d channel list if channel number is found in 11d channel list
 * and if fEnableDFSChnlScan is zero and if channel is DFS, then
 * remove scan result entry from scan list
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  pMac        Pointer to Global MAC structure
 *
 * @return Status
 */

eHalStatus csrScanFilterDFSResults(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry,*pTempEntry;
    tCsrScanResult *pBssDesc;

    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
    while( pEntry )
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry,
                                                            LL_ACCESS_LOCK );
        if((pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_DISABLED) &&
                  CSR_IS_CHANNEL_DFS(pBssDesc->Result.BssDescriptor.channelId))
        {
            smsLog( pMac, LOG1, FL("%d is a DFS ch filtered from scan list"),
                    pBssDesc->Result.BssDescriptor.channelId);
            /* Remove Scan result which does not have 11d channel */
            if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry,
                                                              LL_ACCESS_LOCK ))
            {
                csrFreeScanResultEntry( pMac, pBssDesc );
            }
        }
        else
        {
            smsLog( pMac, LOG1, FL("%d is a Valid channel"),
                    pBssDesc->Result.BssDescriptor.channelId);
        }
        pEntry = pTempEntry;
    }

    pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK );
    while( pEntry )
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        pTempEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry,
                                                            LL_ACCESS_LOCK );

        if((pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_DISABLED) &&
                  CSR_IS_CHANNEL_DFS(pBssDesc->Result.BssDescriptor.channelId))
        {
           smsLog( pMac, LOG1, FL("%d is a DFS ch filtered from scan list"),
                    pBssDesc->Result.BssDescriptor.channelId);
            /* Remove Scan result which does not have 11d channel */
            if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry,
                        LL_ACCESS_LOCK ))
            {
                csrFreeScanResultEntry( pMac, pBssDesc );
            }
        }
        else
        {
            smsLog( pMac, LOG1, FL("%d is a Valid channel"),
                    pBssDesc->Result.BssDescriptor.channelId);
        }
        pEntry = pTempEntry;
    }
    return status;
}


eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tScanResultList *pRetList, *pInList = (tScanResultList *)hIn;
    tCsrScanResult *pResult, *pScanResult;
    tANI_U32 count = 0;
    tListElem *pEntry;
    tANI_U32 bssLen, allocLen;
    
    if(phResult)
    {
        *phResult = CSR_INVALID_SCANRESULT_HANDLE;
    }
    pRetList = vos_mem_malloc(sizeof(tScanResultList));
    if ( NULL == pRetList )
        status = eHAL_STATUS_FAILURE;
    else
    {
        vos_mem_set(pRetList, sizeof(tScanResultList), 0);
        csrLLOpen(pMac->hHdd, &pRetList->List);
        pRetList->pCurEntry = NULL;
        csrLLLock(&pMac->scan.scanResultList);
        csrLLLock(&pInList->List);
        
        pEntry = csrLLPeekHead( &pInList->List, LL_ACCESS_NOLOCK );
        while( pEntry ) 
        {
            pScanResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
            bssLen = pScanResult->Result.BssDescriptor.length + sizeof(pScanResult->Result.BssDescriptor.length);
            allocLen = sizeof( tCsrScanResult ) + bssLen;
            pResult = vos_mem_malloc(allocLen);
            if ( NULL == pResult )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if (!HAL_STATUS_SUCCESS(status))
            {
                csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
                count = 0;
                break;
            }
            vos_mem_set(pResult, allocLen , 0);
            vos_mem_copy(&pResult->Result.BssDescriptor, &pScanResult->Result.BssDescriptor, bssLen);
            if( pScanResult->Result.pvIes )
            {
                pResult->Result.pvIes = vos_mem_malloc(sizeof( tDot11fBeaconIEs ));
                if ( NULL == pResult->Result.pvIes )
                        status = eHAL_STATUS_FAILURE;
                else
                        status = eHAL_STATUS_SUCCESS;
                if (!HAL_STATUS_SUCCESS(status))
                {
                    //Free the memory we allocate above first
                    vos_mem_free(pResult);
                    csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
                    count = 0;
                    break;
                }
                vos_mem_copy(pResult->Result.pvIes, pScanResult->Result.pvIes,
                             sizeof( tDot11fBeaconIEs ));
            }
            csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_LOCK);
            count++;
            pEntry = csrLLNext( &pInList->List, pEntry, LL_ACCESS_NOLOCK );
        }//while
        csrLLUnlock(&pInList->List);
        csrLLUnlock(&pMac->scan.scanResultList);
        
        if(HAL_STATUS_SUCCESS(status))
        {
            if(0 == count)
            {
                csrLLClose(&pRetList->List);
                vos_mem_free(pRetList);
                status = eHAL_STATUS_E_NULL_VALUE;
            }
            else if(phResult)
            {
                *phResult = pRetList;
            }
        }
    }//Allocated pRetList
    
    return (status);
}


 
eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirMbMsg *pMsg = (tSirMbMsg *)pMsgBuf;
    tSirSmeDisConDoneInd *pDisConDoneInd;
    tCsrRoamSession  *pSession;
    tCsrRoamInfo roamInfo = {0};

    if((eWNI_SME_SCAN_RSP == pMsg->type) ||
       (eWNI_SME_GET_SCANNED_CHANNEL_RSP == pMsg->type))
    {
        status = csrScanSmeScanResponse( pMac, pMsgBuf );
    }
    else
    {
        switch (pMsg->type)
        {
            case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
            {
                tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
                tCsrRoamInfo *pRoamInfo = NULL;
                tANI_U32 sessionId;
                eHalStatus status;

                smsLog( pMac, LOG1,
                        FL("Scanning : ASSOCIATION confirmation can be given to upper layer "));
                pRoamInfo = &roamInfo;
                pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *)pMsgBuf;
                status = csrRoamGetSessionIdFromBSSID( pMac,
                                      (tCsrBssid *)pUpperLayerAssocCnf->bssId,
                                      &sessionId );
                pSession = CSR_GET_SESSION(pMac, sessionId);

                if(!pSession)
                {
                    smsLog(pMac, LOGE, FL("session %d not found "), sessionId);
                    return eHAL_STATUS_FAILURE;
                }

                //send the status code as Success
                pRoamInfo->statusCode = eSIR_SME_SUCCESS;
                pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile;
                pRoamInfo->staId = (tANI_U8)pUpperLayerAssocCnf->aid;
                pRoamInfo->rsnIELen =
                            (tANI_U8)pUpperLayerAssocCnf->rsnIE.length;
                pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata;
                pRoamInfo->addIELen =
                            (tANI_U8)pUpperLayerAssocCnf->addIE.length;
                pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata;
                vos_mem_copy(pRoamInfo->peerMac,
                             pUpperLayerAssocCnf->peerMacAddr,
                             sizeof(tSirMacAddr));
                vos_mem_copy(&pRoamInfo->bssid,
                             pUpperLayerAssocCnf->bssId,
                             sizeof(tCsrBssid));
                pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta;
#ifdef WLAN_FEATURE_AP_HT40_24G
                pRoamInfo->HT40MHzIntoEnabledSta =
                           pUpperLayerAssocCnf->HT40MHzIntoEnabledSta;
#endif
                if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) )
                {
                    pMac->roam.roamSession[sessionId].connectState =
                                        eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
                    pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq;
                    status = csrRoamCallCallback(pMac, sessionId, pRoamInfo,
                                       0, eCSR_ROAM_INFRA_IND,
                                       eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
                }
                if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile))
                {
                    vos_sleep( 100 );
                    pMac->roam.roamSession[sessionId].connectState =
                                    eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;//Sta
                    status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0,
                                    eCSR_ROAM_WDS_IND,
                                    eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta
                }
                break;
        }
        case eWNI_SME_DISCONNECT_DONE_IND:
            pDisConDoneInd = (tSirSmeDisConDoneInd *)(pMsg);

            smsLog( pMac, LOG1,
                FL("eWNI_SME_DISCONNECT_DONE_IND RC:%d"),
                    pDisConDoneInd->reasonCode);
            pSession = CSR_GET_SESSION(pMac,pDisConDoneInd->sessionId);
            if (pSession)
            {
                if( CSR_IS_SESSION_VALID(pMac, pDisConDoneInd->sessionId))
                {
                    roamInfo.reasonCode = pDisConDoneInd->reasonCode;
                    roamInfo.statusCode = eSIR_SME_STA_DISASSOCIATED;
                    vos_mem_copy(roamInfo.peerMac, pDisConDoneInd->peerMacAddr,
                                 sizeof(tSirMacAddr));
                    status = csrRoamCallCallback(pMac,
                                    pDisConDoneInd->sessionId,
                                    &roamInfo, 0,
                                    eCSR_ROAM_LOSTLINK,
                                    eCSR_ROAM_RESULT_DISASSOC_IND);
                    /*
                     * Update the previous state if
                     * previous state was eCSR_ROAMING_STATE_JOINED
                     * as we are disconnected and
                     * currunt state is scanning
                     */
                    if (!CSR_IS_INFRA_AP(&pSession->connectedProfile)
                        && (eCSR_ROAMING_STATE_IDLE !=
                        pMac->roam.prev_state[pDisConDoneInd->sessionId]))
                        pMac->roam.prev_state[pDisConDoneInd->sessionId] =
                                  eCSR_ROAMING_STATE_IDLE;
                }
                else
                {
                    smsLog(pMac, LOGE, FL("Inactive session %d"),
                           pDisConDoneInd->sessionId);
                    status = eHAL_STATUS_FAILURE;
                }
            }
            else
            {
                smsLog(pMac, LOGE, FL("Invalid session"));
                status = eHAL_STATUS_FAILURE;
            }
            break;

        default :
            if( csrIsAnySessionInConnectState( pMac ) )
            {
                /*In case of we are connected, we need to check whether connect
                 * status changes because scan may also run while connected.
                 */
                csrRoamCheckForLinkStatusChange( pMac, (tSirSmeRsp *)pMsgBuf );
            }
            else
            {
                smsLog( pMac, LOGW,
                        "Message [0x%04x] received in state, when expecting Scan Response",
                         pMsg->type );
            }
        }
    }

    return (status);
}

void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr,tSirBssDescription *pOldBssDescr)
{
    int elem_id, len, elem_len;
    tANI_U8 *pbIe;

    //If failed to remove, assuming someone else got it.
    if((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) &&
       (0 == pNewBssDescr->WscIeLen))
    {
        len = GET_IE_LEN_IN_BSS(pOldBssDescr->length);
        pbIe = (tANI_U8 *)pOldBssDescr->ieFields;
        //Save WPS IE if it exists
        pNewBssDescr->WscIeLen = 0;
        while (len >= 2)
        {
            elem_id = pbIe[0];
            elem_len = pbIe[1];
            len -= 2;
            if (elem_len > len) {
                smsLog(pMac, LOGW, FL("Invalid eid: %d elem_len: %d left: %d"),
                       elem_id, elem_len, len);
                return;
            }
            if ((elem_id == DOT11F_EID_WSCPROBERES) &&
                (elem_len >= DOT11F_IE_WSCPROBERES_MIN_LEN) &&
                ((pbIe[2] == 0x00) && (pbIe[3] == 0x50) && (pbIe[4] == 0xf2) &&
                (pbIe[5] == 0x04)))
            {
                if((elem_len + 2) <= WSCIE_PROBE_RSP_LEN)
                {
                    vos_mem_copy(pNewBssDescr->WscIeProbeRsp,
                                 pbIe, elem_len + 2);
                    pNewBssDescr->WscIeLen = elem_len + 2;
                }
                return;
            }
            len -= elem_len;
            pbIe += (elem_len + 2);
        }
    }
}



//pIes may be NULL
tANI_BOOLEAN csrRemoveDupBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDescr,
                                         tDot11fBeaconIEs *pIes, tAniSSID *pSsid, v_TIME_t *timer, tANI_BOOLEAN fForced )
{
    tListElem *pEntry;

    tCsrScanResult *pBssDesc;
    tANI_BOOLEAN fRC = FALSE;
    tDot11fBeaconIEs *temp_ie = pIes;

    if (!temp_ie)
        csrGetParsedBssDescriptionIEs(pMac, pSirBssDescr, &temp_ie);

    // Walk through all the chained BssDescriptions.  If we find a chained BssDescription that
    // matches the BssID of the BssDescription passed in, then these must be duplicate scan
    // results for this Bss.  In that case, remove the 'old' Bss description from the linked list.
    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );

    while( pEntry ) 
    {
        pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );

        // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType
        // matches
        if (csrIsDuplicateBssDescription(pMac, &pBssDesc->Result.BssDescriptor,
                                          pSirBssDescr, temp_ie, fForced))
        {
            /*
             * Due to Rx sensitivity issue, sometime beacons are seen on
             * adjacent channel so workaround in software is needed. If DS
             * params or HT info are present driver can get proper channel
             * info from these IEs and the older RSSI values are used in new
             * entry.
             *
             * For the cases where DS params and HT info is not present,
             * driver needs to check below conditions to update proper
             * channel so that the older RSSI and channel values are used in
             * new entry:
             *  -- The old entry channel and new entry channel are not same
             *  -- RSSI is below 15db or more from old value, this indicate
             *     that the signal has leaked in adjacent channel
             */
            if (!pSirBssDescr->fProbeRsp &&
                (temp_ie && !temp_ie->DSParams.present &&
                !temp_ie->HTInfo.present) &&
                (pSirBssDescr->channelId !=
                 pBssDesc->Result.BssDescriptor.channelId) &&
                ((pBssDesc->Result.BssDescriptor.rssi - pSirBssDescr->rssi) >
                 SIR_ADJACENT_CHANNEL_RSSI_DIFF_THRESHOLD)) {
                 pSirBssDescr->channelId =
                            pBssDesc->Result.BssDescriptor.channelId;
                pSirBssDescr->rssi =
                                 pBssDesc->Result.BssDescriptor.rssi;
            }
            pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) +
                                             ((tANI_S32)pBssDesc->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 );
            // Remove the 'old' entry from the list....
            if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ) )
            {
                // !we need to free the memory associated with this node
                //If failed to remove, assuming someone else got it.
                *pSsid = pBssDesc->Result.ssId;
                *timer = pBssDesc->Result.timer;
                csrCheckNSaveWscIe(pMac, pSirBssDescr, &pBssDesc->Result.BssDescriptor);
                
                csrFreeScanResultEntry( pMac, pBssDesc );
            }
            else
            {
                smsLog( pMac, LOGW, FL( "  fail to remove entry" ) );
            }
            fRC = TRUE;

            // If we found a match, we can stop looking through the list.
            break;
        }

        pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK );
    }

    if (!pIes && temp_ie)
       vos_mem_free(temp_ie);

    return fRC;
}


eHalStatus csrAddPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId,
                                     tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, "csrAddPMKIDCandidateList called pMac->scan.NumPmkidCandidate = %d", pSession->NumPmkidCandidate);
    if( pIes )
    {
        // check if this is a RSN BSS
        if( pIes->RSN.present )
        {
            // Check if the BSS is capable of doing pre-authentication
            if( pSession->NumPmkidCandidate < CSR_MAX_PMKID_ALLOWED )
            {

#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
                {
                    WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type);
                    vos_mem_set(&secEvent, sizeof(vos_event_wlan_security_payload_type), 0);
                    secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND;
                    secEvent.encryptionModeMulticast = 
                        (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType);
                    secEvent.encryptionModeUnicast = 
                        (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType);
                    vos_mem_copy(secEvent.bssid, pSession->connectedProfile.bssid, 6);
                    secEvent.authMode = 
                        (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType);
                    WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
                }
#endif//#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR

                // if yes, then add to PMKIDCandidateList
                vos_mem_copy(pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].BSSID,
                             pBssDesc->bssId, WNI_CFG_BSSID_LEN);
                // Bit 0 offirst byte - PreAuthentication Capability
                if ( (pIes->RSN.RSN_Cap[0] >> 0) & 0x1 )
                {
                    pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported
                                                                          = eANI_BOOLEAN_TRUE;
                }
                else
                {
                    pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported
                                                                          = eANI_BOOLEAN_FALSE;
                }
                pSession->NumPmkidCandidate++;
            }
            else
            {
                status = eHAL_STATUS_FAILURE;
            }
        }
    }

    return (status);
}

//This function checks whether new AP is found for the current connected profile
//If it is found, it return the sessionId, else it return invalid sessionID
tANI_U32 csrProcessBSSDescForPMKIDList(tpAniSirGlobal pMac, 
                                           tSirBssDescription *pBssDesc,
                                           tDot11fBeaconIEs *pIes)
{
    tANI_U32 i, bRet = CSR_SESSION_ID_INVALID;
    tCsrRoamSession *pSession;
    tDot11fBeaconIEs *pIesLocal = pIes;

    if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) )
    {
        for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
        {
            if( CSR_IS_SESSION_VALID( pMac, i ) )
            {
                pSession = CSR_GET_SESSION( pMac, i );
                if( csrIsConnStateConnectedInfra( pMac, i ) && 
                    ( eCSR_AUTH_TYPE_RSN == pSession->connectedProfile.AuthType ) )
                {
                    if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile, pBssDesc, pIesLocal))
                    {
                        //this new BSS fits the current profile connected
                        if(HAL_STATUS_SUCCESS(csrAddPMKIDCandidateList(pMac, i, pBssDesc, pIesLocal)))
                        {
                            bRet = i;
                        }
                        break;
                    }
                }
            }
        }
        if( !pIes )
        {
            vos_mem_free(pIesLocal);
        }
    }

    return (tANI_U8)bRet;
}

#ifdef FEATURE_WLAN_WAPI
eHalStatus csrAddBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId,
                                    tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, "csrAddBKIDCandidateList called pMac->scan.NumBkidCandidate = %d",
                                             pSession->NumBkidCandidate);
    if( pIes )
    {
        // check if this is a WAPI BSS
        if( pIes->WAPI.present )
        {
            // Check if the BSS is capable of doing pre-authentication
            if( pSession->NumBkidCandidate < CSR_MAX_BKID_ALLOWED )
            {

                // if yes, then add to BKIDCandidateList
                vos_mem_copy(pSession->BkidCandidateInfo[pSession->NumBkidCandidate].BSSID,
                             pBssDesc->bssId, WNI_CFG_BSSID_LEN);
                if ( pIes->WAPI.preauth )
                {
                    pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported
                                                                         = eANI_BOOLEAN_TRUE;
                }
                else
                {
                    pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported
                                                                        = eANI_BOOLEAN_FALSE;
                }
                pSession->NumBkidCandidate++;
            }
            else
            {
                status = eHAL_STATUS_FAILURE;
            }
        }
    }

    return (status);
}

//This function checks whether new AP is found for the current connected profile
//if so add to BKIDCandidateList
tANI_BOOLEAN csrProcessBSSDescForBKIDList(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc,
                                          tDot11fBeaconIEs *pIes)
{
    tANI_BOOLEAN fRC = FALSE;
    tDot11fBeaconIEs *pIesLocal = pIes;
    tANI_U32 sessionId;
    tCsrRoamSession *pSession;

    if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) )
    {
        for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
        {
            if( CSR_IS_SESSION_VALID( pMac, sessionId) )
            {
                pSession = CSR_GET_SESSION( pMac, sessionId );
                if( csrIsConnStateConnectedInfra( pMac, sessionId ) && 
                    eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == pSession->connectedProfile.AuthType)
                {
                    if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile,pBssDesc, pIesLocal))
                    {
                        //this new BSS fits the current profile connected
                        if(HAL_STATUS_SUCCESS(csrAddBKIDCandidateList(pMac, sessionId, pBssDesc, pIesLocal)))
                        {
                            fRC = TRUE;
                        }
                    }
                }
            }
        }
        if(!pIes)
        {
            vos_mem_free(pIesLocal);
        }

    }
    return fRC;
}

#endif


static void csrMoveTempScanResultsToMainList( tpAniSirGlobal pMac, tANI_U8 reason )
{
    tListElem *pEntry;
    tCsrScanResult *pBssDescription;
    tANI_BOOLEAN    fDupBss;
#ifdef FEATURE_WLAN_WAPI
    tANI_BOOLEAN fNewWapiBSSForCurConnection = eANI_BOOLEAN_FALSE;
#endif /* FEATURE_WLAN_WAPI */
    tDot11fBeaconIEs *pIesLocal = NULL;
    tANI_U32 sessionId = CSR_SESSION_ID_INVALID;
    tAniSSID tmpSsid;
    v_TIME_t timer=0;
    tANI_U8 occupied_chan_count = pMac->scan.occupiedChannels.numChannels;

    tmpSsid.length = 0;

    // remove the BSS descriptions from temporary list
    while( ( pEntry = csrLLRemoveTail( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ) ) != NULL)
    {
        pBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );

        smsLog( pMac, LOG2, "...Bssid= "MAC_ADDRESS_STR" chan= %d, rssi = -%d",
                      MAC_ADDR_ARRAY(pBssDescription->Result.BssDescriptor.bssId),
                      pBssDescription->Result.BssDescriptor.channelId,
                pBssDescription->Result.BssDescriptor.rssi * (-1) );

        //At this time, pBssDescription->Result.pvIes may be NULL
        pIesLocal = (tDot11fBeaconIEs *)( pBssDescription->Result.pvIes );
        if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssDescription->Result.BssDescriptor, &pIesLocal))) )
        {
            smsLog(pMac, LOGE, FL("  Cannot pared IEs"));
            csrFreeScanResultEntry(pMac, pBssDescription);
            continue;
        }
        fDupBss = csrRemoveDupBssDescription( pMac, &pBssDescription->Result.BssDescriptor, pIesLocal, &tmpSsid, &timer, FALSE );
        //Check whether we have reach out limit, but don't lose the LFR candidates came from FW
        if( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac)
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
            && !( eCsrScanGetLfrResult == reason )
#endif
          )
        {
            smsLog(pMac, LOG1, FL("########## BSS Limit reached ###########"));
            csrPurgeScanResults(pMac);
        }
        // check for duplicate scan results
        if ( !fDupBss )
        {
            //Found a new BSS
            sessionId = csrProcessBSSDescForPMKIDList(pMac, 
                             &pBssDescription->Result.BssDescriptor, pIesLocal);
            if( CSR_SESSION_ID_INVALID != sessionId)
            {
                csrRoamCallCallback(pMac, sessionId, NULL, 0, 
                           eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NONE);
            }
        }
        else
        {
            //Check if the new one has SSID it it, if not, use the older SSID if it exists.
            if( (0 == pBssDescription->Result.ssId.length) && tmpSsid.length )
            {
                //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only 
                //if diff of saved SSID time and current time is less than 1 min to avoid
                //side effect of saving SSID with old one is that if AP changes its SSID while remain
                //hidden, we may never see it and also to address the requirement of 
                //When we remove hidden ssid from the profile i.e., forget the SSID via 
                // GUI that SSID shouldn't see in the profile
                if( (vos_timer_get_system_time() - timer) <= HIDDEN_TIMER)
                {
                   pBssDescription->Result.timer = timer;
                   pBssDescription->Result.ssId = tmpSsid;
                }
            }
        }

        //Find a good AP for 11d info
        if ( csrIs11dSupported( pMac ) )
        {
            // check if country information element is present
            if (pIesLocal->Country.present)
            {
                csrAddVoteForCountryInfo(pMac, pIesLocal->Country.country);
                smsLog(pMac, LOGW, FL("11d AP Bssid " MAC_ADDRESS_STR
                                " chan= %d, rssi = -%d, countryCode %c%c"),
                                MAC_ADDR_ARRAY( pBssDescription->Result.BssDescriptor.bssId),
                                pBssDescription->Result.BssDescriptor.channelId,
                                pBssDescription->Result.BssDescriptor.rssi * (-1),
                                pIesLocal->Country.country[0],pIesLocal->Country.country[1] );
             }

        }
        
        // append to main list
        csrScanAddResult(pMac, pBssDescription, pIesLocal);
        if ( (pBssDescription->Result.pvIes == NULL) && pIesLocal )
        {
            vos_mem_free(pIesLocal);
        }
    }

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (sme_IsFeatureSupportedByFW(PER_BASED_ROAMING) &&
       (csrGetInfraSessionId(pMac) != -1) &&
        (pMac->scan.occupiedChannels.numChannels != occupied_chan_count))
    {
        /* Update FW with new list */
        smsLog(pMac, LOGW,
               FL("Updating occupied channel list, new chanNum %d"),
               pMac->scan.occupiedChannels.numChannels);
        csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                           REASON_CHANNEL_LIST_CHANGED);
    }
#endif
    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
    //we don't need to update CC while connected to an AP which is advertising CC already
    if (csrIs11dSupported(pMac))
    {
        tANI_U32 i;
        tCsrRoamSession *pSession;

        for (i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
        {
            if (CSR_IS_SESSION_VALID( pMac, i ) )
            {
                pSession = CSR_GET_SESSION( pMac, i );
                if (csrIsConnStateConnected(pMac, i))
                {
                    smsLog(pMac, LOGW, FL("No need for updating CC in"
                                          "connected state"));
                    goto end;
                }
            }
        }
        if (csrElectedCountryInfo(pMac))
            csrLearnCountryInformation(pMac, NULL, NULL,
                    eANI_BOOLEAN_TRUE);
    }

end:
    //If we can find the current 11d info in any of the scan results, or
    // a good enough AP with the 11d info from the scan results then no need to
    // get into ambiguous state
    if(pMac->scan.fAmbiguous11dInfoFound) 
    {
      if((pMac->scan.fCurrent11dInfoMatch))
      {
        pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
      }
    }

#ifdef FEATURE_WLAN_WAPI
    if(fNewWapiBSSForCurConnection)
    {
        //remember it first
        csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NEW_WAPI_BSS);
    }
#endif /* FEATURE_WLAN_WAPI */

    return;
}

/**
 * csrPurgeScanResults() - This function removes scan entry based
 * on RSSI or AGE
 * @pMac: pointer to Global MAC structure
 *
 * This function removes scan entry based on RSSI or AGE.
 * If an scan entry with RSSI less than CSR_PURGE_RSSI_THRESHOLD,
 * the scan entry is removed else oldest entry is removed.
 *
 * Return: None
 */
void csrPurgeScanResults(tpAniSirGlobal pMac)
{
    tListElem *pEntry, *tmpEntry;
    tCsrScanResult *pResult, *oldest_bss = NULL, *weakest_bss = NULL;
    v_TIME_t oldest_entry = 0;
    v_TIME_t curTime = vos_timer_get_system_time();
    tANI_S8 weakest_rssi = 0;

    csrLLLock(&pMac->scan.scanResultList);
    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
    while(pEntry)
    {
        tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry,
                LL_ACCESS_NOLOCK);
        pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        if((curTime -
                 pResult->Result.BssDescriptor.nReceivedTime) > oldest_entry)
        {
            oldest_entry =  curTime -
                                pResult->Result.BssDescriptor.nReceivedTime;
            oldest_bss = pResult;
        }
        if (pResult->Result.BssDescriptor.rssi < weakest_rssi)
        {
            weakest_rssi = pResult->Result.BssDescriptor.rssi;
            weakest_bss = pResult;
        }
        pEntry = tmpEntry;
    }
    if (oldest_bss)
    {
        tCsrScanResult *bss_to_remove;

        if (weakest_rssi < CSR_PURGE_RSSI_THRESHOLD)
            bss_to_remove = weakest_bss;
        else
            bss_to_remove = oldest_bss;

        //Free the old BSS Entries
        if(csrLLRemoveEntry(&pMac->scan.scanResultList,
                       &bss_to_remove->Link, LL_ACCESS_NOLOCK))
        {
            smsLog(pMac, LOG1,
               FL("BSSID: "MAC_ADDRESS_STR" Removed, time delta (%lu) RSSI %d"),
               MAC_ADDR_ARRAY(
               bss_to_remove->Result.BssDescriptor.bssId),
               (curTime -
               bss_to_remove->Result.BssDescriptor.nReceivedTime),
               bss_to_remove->Result.BssDescriptor.rssi);
            csrFreeScanResultEntry(pMac, bss_to_remove);
        }
    }
    csrLLUnlock(&pMac->scan.scanResultList);
}

static tCsrScanResult *csrScanSaveBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription,
                                                  tDot11fBeaconIEs *pIes)
{
    tCsrScanResult *pCsrBssDescription = NULL;
    tANI_U32 cbBSSDesc;
    tANI_U32 cbAllocated;
    tListElem *pEntry;

    // figure out how big the BSS description is (the BSSDesc->length does NOT
    // include the size of the length field itself).
    cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length );

    cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc;

    pCsrBssDescription = vos_mem_malloc(cbAllocated);
    if ( NULL != pCsrBssDescription )
    {
        vos_mem_set(pCsrBssDescription, cbAllocated, 0);
        pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
        vos_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc);
#if defined(VOSS_ENSBALED)
        VOS_ASSERT( pCsrBssDescription->Result.pvIes == NULL );
#endif
        csrScanAddResult(pMac, pCsrBssDescription, pIes);
        pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
    }

    return( pCsrBssDescription );
}

// Append a Bss Description...
tCsrScanResult *csrScanAppendBssDescription( tpAniSirGlobal pMac, 
                                             tSirBssDescription *pSirBssDescription, 
                                             tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForced )
{
    tCsrScanResult *pCsrBssDescription = NULL;
    tAniSSID tmpSsid;
    v_TIME_t timer = 0;
    int result;

    tmpSsid.length = 0;
    result = csrRemoveDupBssDescription( pMac, pSirBssDescription, pIes, &tmpSsid, &timer, fForced );
    pCsrBssDescription = csrScanSaveBssDescription( pMac, pSirBssDescription, pIes );
    if (result && (pCsrBssDescription != NULL))
    {
        //Check if the new one has SSID it it, if not, use the older SSID if it exists.
        if( (0 == pCsrBssDescription->Result.ssId.length) && tmpSsid.length )
        {
            //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only
            //if diff of saved SSID time and current time is less than 1 min to avoid
            //side effect of saving SSID with old one is that if AP changes its SSID while remain
            //hidden, we may never see it and also to address the requirement of
            //When we remove hidden ssid from the profile i.e., forget the SSID via
            // GUI that SSID shouldn't see in the profile
            if((vos_timer_get_system_time()-timer) <= HIDDEN_TIMER)
            { 
              pCsrBssDescription->Result.ssId = tmpSsid;
              pCsrBssDescription->Result.timer = timer;
            }
        }
    }


    return( pCsrBssDescription );
}



void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList )
{
    tCsrChannelPowerInfo *pChannelSet;
    tListElem *pEntry;

    csrLLLock(pChannelList); 
    // Remove the channel sets from the learned list and put them in the free list
    while( ( pEntry = csrLLRemoveHead( pChannelList, LL_ACCESS_NOLOCK ) ) != NULL)
    {
        pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
        if( pChannelSet )
        {
            vos_mem_free(pChannelSet);
        }
    }
    csrLLUnlock(pChannelList);
    return;
}


/*
 * Save the channelList into the ultimate storage as the final stage of channel 
 * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power limit are all stored inside this data structure
 */
eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable )
{
    tANI_U32 i = tableSize / sizeof( tSirMacChanInfo );
    tSirMacChanInfo *pChannelInfo;
    tCsrChannelPowerInfo *pChannelSet;
    tANI_BOOLEAN f2GHzInfoFound = FALSE;
    tANI_BOOLEAN f2GListPurged = FALSE, f5GListPurged = FALSE;

    pChannelInfo = channelTable;
    // atleast 3 bytes have to be remaining  -- from "countryString"
    while ( i-- )
    {
        pChannelSet = vos_mem_malloc(sizeof(tCsrChannelPowerInfo));
        if ( NULL != pChannelSet )
        {
            vos_mem_set(pChannelSet, sizeof(tCsrChannelPowerInfo), 0);
            pChannelSet->firstChannel = pChannelInfo->firstChanNum;
            pChannelSet->numChannels = pChannelInfo->numChannels;

            // Now set the inter-channel offset based on the frequency band the channel set lies in
            if( (CSR_IS_CHANNEL_24GHZ(pChannelSet->firstChannel)) &&
                    ((pChannelSet->firstChannel + (pChannelSet->numChannels - 1)) <= CSR_MAX_24GHz_CHANNEL_NUMBER) )

            {
                pChannelSet->interChannelOffset = 1;
                f2GHzInfoFound = TRUE;
            }
            else if ( (CSR_IS_CHANNEL_5GHZ(pChannelSet->firstChannel)) &&
                ((pChannelSet->firstChannel + ((pChannelSet->numChannels - 1) * 4)) <= CSR_MAX_5GHz_CHANNEL_NUMBER) )
            {
                pChannelSet->interChannelOffset = 4;
                f2GHzInfoFound = FALSE;
            }
            else
            {
                smsLog( pMac, LOGW, FL("Invalid Channel %d Present in Country IE"),
                        pChannelSet->firstChannel);
                vos_mem_free(pChannelSet);
                return eHAL_STATUS_FAILURE;
            }

            pChannelSet->txPower = CSR_ROAM_MIN( pChannelInfo->maxTxPower, pMac->roam.configParam.nTxPowerCap );

            if( f2GHzInfoFound )
            {
                if( !f2GListPurged )
                {
                    // purge previous results if found new
                    csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList24 );
                    f2GListPurged = TRUE;
                }

                if(CSR_IS_OPERATING_BG_BAND(pMac))
                {
                    // add to the list of 2.4 GHz channel sets
                    csrLLInsertTail( &pMac->scan.channelPowerInfoList24, &pChannelSet->link, LL_ACCESS_LOCK );
                }
                else {
                    smsLog( pMac, LOGW, FL("Adding 11B/G channels in 11A mode -- First Channel is %d"),
                                pChannelSet->firstChannel);
                      vos_mem_free(pChannelSet);
                }
            }
            else
            {
                // 5GHz info found
                if( !f5GListPurged )
                {
                    // purge previous results if found new
                    csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList5G );
                    f5GListPurged = TRUE;
                }

                if(CSR_IS_OPERATING_A_BAND(pMac))
                {
                    // add to the list of 5GHz channel sets
                    csrLLInsertTail( &pMac->scan.channelPowerInfoList5G, &pChannelSet->link, LL_ACCESS_LOCK );
                }
                else {
                    smsLog( pMac, LOGW, FL("Adding 11A channels in B/G mode -- First Channel is %d"),
                                pChannelSet->firstChannel);
                    vos_mem_free(pChannelSet);
                }
            }
        }

        pChannelInfo++;                // move to next entry
    }

    return eHAL_STATUS_SUCCESS;
}

static  void csrClearDfsChannelList( tpAniSirGlobal pMac )
{
    tSirMbMsg *pMsg;
    tANI_U16 msgLen;

    msgLen = (tANI_U16)(sizeof( tSirMbMsg ));
    pMsg = vos_mem_malloc(msgLen);
    if ( NULL != pMsg )
    {
       vos_mem_set((void *)pMsg, msgLen, 0);
       pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_CLEAR_DFS_CHANNEL_LIST);
       pMsg->msgLen = pal_cpu_to_be16(msgLen);
       palSendMBMessage(pMac->hHdd, pMsg);
    }
}

void csrApplyPower2Current( tpAniSirGlobal pMac )
{
    smsLog( pMac, LOG3, FL(" Updating Cfg with power settings"));
    csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList24, WNI_CFG_MAX_TX_POWER_2_4 );
    csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList5G, WNI_CFG_MAX_TX_POWER_5 );
}


void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode, tANI_BOOLEAN updateRiva)
{
    int i, j, count, countryIndex = -1;
    tANI_U8 numChannels = 0;
    tANI_U8 tempNumChannels = 0;
    tANI_U8 channelIgnore = FALSE;
    tCsrChannel ChannelList;

    if( pChannelList->numChannels )
    {
        for(count=0; count < MAX_COUNTRY_IGNORE; count++)
        {
            if(vos_mem_compare(countryCode, countryIgnoreList[count].countryCode,
                                                          VOS_COUNTRY_CODE_LEN))
            {
                countryIndex = count;
                break;
            }
        }
        tempNumChannels = CSR_MIN(pChannelList->numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);

        for(i=0; i < tempNumChannels; i++)
        {
            channelIgnore = FALSE;
            if( countryIndex != -1 )
            {
                for(j=0; j < countryIgnoreList[countryIndex].channelCount; j++)
                {
                    if( pChannelList->channelList[i] ==
                            countryIgnoreList[countryIndex].channelList[j] )
                    {
                        channelIgnore = TRUE;
                        break;
                    }
                }
            }
            if( FALSE == channelIgnore )
            {
                ChannelList.channelList[numChannels] = pChannelList->channelList[i];
                numChannels++;
            }
        }
        ChannelList.numChannels = numChannels;
        csrApplyPower2Current( pMac );     // Store the channel+power info in the global place: Cfg
        csrSetCfgValidChannelList(pMac, ChannelList.channelList, ChannelList.numChannels);
        // extend scan capability
        //  build a scan list based on the channel list : channel# + active/passive scan
        csrSetCfgScanControlList(pMac, countryCode, &ChannelList);
#ifdef FEATURE_WLAN_SCAN_PNO
        if (updateRiva)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, FL("  Sending 11d PNO info to Riva"));
            // Send HAL UpdateScanParams message
            pmcUpdateScanParams(pMac, &(pMac->roam.configParam), &ChannelList, TRUE);
        }
#endif // FEATURE_WLAN_SCAN_PNO
    }
    else
    {
        smsLog( pMac, LOGE, FL("  11D channel list is empty"));
    }
    csrSetCfgCountryCode(pMac, countryCode);
}

void csrUpdateFCCChannelList(tpAniSirGlobal pMac)
{
    tCsrChannel ChannelList;
    tANI_U8 chnlIndx = 0;
    int i;

    for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ )
    {
        if (pMac->scan.fcc_constraint &&
            ((pMac->scan.base20MHzChannels.channelList[i] == 12) ||
            (pMac->scan.base20MHzChannels.channelList[i] == 13)))
        {
                    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                        FL("removing channel %d"),
                        pMac->scan.base20MHzChannels.channelList[i]);
            continue;
        }
        ChannelList.channelList[chnlIndx] =
        pMac->scan.base20MHzChannels.channelList[i];
        chnlIndx++;
    }
    csrSetCfgValidChannelList(pMac, ChannelList.channelList, chnlIndx);
    csrScanFilterResults(pMac);
}

void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce, tANI_BOOLEAN updateRiva )
{
    if( fForce || (csrIs11dSupported( pMac ) && (!pMac->scan.f11dInfoReset)))
    {

#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
    {
        vos_log_802_11d_pkt_type *p11dLog;
        int Index;

        WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C);
        if(p11dLog)
        {
            p11dLog->eventId = WLAN_80211D_EVENT_RESET;
            vos_mem_copy(p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3);
            p11dLog->numChannel = pMac->scan.base20MHzChannels.numChannels;
            if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL)
            {
                vos_mem_copy(p11dLog->Channels,
                             pMac->scan.base20MHzChannels.channelList,
                             p11dLog->numChannel);
                for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++)
                {
                    p11dLog->TxPwr[Index] = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap );
                }
            }
            if(!pMac->roam.configParam.Is11dSupportEnabled)
            {
                p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
            }
            else if(pMac->roam.configParam.fEnforceDefaultDomain)
            {
                p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN;
            }
            else
            {
                p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN;
            }
            WLAN_VOS_DIAG_LOG_REPORT(p11dLog);
        }
    }
#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR

        csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels);
        csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels);

        csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE);
        csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE);
        // ... and apply the channel list, power settings, and the country code.
        csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, updateRiva );
        // clear the 11d channel list
        vos_mem_set(&pMac->scan.channels11d, sizeof(pMac->scan.channels11d), 0);
        pMac->scan.f11dInfoReset = eANI_BOOLEAN_TRUE;
        pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE;
    }

    return;
}


eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_BOOLEAN fRestart = eANI_BOOLEAN_FALSE;

    //Use the Country code and domain from EEPROM
    vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault,
                 WNI_CFG_COUNTRY_CODE_LEN);
    csrSetRegulatoryDomain(pMac, pMac->scan.domainIdCurrent, &fRestart);
    if( ((eANI_BOOLEAN_FALSE == fRestart) || (pfRestartNeeded == NULL) )
          && !csrIsInfraConnected(pMac))
    {
        //Only reset the country info if we don't need to restart
        csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
    }
    if(pfRestartNeeded)
    {
        *pfRestartNeeded = fRestart;
    }

    return (status);
}

void csrClearVotesForCountryInfo(tpAniSirGlobal pMac)
{
    pMac->scan.countryCodeCount = 0;
    vos_mem_set(pMac->scan.votes11d,
                 sizeof(tCsrVotes11d) * CSR_MAX_NUM_COUNTRY_CODE, 0);
}

void csrAddVoteForCountryInfo(tpAniSirGlobal pMac, tANI_U8 *pCountryCode)
{
    tANI_BOOLEAN match = FALSE;
    tANI_U8 i;

    /* convert to UPPER here so we are assured
     * the strings are always in upper case.
     */
    for( i = 0; i < 3; i++ )
    {
        pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] );
    }

    /* Some of the 'old' Cisco 350 series AP's advertise NA as the
     * country code (for North America ??). NA is not a valid country code
     * or domain so let's allow this by changing it to the proper
     * country code (which is US).  We've also seen some NETGEAR AP's
     * that have "XX " as the country code with valid 2.4 GHz US channel
     * information.  If we cannot find the country code advertised in the
     * 11d information element, let's default to US.
     */

    if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac,
                  pCountryCode, NULL,COUNTRY_QUERY ) ) )
    {
        pCountryCode[ 0 ] = '0';
        pCountryCode[ 1 ] = '0';
    }

    /* We've seen some of the AP's improperly put a 0 for the
     * third character of the country code. spec says valid charcters are
     * 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either).
     * if we see a 0 in this third character, let's change it to a ' '.
     */
    if ( 0 == pCountryCode[ 2 ] )
    {
        pCountryCode[ 2 ] = ' ';
    }

    for (i = 0; i < pMac->scan.countryCodeCount; i++)
    {
        match = (vos_mem_compare(pMac->scan.votes11d[i].countryCode,
                          pCountryCode, 2));
        if(match)
        {
            break;
        }
    }

    if (match)
    {
        pMac->scan.votes11d[i].votes++;
    }
    else
    {
        vos_mem_copy( pMac->scan.votes11d[pMac->scan.countryCodeCount].countryCode,
                       pCountryCode, 3 );
        pMac->scan.votes11d[pMac->scan.countryCodeCount].votes = 1;
        pMac->scan.countryCodeCount++;
    }

    return;
}

tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac)
{
    tANI_BOOLEAN fRet = FALSE;
    tANI_U8 maxVotes = 0;
    tANI_U8 i, j=0;

    if (!pMac->scan.countryCodeCount)
    {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
                "No AP with 11d Country code is present in scan list");
        return fRet;
    }
    maxVotes = pMac->scan.votes11d[0].votes;
    fRet = TRUE;

    for(i = 1; i < pMac->scan.countryCodeCount; i++)
    {
        /* If we have a tie for max votes for 2 different country codes,
         * pick random.we can put some more intelligence - TBD
         */
        if (maxVotes < pMac->scan.votes11d[i].votes)
        {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     " Votes for Country %c%c : %d\n",
                    pMac->scan.votes11d[i].countryCode[0],
                    pMac->scan.votes11d[i].countryCode[1],
                    pMac->scan.votes11d[i].votes);

            maxVotes = pMac->scan.votes11d[i].votes;
            j = i;
            fRet = TRUE;
        }

    }
    if (fRet)
    {
        vos_mem_copy(pMac->scan.countryCodeElected,
            pMac->scan.votes11d[j].countryCode, WNI_CFG_COUNTRY_CODE_LEN);
        vos_mem_copy(pMac->scan.countryCode11d,
            pMac->scan.votes11d[j].countryCode, WNI_CFG_COUNTRY_CODE_LEN);
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                 "Selected Country is %c%c With count %d\n",
                      pMac->scan.votes11d[j].countryCode[0],
                      pMac->scan.votes11d[j].countryCode[1],
                      pMac->scan.votes11d[j].votes);
    }
    return fRet;
}

eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    v_REGDOMAIN_t domainId;

    if(pCountry)
    {
        status = csrGetRegulatoryDomainForCountry(pMac, pCountry, &domainId, COUNTRY_USER);
        if(HAL_STATUS_SUCCESS(status))
        {
            status = csrSetRegulatoryDomain(pMac, domainId, pfRestartNeeded);
            if(HAL_STATUS_SUCCESS(status))
            {
                //We don't need to check the pMac->roam.configParam.fEnforceDefaultDomain flag here,
                //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria.
                vos_mem_copy(pMac->scan.countryCodeCurrent, pCountry, WNI_CFG_COUNTRY_CODE_LEN);
                if((pfRestartNeeded == NULL) || !(*pfRestartNeeded))
                {
                    //Simply set it to cfg. If we need to restart, restart will apply it to the CFG
                    csrSetCfgCountryCode(pMac, pCountry);
                }
            }
        }
    }

    return (status);
}



//caller allocated memory for pNumChn and pChnPowerInfo
//As input, *pNumChn has the size of the array of pChnPowerInfo
//Upon return, *pNumChn has the number of channels assigned.
void csrGetChannelPowerInfo( tpAniSirGlobal pMac, tDblLinkList *pList,
                             tANI_U32 *pNumChn, tChannelListWithPower *pChnPowerInfo)
{
    tListElem *pEntry;
    tANI_U32 chnIdx = 0, idx;
    tCsrChannelPowerInfo *pChannelSet;

    //Get 2.4Ghz first
    pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
    while( pEntry && (chnIdx < *pNumChn) )
    {
        pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
        if ( 1 != pChannelSet->interChannelOffset )
        {
            for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ )
            {
                pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset ));
                pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower;
            }
        }
        else
        {
            for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ )
            {
                pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + idx);
                pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower;
            }
        }

        pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK );
    }
    *pNumChn = chnIdx;

    return ;
}



void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce )
{
    v_REGDOMAIN_t domainId;
    eHalStatus status = eHAL_STATUS_SUCCESS;

    do
    {
        if( !csrIs11dSupported( pMac ) || 0 == pMac->scan.channelOf11dInfo) break;
        if( pMac->scan.fAmbiguous11dInfoFound )
        {
            // ambiguous info found
            //Restore te default domain as well
            if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(
                                         pMac, pMac->scan.countryCodeCurrent,
                                         &domainId, COUNTRY_QUERY)))
            {
                pMac->scan.domainIdCurrent = domainId;
            }
            else
            {
                smsLog(pMac, LOGE, FL(" failed to get domain from currentCountryCode %02X%02X"),
                    pMac->scan.countryCodeCurrent[0], pMac->scan.countryCodeCurrent[1]);
            }
            csrResetCountryInformation( pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE );
            break;
        }
        if ( pMac->scan.f11dInfoApplied && !fForce ) break;
        if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(
                                        pMac, pMac->scan.countryCode11d,
                                        &domainId, COUNTRY_QUERY)))
        {
            //Check whether we need to enforce default domain
            if( ( !pMac->roam.configParam.fEnforceDefaultDomain ) ||
                (pMac->scan.domainIdCurrent == domainId) )
            {

#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
                {
                    vos_log_802_11d_pkt_type *p11dLog;
                    tChannelListWithPower chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN];
                    tANI_U32 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp;

                    WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C);
                    if(p11dLog)
                    {
                        p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET;
                        vos_mem_copy(p11dLog->countryCode, pMac->scan.countryCode11d, 3);
                        p11dLog->numChannel = pMac->scan.channels11d.numChannels;
                        if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL)
                        {
                            vos_mem_copy(p11dLog->Channels,
                                         pMac->scan.channels11d.channelList,
                                         p11dLog->numChannel);
                            csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList24,
                                                    &nChnInfo, chnPwrInfo);
                            nTmp = nChnInfo;
                            nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp;
                            csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList5G,
                                                    &nChnInfo, &chnPwrInfo[nTmp]);
                            for(nTmp = 0; nTmp < p11dLog->numChannel; nTmp++)
                            {
                                for(nChnInfo = 0; nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN; nChnInfo++)
                                {
                                    if(p11dLog->Channels[nTmp] == chnPwrInfo[nChnInfo].chanId)
                                    {
                                        p11dLog->TxPwr[nTmp] = chnPwrInfo[nChnInfo].pwr;
                                        break;
                                    }
                                }
                            }
                        }
                        if(!pMac->roam.configParam.Is11dSupportEnabled)
                        {
                            p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
                        }
                        else if(pMac->roam.configParam.fEnforceDefaultDomain)
                        {
                            p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN;
                        }
                        else
                        {
                            p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN;
                        }
                        WLAN_VOS_DIAG_LOG_REPORT(p11dLog);
                    }
                }
#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
                if(pMac->scan.domainIdCurrent != domainId)
                {
                   smsLog(pMac, LOGW, FL("Domain Changed Old %s (%d), new %s"),
                                      voss_DomainIdtoString(pMac->scan.domainIdCurrent),
                                      pMac->scan.domainIdCurrent,
                                      voss_DomainIdtoString(domainId));
                   status = WDA_SetRegDomain(pMac, domainId, eSIR_TRUE);
                }
                if (status != eHAL_STATUS_SUCCESS)
                {
                    smsLog( pMac, LOGE, FL("  fail to set regId %d"), domainId );
                }
                pMac->scan.domainIdCurrent = domainId;
#ifndef CONFIG_ENABLE_LINUX_REG
                csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels,
                                  pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE );
#endif
                // switch to active scans using this new channel list
                pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
                pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE;
                pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE;
            }
        }

    } while( 0 );

    return;
}



tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode,
                     tANI_BOOLEAN fForce)
{
    tANI_BOOLEAN fCountryStringChanged = FALSE, fUnknownCountryCode = FALSE;
    tANI_U32 i;
    v_REGDOMAIN_t regd;
    tANI_BOOLEAN fCountryNotPresentInDriver = FALSE;

    // convert to UPPER here so we are assured the strings are always in upper case.
    for( i = 0; i < 3; i++ )
    {
        pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] );
    }

    // Some of the 'old' Cisco 350 series AP's advertise NA as the country code (for North America ??).
    // NA is not a valid country code or domain so let's allow this by changing it to the proper
    // country code (which is US).  We've also seen some NETGEAR AP's that have "XX " as the country code
    // with valid 2.4 GHz US channel information.  If we cannot find the country code advertised in the
    // 11d information element, let's default to US.
    if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac,
                                                      pCountryCode,
                                                      &regd,
                                                      COUNTRY_QUERY) ) )
    {
        // Check the enforcement first
        if( pMac->roam.configParam.fEnforceDefaultDomain || pMac->roam.configParam.fEnforceCountryCodeMatch )
        {
            fUnknownCountryCode = TRUE;
        }
        else
        {
            fCountryNotPresentInDriver = TRUE;
        }
    }
    //right now, even if we don't find the CC in driver we set to world. Making
    //sure countryCode11d doesn't get updated with the invalid CC, instead
    //reflect the world CC
    else if (REGDOMAIN_WORLD == regd)
    {
        fCountryNotPresentInDriver = TRUE;
    }

    // We've seen some of the AP's improperly put a 0 for the third character of the country code.
    // spec says valid charcters are 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either).
    // if we see a 0 in this third character, let's change it to a ' '.
    if ( 0 == pCountryCode[ 2 ] )
    {
        pCountryCode[ 2 ] = ' ';
    }

    if( !fUnknownCountryCode )
    {
        fCountryStringChanged = (!vos_mem_compare(pMac->scan.countryCode11d, pCountryCode, 2));


        if(( 0 == pMac->scan.countryCode11d[ 0 ] && 0 == pMac->scan.countryCode11d[ 1 ] )
             || (fForce))
        {
            if (!fCountryNotPresentInDriver)
            {
                // this is the first .11d information
                vos_mem_copy(pMac->scan.countryCode11d, pCountryCode,
                         sizeof( pMac->scan.countryCode11d ));

            }
            else
            {
                pMac->scan.countryCode11d[0] = '0';
                pMac->scan.countryCode11d[1] = '0';
            }
        }
    }

    return( fCountryStringChanged );
}


void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand )
{
    tANI_U32 Index, count=0;
    tSirMacChanInfo *pChanInfo;
    tSirMacChanInfo *pChanInfoStart;
    tANI_S32 maxChannelIndex;

    maxChannelIndex = ( pMac->scan.base20MHzChannels.numChannels < WNI_CFG_VALID_CHANNEL_LIST_LEN ) ?
                      pMac->scan.base20MHzChannels.numChannels : WNI_CFG_VALID_CHANNEL_LIST_LEN ;

    pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN);
    if ( NULL != pChanInfo )
    {
        vos_mem_set(pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
        pChanInfoStart = pChanInfo;
        for (Index=0; Index < maxChannelIndex; Index++)
        {
            if ((fPopulate5GBand && (CSR_IS_CHANNEL_5GHZ(pMac->scan.defaultPowerTable[Index].chanId))) ||
                (!fPopulate5GBand && (CSR_IS_CHANNEL_24GHZ(pMac->scan.defaultPowerTable[Index].chanId))) )
            {
                if(count >= WNI_CFG_VALID_CHANNEL_LIST_LEN)
                {
                    smsLog( pMac, LOGW, FL(" csrSaveChannelPowerForBand, count exceeded, count =  %d"), count);
                    break;
                }
                pChanInfo->firstChanNum = pMac->scan.defaultPowerTable[Index].chanId;
                pChanInfo->numChannels  = 1;
                pChanInfo->maxTxPower   = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap );
                pChanInfo++;
                count++;
            }
        }
        if(count)
        {
            csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart );
        }
        vos_mem_free(pChanInfoStart);
    }
}


void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac )
{
    tANI_BOOLEAN fPopulate5GBand = FALSE;

    do 
    {
        // if this is not a dual band product, then we don't need to set the opposite
        // band info.  We only work in one band so no need to look in the other band.
        if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) break;
        // if we found channel info on the 5.0 band and...
        if ( CSR_IS_CHANNEL_5GHZ( pMac->scan.channelOf11dInfo ) )
        {
            // and the 2.4 band is empty, then populate the 2.4 channel info
            if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList24, LL_ACCESS_LOCK ) ) break;
            fPopulate5GBand = FALSE;
        }
        else
        {
            // else, we found channel info in the 2.4 GHz band.  If the 5.0 band is empty
            // set the 5.0 band info from the 2.4 country code.
            if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList5G, LL_ACCESS_LOCK ) ) break;
            fPopulate5GBand = TRUE;
        }
        csrSaveChannelPowerForBand( pMac, fPopulate5GBand );

    } while( 0 );
}


tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
    tANI_U32 i;

    //Make sure it is a channel that is in our supported list.
    for ( i = 0; i < pMac->scan.baseChannels.numChannels; i++ )
    {
        if ( channelId == pMac->scan.baseChannels.channelList[i] )
        {
            fRet = eANI_BOOLEAN_TRUE;
            break;
        }
    }

    //If it is configured to limit a set of the channels
    if( fRet && pMac->roam.configParam.fEnforce11dChannels )
    {
        fRet = eANI_BOOLEAN_FALSE;
        for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ )
        {
            if ( channelId == pMac->scan.base20MHzChannels.channelList[i] )
            {
                fRet = eANI_BOOLEAN_TRUE;
                break;
            }
        }
    }

    return (fRet);
}



//bSize specify the buffer size of pChannelList
tANI_U8 csrGetChannelListFromChannelSet( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 bSize, tCsrChannelPowerInfo *pChannelSet )
{
    tANI_U8 i, j = 0, chnId;

    bSize = CSR_MIN(bSize, pChannelSet->numChannels);
    for( i = 0; i < bSize; i++ )
    {
        chnId = (tANI_U8)(pChannelSet->firstChannel + ( i * pChannelSet->interChannelOffset ));
        if ( csrIsSupportedChannel( pMac, chnId ) )
        {
            pChannelList[j++] = chnId;
        }
    }

    return (j);
}



//bSize -- specify the buffer size of pChannelList
void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList, 
                                            tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels )
{
    tListElem *pEntry;
    tCsrChannelPowerInfo *pChannelSet;
    tANI_U8 numChannels;
    tANI_U8 *pChannels;

    if( pChannelSetList && pChannelList && pNumChannels )
    {
        pChannels = pChannelList;
        *pNumChannels = 0;
        pEntry = csrLLPeekHead( pChannelSetList, LL_ACCESS_LOCK );
        while( pEntry )
        {
            pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
            numChannels = csrGetChannelListFromChannelSet( pMac, pChannels, bSize, pChannelSet );
            pChannels += numChannels;
            *pNumChannels += numChannels;
            pEntry = csrLLNext( pChannelSetList, pEntry, LL_ACCESS_LOCK );
        }
    }
}


/*
  * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d
*/
tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
                                         tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce)
{
    eHalStatus status;
    tANI_U8 *pCountryCodeSelected;
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
    v_REGDOMAIN_t domainId;
    tDot11fBeaconIEs *pIesLocal = pIes;
    tANI_BOOLEAN useVoting = eANI_BOOLEAN_FALSE;

    if (VOS_STA_SAP_MODE == vos_get_conparam ())
        return eHAL_STATUS_SUCCESS;

    if ((NULL == pSirBssDesc) && (NULL == pIes))
        useVoting = eANI_BOOLEAN_TRUE;

    do
    {
        // check if .11d support is enabled
        if( !csrIs11dSupported( pMac ) ) break;

        if (eANI_BOOLEAN_FALSE == useVoting)
        {
            if( !pIesLocal &&
                (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
                                     pSirBssDesc, &pIesLocal))))
            {
                break;
            }
            // check if country information element is present
            if(!pIesLocal->Country.present)
            {
                //No country info
                break;
            }

            if( HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry
                (pMac, pIesLocal->Country.country, &domainId,
                COUNTRY_QUERY)) &&
                ( domainId == REGDOMAIN_WORLD))
            {
                break;
            }
        } //useVoting == eANI_BOOLEAN_FALSE

        if (eANI_BOOLEAN_FALSE == useVoting)
            pCountryCodeSelected = pIesLocal->Country.country;
        else
            pCountryCodeSelected = pMac->scan.countryCodeElected;

        status = csrGetRegulatoryDomainForCountry(pMac,
                       pCountryCodeSelected, &domainId, COUNTRY_IE);
        if ( status != eHAL_STATUS_SUCCESS )
        {
            smsLog( pMac, LOGE, FL("  fail to get regId %d"), domainId );
            fRet = eANI_BOOLEAN_FALSE;
            break;
        }

        /* updating 11d Country Code with Country code selected. */

        vos_mem_copy(pMac->scan.countryCode11d,
                             pCountryCodeSelected,
                             WNI_CFG_COUNTRY_CODE_LEN);

#ifndef CONFIG_ENABLE_LINUX_REG
        // Checking for Domain Id change
        if ( domainId != pMac->scan.domainIdCurrent )
        {
            vos_mem_copy(pMac->scan.countryCode11d,
                                  pCountryCodeSelected,
                                  sizeof( pMac->scan.countryCode11d ) );
            /* Set Current Country code and Current Regulatory domain */
            status = csrSetRegulatoryDomain(pMac, domainId, NULL);
            if (eHAL_STATUS_SUCCESS != status)
            {
                smsLog(pMac, LOGE, "Set Reg Domain Fail %d", status);
                fRet = eANI_BOOLEAN_FALSE;
                return fRet;
            }
            //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria.
            vos_mem_copy(pMac->scan.countryCodeCurrent,
                            pCountryCodeSelected, WNI_CFG_COUNTRY_CODE_LEN);
            //Simply set it to cfg.
            csrSetCfgCountryCode(pMac, pCountryCodeSelected);

            /* overwrite the defualt country code */
            vos_mem_copy(pMac->scan.countryCodeDefault,
                                      pMac->scan.countryCodeCurrent,
                                      WNI_CFG_COUNTRY_CODE_LEN);
            /* Set Current RegDomain */
            status = WDA_SetRegDomain(pMac, domainId, eSIR_TRUE);
            if ( status != eHAL_STATUS_SUCCESS )
            {
                smsLog( pMac, LOGE, FL("  fail to Set regId %d"), domainId );
                fRet = eANI_BOOLEAN_FALSE;
                return fRet;
            }
             /* set to default domain ID */
            pMac->scan.domainIdCurrent = domainId;
            /* get the channels based on new cc */
            status = csrInitGetChannels( pMac );

            if ( status != eHAL_STATUS_SUCCESS )
            {
                smsLog( pMac, LOGE, FL("  fail to get Channels "));
                fRet = eANI_BOOLEAN_FALSE;
                return fRet;
            }

            /* reset info based on new cc, and we are done */
            csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
           /* Regulatory Domain Changed, Purge Only scan result
            * which does not have channel number belong to 11d
            * channel list
            */
            csrScanFilterResults(pMac);
        }
#endif
        fRet = eANI_BOOLEAN_TRUE;

    } while( 0 );

    if( !pIes && pIesLocal )
    {
        //locally allocated
        vos_mem_free(pIesLocal);
    }

    return( fRet );
}


static void csrSaveScanResults( tpAniSirGlobal pMac, tANI_U8 reason )
{
    // initialize this to FALSE. profMoveInterimScanResultsToMainList() routine
    // will set this to the channel where an .11d beacon is seen
    pMac->scan.channelOf11dInfo = 0;
    // if we get any ambiguous .11d information then this will be set to TRUE
    pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
    //Tush
    // if we get any ambiguous .11d information, then this will be set to TRUE
    // only if the applied 11d info could be found in one of the scan results
    pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_FALSE;
    // move the scan results from interim list to the main scan list
    csrMoveTempScanResultsToMainList( pMac, reason );
}


void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    switch (pCommand->u.scanCmd.reason)
    {
    case eCsrScanSetBGScanParam:
    case eCsrScanAbortBgScan:
        if(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList)
        {
            vos_mem_free(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList);
            pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL;
        }
        break;
    case eCsrScanBGScanAbort:
    case eCsrScanBGScanEnable:
    case eCsrScanGetScanChnInfo:
        break;
    case eCsrScanAbortNormalScan:
    default:
        csrScanFreeRequest(pMac, &pCommand->u.scanCmd.u.scanRequest);
        break;
    }
    if(pCommand->u.scanCmd.pToRoamProfile)
    {
        csrReleaseProfile(pMac, pCommand->u.scanCmd.pToRoamProfile);
        vos_mem_free(pCommand->u.scanCmd.pToRoamProfile);
    }
    vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
}


tANI_BOOLEAN csrGetRemainingChannelsFor11dScan( tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U8 *pcChannels )
{
    tANI_U32 index11dChannels, index;
    tANI_U32 indexCurrentChannels;
    tANI_BOOLEAN fChannelAlreadyScanned;
    tANI_U32 len = sizeof(pMac->roam.validChannelList);

    *pcChannels = 0;
    if ( CSR_IS_11D_INFO_FOUND(pMac) && csrRoamIsChannelValid(pMac, pMac->scan.channelOf11dInfo) )
    {
        if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
        {
            //Find the channel index where we found the 11d info
            for(index = 0; index < len; index++)
            {
                if(pMac->scan.channelOf11dInfo == pMac->roam.validChannelList[index])
                    break;
            }
            //check whether we found the channel index
            if(index < len)
            {
                // Now, look through the 11d channel list and create a list of all channels in the 11d list that are
                // NOT in the current channel list.  This gives us a list of the new channels that have not been
                // scanned.  We'll scan this new list so we have a complete set of scan results on all of the domain channels
                // initially.
                for ( index11dChannels = 0; index11dChannels < pMac->scan.channels11d.numChannels; index11dChannels++ )
                {
                    fChannelAlreadyScanned = eANI_BOOLEAN_FALSE;

                    for( indexCurrentChannels = 0; indexCurrentChannels < index; indexCurrentChannels++ )
                    {
                        if ( pMac->roam.validChannelList[ indexCurrentChannels ] == pMac->scan.channels11d.channelList[ index11dChannels ] )
                        {
                            fChannelAlreadyScanned = eANI_BOOLEAN_TRUE;
                            break;
                        }
                    }

                    if ( !fChannelAlreadyScanned )
                    {
                        pChannels[ *pcChannels ] = pMac->scan.channels11d.channelList[ index11dChannels ];
                        ( *pcChannels )++;
                    }
                }
            }
        }//GetCFG
    }
    return( *pcChannels );
}


eCsrScanCompleteNextCommand csrScanGetNextCommandState( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fSuccess )
{
    eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
    
    switch( pCommand->u.scanCmd.reason )
    {
        case eCsrScan11d1:
            NextCommand = (fSuccess) ? eCsrNext11dScan1Success : eCsrNext11dScan1Failure;
            break;
        case eCsrScan11d2:
            NextCommand = (fSuccess) ? eCsrNext11dScan2Success : eCsrNext11dScan2Failure;
            break;    
        case eCsrScan11dDone:
            NextCommand = eCsrNext11dScanComplete;
            break;
        case eCsrScanLostLink1:
            NextCommand = (fSuccess) ? eCsrNextLostLinkScan1Success : eCsrNextLostLinkScan1Failed;
            break;
        case eCsrScanLostLink2:
            NextCommand = (fSuccess) ? eCsrNextLostLinkScan2Success : eCsrNextLostLinkScan2Failed;
            break;
        case eCsrScanLostLink3:
            NextCommand = (fSuccess) ? eCsrNextLostLinkScan3Success : eCsrNextLostLinkScan3Failed;
            break;
        case eCsrScanForSsid:
            NextCommand = (fSuccess) ? eCsrNexteScanForSsidSuccess : eCsrNexteScanForSsidFailure;
            break;
        case eCsrScanForCapsChange:
            NextCommand = eCsrNextCapChangeScanComplete;    //don't care success or not
            break;
        case eCsrScanIdleScan:
            NextCommand = eCsrNextIdleScanComplete;
            break;
        default:
            NextCommand = eCsrNextScanNothing;
            break;
    }
    return( NextCommand );
}


//Return whether the pCommand is finished.
tANI_BOOLEAN csrHandleScan11d1Failure(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
    
    //Apply back the default setting and passively scan one more time.
    csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE);
    pCommand->u.scanCmd.reason = eCsrScan11d2;
    if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand)))
    {
        fRet = eANI_BOOLEAN_FALSE;
    }
    
    return (fRet);
}


tANI_BOOLEAN csrHandleScan11dSuccess(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
    tANI_U8 *pChannels;
    tANI_U8 cChannels;
    
    pChannels = vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN);
    if ( NULL != pChannels )
    {
        vos_mem_set(pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
        if ( csrGetRemainingChannelsFor11dScan( pMac, pChannels, &cChannels ) )
        {
            pCommand->u.scanCmd.reason = eCsrScan11dDone;
            if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
            {
                vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
            }
            pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(cChannels);
            if ( NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList )
            {
                vos_mem_copy(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
                             pChannels, cChannels);
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = cChannels;
                pCommand->u.scanCmd.u.scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
                pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
                if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand)))
                {
                    //Reuse the same command buffer
                    fRet = eANI_BOOLEAN_FALSE;
                }
            }
        }
        vos_mem_free(pChannels);
    }
    
    return (fRet);
}

//Return whether the command should be removed
tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp )
{
    eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
    tListElem *pEntry;
    tSmeCmd *pCommand;
    tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
    tANI_BOOLEAN fSuccess;

    if (pMac->fScanOffload)
        pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK);
    else
        pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);

    if ( pEntry )
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );

        // If the head of the queue is Active and it is a SCAN command, remove
        // and put this on the Free queue.
        if ( eSmeCommandScan == pCommand->command )
        {     
            tANI_U32 sessionId = pCommand->sessionId;

            if(eSIR_SME_SUCCESS != pScanRsp->statusCode)
            {
                fSuccess = eANI_BOOLEAN_FALSE;
            }
            else
            {
                //pMac->scan.tempScanResults is not empty meaning the scan found something
                //This check only valid here because csrSaveScanresults is not yet called
                fSuccess = (!csrLLIsListEmpty(&pMac->scan.tempScanResults, LL_ACCESS_LOCK));
            }
            if (pCommand->u.scanCmd.abortScanIndication &
                                   eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE)
            {
                /*
                 * Scan aborted due to band change
                 * The scan results need to be flushed
                 */
                if (pCommand->u.scanCmd.callback
                    != pMac->scan.callback11dScanDone)
                {
                    smsLog(pMac, LOG1, FL("Filtering the scan results as the "
                                          "results may belong to wrong band"));
                    csrScanFilterResults(pMac);
                }
                else
                {
                    smsLog(pMac, LOG1, FL("11d_scan_done will flush the scan"
                                          " results"));
                }
            }
            csrSaveScanResults(pMac, pCommand->u.scanCmd.reason);

            /* filter scan result based on valid channel list number */
            if (pMac->scan.fcc_constraint)
            {
                smsLog(pMac, LOG1, FL("Clear BSS from invalid channels"));
                csrScanFilterResults(pMac);
            }
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
            {
                vos_log_scan_pkt_type *pScanLog = NULL;
                tScanResultHandle hScanResult;
                tCsrScanResultInfo *pScanResult;
                tDot11fBeaconIEs *pIes;
                int n = 0, c = 0;

                WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
                if(pScanLog)
                {
                    if(eCsrScanBgScan == pCommand->u.scanCmd.reason || 
                        eCsrScanProbeBss == pCommand->u.scanCmd.reason ||
                        eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason)
                    {
                        pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_RSP;
                    }
                    else
                    {
                        if( eSIR_PASSIVE_SCAN != pMac->scan.curScanType )
                        {
                            pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP;
                        }
                        else
                        {
                            pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP;
                        }
                    }
                    if(eSIR_SME_SUCCESS == pScanRsp->statusCode)
                    {
                        if(HAL_STATUS_SUCCESS(csrScanGetResult(pMac, NULL, &hScanResult)))
                        {
                            while(((pScanResult = csrScanResultGetNext(pMac, hScanResult)) != NULL))
                            {
                                if( n < VOS_LOG_MAX_NUM_BSSID )
                                {
                                    if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->BssDescriptor, &pIes)))
                                    {
                                        smsLog(pMac, LOGE, FL(" fail to parse IEs"));
                                        break;
                                    }
                                    vos_mem_copy(pScanLog->bssid[n],
                                                 pScanResult->BssDescriptor.bssId, 6);
                                    if(pIes && pIes->SSID.present && VOS_LOG_MAX_SSID_SIZE >= pIes->SSID.num_ssid)
                                    {
                                        vos_mem_copy(pScanLog->ssid[n],
                                                     pIes->SSID.ssid, pIes->SSID.num_ssid);
                                    }
                                    vos_mem_free(pIes);
                                    n++;
                                }
                                c++;
                            }
                            pScanLog->numSsid = (v_U8_t)n;
                            pScanLog->totalSsid = (v_U8_t)c;
                            csrScanResultPurge(pMac, hScanResult);
                        }
                    }
                    else
                    {
                        pScanLog->status = WLAN_SCAN_STATUS_FAILURE;
                    }
                    WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
                }
            }
#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR

            NextCommand = csrScanGetNextCommandState(pMac, pCommand, fSuccess);
            //We reuse the command here instead reissue a new command
            switch(NextCommand)
            {
            case eCsrNext11dScan1Success:
            case eCsrNext11dScan2Success:
                smsLog( pMac, LOG2, FL("11dScan1/3 produced results.  Reissue Active scan..."));
                // if we found country information, no need to continue scanning further, bail out
                fRemoveCommand = eANI_BOOLEAN_TRUE;
                NextCommand = eCsrNext11dScanComplete;
                break;
            case eCsrNext11dScan1Failure:
                //We are not done yet. 11d scan fail once. We will try to reset anything and do it over again
                //The only meaningful thing for this retry is that we cannot find 11d information after a reset so
                //we clear the "old" 11d info and give it once more chance
                fRemoveCommand = csrHandleScan11d1Failure(pMac, pCommand);
                if(fRemoveCommand)
                {
                    NextCommand = eCsrNext11dScanComplete;
                } 
                break;
            case eCsrNextLostLinkScan1Success:
                if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink1)))
                {
                    csrScanHandleFailedLostlink1(pMac, sessionId);
                }
                break;
            case eCsrNextLostLinkScan2Success:
                if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink2)))
                {
                    csrScanHandleFailedLostlink2(pMac, sessionId);
                }
                break;
            case eCsrNextLostLinkScan3Success:
                if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink3)))
                {
                    csrScanHandleFailedLostlink3(pMac, sessionId);
                }
                break;
            case eCsrNextLostLinkScan1Failed:
                csrScanHandleFailedLostlink1(pMac, sessionId);
                break;
            case eCsrNextLostLinkScan2Failed:
                csrScanHandleFailedLostlink2(pMac, sessionId);
                break;
            case eCsrNextLostLinkScan3Failed:
                csrScanHandleFailedLostlink3(pMac, sessionId);
                break;    
            case eCsrNexteScanForSsidSuccess:
                csrScanHandleSearchForSSID(pMac, pCommand);
                break;
            case eCsrNexteScanForSsidFailure:
                csrScanHandleSearchForSSIDFailure(pMac, pCommand);
                break;
            case eCsrNextIdleScanComplete:
                pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
                break;
            case eCsrNextCapChangeScanComplete:
                csrScanHandleCapChangeScanComplete(pMac, sessionId);
                break;
            default:

                break;
            }
        }
        else
        {
            smsLog( pMac, LOGW, FL("Scan Completion called but SCAN command is not ACTIVE ..."));
            fRemoveCommand = eANI_BOOLEAN_FALSE;
        }
    }
    else
    {
        smsLog( pMac, LOGW, FL("Scan Completion called but NO commands are ACTIVE ..."));
        fRemoveCommand = eANI_BOOLEAN_FALSE;
    }
   
    return( fRemoveCommand );
}


static void csrScanRemoveDupBssDescriptionFromInterimList( tpAniSirGlobal pMac, 
                                                           tSirBssDescription *pSirBssDescr,
                                                           tDot11fBeaconIEs *pIes)
{
    tListElem *pEntry;
    tCsrScanResult *pCsrBssDescription;
    tDot11fBeaconIEs *temp_ie = pIes;

    if (!temp_ie)
        csrGetParsedBssDescriptionIEs(pMac, pSirBssDescr, &temp_ie);

    // Walk through all the chained BssDescriptions.  If we find a chained BssDescription that
    // matches the BssID of the BssDescription passed in, then these must be duplicate scan
    // results for this Bss.  In that case, remove the 'old' Bss description from the linked list.
    pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK );
    while( pEntry ) 
    {
        pCsrBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );

        // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType
        // matches

        if (csrIsDuplicateBssDescription(pMac,
                                     &pCsrBssDescription->Result.BssDescriptor,
                                     pSirBssDescr, temp_ie, FALSE))
        {
            /*
             * Due to Rx sensitivity issue, sometime beacons are seen on
             * adjacent channel so workaround in software is needed. If DS
             * params or HT info are present driver can get proper channel
             * info from these IEs and the older RSSI values are used in new
             * entry.
             *
             * For the cases where DS params and HT info is not present,
             * driver needs to check below conditions to update proper
             * channel so that the older RSSI and channel values are used in
             * new entry:
             *  -- The old entry channel and new entry channel are not same
             *  -- RSSI is below 15db or more from old value, this indicate
             *     that the signal has leaked in adjacent channel
             */
            if (!pSirBssDescr->fProbeRsp &&
                (temp_ie && !temp_ie->DSParams.present &&
                !temp_ie->HTInfo.present) &&
                (pSirBssDescr->channelId !=
                 pCsrBssDescription->Result.BssDescriptor.channelId) &&
                ((pCsrBssDescription->Result.BssDescriptor.rssi -
                  pSirBssDescr->rssi) >
                 SIR_ADJACENT_CHANNEL_RSSI_DIFF_THRESHOLD)) {
                 pSirBssDescr->channelId =
                            pCsrBssDescription->Result.BssDescriptor.channelId;
                pSirBssDescr->rssi =
                                 pCsrBssDescription->Result.BssDescriptor.rssi;
            }

            pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) +
                                    ((tANI_S32)pCsrBssDescription->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 );

            // Remove the 'old' entry from the list....
            if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ) )
            {
                csrCheckNSaveWscIe(pMac, pSirBssDescr, &pCsrBssDescription->Result.BssDescriptor);
                // we need to free the memory associated with this node
                csrFreeScanResultEntry( pMac, pCsrBssDescription );
            }
            
            // If we found a match, we can stop looking through the list.
            break;
        }

        pEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK );
    }

    if (!pIes && temp_ie)
       vos_mem_free(temp_ie);
}



//Caller allocated memory pfNewBssForConn to return whether new candidate for
//current connection is found. Cannot be NULL
tCsrScanResult *csrScanSaveBssDescriptionToInterimList( tpAniSirGlobal pMac, 
                                                        tSirBssDescription *pBSSDescription,
                                                        tDot11fBeaconIEs *pIes)
{
    tCsrScanResult *pCsrBssDescription = NULL;
    tANI_U32 cbBSSDesc;
    tANI_U32 cbAllocated;
    
    // figure out how big the BSS description is (the BSSDesc->length does NOT
    // include the size of the length field itself).
    cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length );

    cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc;

    pCsrBssDescription = vos_mem_malloc(cbAllocated);
    if ( NULL != pCsrBssDescription )
    {
        vos_mem_set(pCsrBssDescription, cbAllocated, 0);
        pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
        vos_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc );
        //Save SSID separately for later use
        if( pIes->SSID.present && !csrIsNULLSSID(pIes->SSID.ssid, pIes->SSID.num_ssid) )
        {
            //SSID not hidden
            tANI_U32 len = pIes->SSID.num_ssid;
            if (len > SIR_MAC_MAX_SSID_LENGTH)
            {
               // truncate to fit in our struct
               len = SIR_MAC_MAX_SSID_LENGTH;
            }
            pCsrBssDescription->Result.ssId.length = len;
            pCsrBssDescription->Result.timer = vos_timer_get_system_time();
            vos_mem_copy(pCsrBssDescription->Result.ssId.ssId, pIes->SSID.ssid, len);
        }
        csrLLInsertTail( &pMac->scan.tempScanResults, &pCsrBssDescription->Link, LL_ACCESS_LOCK );
    }

    return( pCsrBssDescription );
}


    

tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1, 
                                           tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2, tANI_BOOLEAN fForced )
{
    tANI_BOOLEAN fMatch = FALSE;
    tSirMacCapabilityInfo *pCap1, *pCap2;
    tDot11fBeaconIEs *pIes1 = NULL;
    tDot11fBeaconIEs *pIesTemp = pIes2;

    pCap1 = (tSirMacCapabilityInfo *)&pSirBssDesc1->capabilityInfo;
    pCap2 = (tSirMacCapabilityInfo *)&pSirBssDesc2->capabilityInfo;
    if(pCap1->ess == pCap2->ess)
    {
        if (pCap1->ess && 
                csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)&&
            (fForced || (vos_chan_to_band(pSirBssDesc1->channelId) == vos_chan_to_band((pSirBssDesc2->channelId)))))
        {
            fMatch = TRUE;
            // Check for SSID match, if exists
            do
            {
                if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
                {
                    break;
                }
                if( NULL == pIesTemp )
                {
                    if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp)))
                    {
                        break;
                    }
                }
                if(pIes1->SSID.present && pIesTemp->SSID.present)
                {
                    fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid, 
                                            pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE);
                } 
            }while(0);

        }
        else if (pCap1->ibss && (pSirBssDesc1->channelId == pSirBssDesc2->channelId))
        {

            do
            {
                if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
                {
                    break;
                }
                if( NULL == pIesTemp )
                {
                    if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp)))
                    {
                        break;
                    }
                }
                //Same channel cannot have same SSID for different IBSS
                if(pIes1->SSID.present && pIesTemp->SSID.present)
                {
                    fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid, 
                                            pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE);
                }
            }while(0);
        }
        /* In case of P2P devices, ess and ibss will be set to zero */
        else if (!pCap1->ess && 
                csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId))
        {
            fMatch = TRUE;
        }
    }

    if(pIes1)
    {
        vos_mem_free(pIes1);
    }
    
    if( (NULL == pIes2) && pIesTemp )
    {
        //locally allocated
        vos_mem_free(pIesTemp);
    }

    return( fMatch );
}


tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 )
{
    return( pSirBssDesc1->nwType == pSirBssDesc2->nwType );
}


//to check whether the BSS matches the dot11Mode
static tANI_BOOLEAN csrScanIsBssAllowed(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, 
                                        tDot11fBeaconIEs *pIes)
{
    tANI_BOOLEAN fAllowed = eANI_BOOLEAN_FALSE;
    eCsrPhyMode phyMode;

    if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pBssDesc, &phyMode, pIes)))
    {
        switch(pMac->roam.configParam.phyMode)
        {
        case eCSR_DOT11_MODE_11b:
            fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode);
            break;
        case eCSR_DOT11_MODE_11g:
            fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode);
            break;
        case eCSR_DOT11_MODE_11g_ONLY:
            fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11g == phyMode);
            break;
        case eCSR_DOT11_MODE_11a:
            fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11b != phyMode) && (eCSR_DOT11_MODE_11g != phyMode));
            break;
        case eCSR_DOT11_MODE_11n_ONLY:
            fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11n == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode));
            break;

#ifdef WLAN_FEATURE_11AC
         case eCSR_DOT11_MODE_11ac_ONLY:
             fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11ac == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode));
             break;
#endif
        case eCSR_DOT11_MODE_11b_ONLY:
            fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11b == phyMode);
            break;
        case eCSR_DOT11_MODE_11a_ONLY:
            fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a == phyMode);
            break;
        case eCSR_DOT11_MODE_11n:
#ifdef WLAN_FEATURE_11AC
        case eCSR_DOT11_MODE_11ac:
#endif
        case eCSR_DOT11_MODE_TAURUS:
        default:
            fAllowed = eANI_BOOLEAN_TRUE;
            break;
        }
    }

    return (fAllowed);
}



//Return pIes to caller for future use when returning TRUE.
static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels, 
                                               tANI_U8 numChn, tSirBssDescription *pBssDesc, 
                                               tDot11fBeaconIEs **ppIes )
{
    tANI_BOOLEAN fValidChannel = FALSE;
    tDot11fBeaconIEs *pIes = NULL;
    tANI_U8 index;

    for( index = 0; index < numChn; index++ )
    {
        // This check relies on the fact that a single BSS description is returned in each
        // ScanRsp call, which is the way LIM implemented the scan req/rsp funtions.  We changed 
        // to this model when we ran with a large number of APs.  If this were to change, then 
        // this check would have to mess with removing the bssDescription from somewhere in an 
        // arbitrary index in the bssDescription array.
        if ( pChannels[ index ] == pBssDesc->channelId ) 
        {
           fValidChannel = TRUE;
           break;
        }
    }
    *ppIes = NULL;
    if(fValidChannel)
    {
        if( HAL_STATUS_SUCCESS( csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes) ) )
        {
            fValidChannel = csrScanIsBssAllowed(pMac, pBssDesc, pIes);
            if( fValidChannel )
            {
                *ppIes = pIes;
            }
            else
            {
                vos_mem_free(pIes);
            }
        }
        else
        {
            fValidChannel = FALSE;
        }
    }

    return( fValidChannel );   
}


//Return whether last scan result is received
static tANI_BOOLEAN csrScanProcessScanResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, 
                                                tSirSmeScanRsp *pScanRsp, tANI_BOOLEAN *pfRemoveCommand )
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE, fRemoveCommand = eANI_BOOLEAN_FALSE;
    tDot11fBeaconIEs *pIes = NULL;
    tANI_U32 cbParsed;
    tSirBssDescription *pSirBssDescription;
    tANI_U32 cbBssDesc;
    eHalStatus status;
    tANI_U32 cbScanResult = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ) 
                            + sizeof(tSirBssDescription);    //We need at least one CB

    // don't consider the scan rsp to be valid if the status code is Scan Failure.  Scan Failure
    // is returned when the scan could not find anything.  so if we get scan failure return that
    // the scan response is invalid.  Also check the lenght in the scan result for valid scan
    // BssDescriptions....
    do
    {
        if ( ( cbScanResult <= pScanRsp->length ) && 
             (( eSIR_SME_SUCCESS == pScanRsp->statusCode ) ||
              ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW == pScanRsp->statusCode ) ) )
        {
            tANI_U8 *pChannelList = NULL;
            tANI_U8 cChannels = 0;

            //Different scan type can reach this point, we need to distinguish it
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
            if( eCsrScanGetLfrResult == pCommand->u.scanCmd.reason )
            {
                pChannelList = NULL;
                cChannels = 0;
            }
            else
#endif
            if( eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason )
            {
                //eCsrScanSetBGScanParam uses different structure
                tCsrBGScanRequest *pBgScanReq = &pCommand->u.scanCmd.u.bgScanRequest;

                cChannels = pBgScanReq->ChannelInfo.numOfChannels;
                pChannelList = pBgScanReq->ChannelInfo.ChannelList;
            }
            else
            {
                //the rest use generic scan request
                cChannels = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
                pChannelList = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
            }

            // if the scan result is not on one of the channels in the Valid channel list, then it
            // must have come from an AP on an overlapping channel (in the 2.4GHz band).  In this case,
            // let's drop the scan result.
            //
            // The other situation is where the scan request is for a scan on a particular channel set
            // and the scan result is from a 
            
            // if the NumChannels is 0, then we are supposed to be scanning all channels.  Use the full channel
            // list as the 'valid' channel list.  Otherwise, use the specific channel list in the scan parms
            // as the valid channels.
            if ( 0 == cChannels ) 
            {
                tANI_U32 len = sizeof(pMac->roam.validChannelList);
                
                if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
                {
                    pChannelList = pMac->roam.validChannelList;
                    cChannels = (tANI_U8)len; 
                }
                else
                {
                    //Cannot continue
                    smsLog( pMac, LOGE, "CSR: Processing internal SCAN results...csrGetCfgValidChannels failed" );
                    break;
                }
            }

            smsLog( pMac, LOG2, "CSR: Processing internal SCAN results..." );
            cbParsed = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription );
            pSirBssDescription = pScanRsp->bssDescription;
            while( cbParsed < pScanRsp->length )
            {
                if ( csrScanValidateScanResult( pMac, pChannelList, cChannels, pSirBssDescription, &pIes ) ) 
                {
                    csrScanRemoveDupBssDescriptionFromInterimList(pMac, pSirBssDescription, pIes);
                    csrScanSaveBssDescriptionToInterimList( pMac, pSirBssDescription, pIes );
                    if( eSIR_PASSIVE_SCAN == pMac->scan.curScanType )
                    {
                        if( csrIs11dSupported( pMac) )
                        {
                            //Check whether the BSS is acceptable base on 11d info and our configs.
                            if( csrMatchCountryCode( pMac, NULL, pIes ) )
                            {
                                //Double check whether the channel is acceptable by us.
                                if( csrIsSupportedChannel( pMac, pSirBssDescription->channelId ) )
                                {
                                    pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
                                }
                            }
                        }
                        else
                        {
                            pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
                        }
                    }
                    //Free the resource
                    vos_mem_free(pIes);
                }
                // skip over the BSS description to the next one...
                cbBssDesc = pSirBssDescription->length + sizeof( pSirBssDescription->length );

                cbParsed += cbBssDesc;
                pSirBssDescription = (tSirBssDescription *)((tANI_U8 *)pSirBssDescription + cbBssDesc );

            } //while
        }
        else
        {
            smsLog( pMac, LOGW, " Scanrsp fail (0x%08X), length = %d (expected %d)",
                    pScanRsp->statusCode, pScanRsp->length, cbScanResult);
            //HO bg scan/probe failed no need to try autonomously
            if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
               eCsrScanProbeBss == pCommand->u.scanCmd.reason ||
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
               eCsrScanGetLfrResult == pCommand->u.scanCmd.reason ||
#endif
               eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason)
            {
                fRemoveCommand = eANI_BOOLEAN_TRUE;
            }
        }
    }while(0);
    if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode )
    {
        smsLog(pMac, LOG1, " Scan received %d unique BSS scan reason is %d", csrLLCount(&pMac->scan.tempScanResults), pCommand->u.scanCmd.reason);
        fRemoveCommand = csrScanComplete( pMac, pScanRsp );
        fRet = eANI_BOOLEAN_TRUE;
    }//if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode )
    if(pfRemoveCommand)
    {
        *pfRemoveCommand = fRemoveCommand;
    }

    /*
     * Currently SET_FCC_CHANNEL issues updated channel list to fw.
     * At the time of driver load, if scan is issued followed with
     * SET_FCC_CHANNEL, driver will send update channel list to fw.
     * Fw will stop ongoing scan because of that GUI will have very less
     * scan list.
     * Update channel list should be sent to fw once scan is done
     */
    if (pMac->scan.defer_update_channel_list) {
        status = csrUpdateChannelList(pMac);
        if (eHAL_STATUS_SUCCESS != status)
            smsLog(pMac, LOGE,
                   FL( "failed to update the supported channel list"));
            pMac->scan.defer_update_channel_list = false;
    }

#ifdef WLAN_AP_STA_CONCURRENCY
    if (pMac->fScanOffload)
        return fRet;

    if (!csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK ))
    {
        /* Pending scan commands in the list because the previous scan command
         * was split into a scan command on one channel + a scan command for all
         * remaining channels.
         *
         * Start timer to trigger processing of the next scan command.
         * NOTE for LFR:
         * Do not split scans if no concurrent infra connections are
         * active and if the scan is a BG scan triggered by LFR (OR)
         * any scan if LFR is in the middle of a BG scan. Splitting
         * the scan is delaying the time it takes for LFR to find
         * candidates and resulting in disconnects.
         */
        if ( (csrIsStaSessionConnected(pMac) &&
#ifdef FEATURE_WLAN_LFR
                    (csrIsConcurrentInfraConnected(pMac) ||
                     ((pCommand->u.scanCmd.reason != eCsrScanBgScan) &&
                      (pMac->roam.neighborRoamInfo.neighborRoamState !=
                       eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) &&
#endif
                    (pCommand->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
                (csrIsP2pSessionConnected(pMac)) )
        {
            /* if active connected sessions present then continue to split scan
             * with specified interval between consecutive scans */
            csrSetDefaultScanTiming(pMac, pCommand->u.scanCmd.u.scanRequest.scanType, &(pCommand->u.scanCmd.u.scanRequest));
            vos_timer_start(&pMac->scan.hTimerStaApConcTimer,
                pCommand->u.scanCmd.u.scanRequest.restTime);
        } else {
            /* if no connected sessions present then initiate next scan command immediately */
            /* minimum timer granularity is 10ms */
            vos_timer_start(&pMac->scan.hTimerStaApConcTimer, 10);
        }
    }
#endif
    return (fRet);
}


tANI_BOOLEAN csrScanIsWildCardScan( tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
    tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0};
    tANI_BOOLEAN f = vos_mem_compare(pCommand->u.scanCmd.u.scanRequest.bssid,
                                     bssid, sizeof(tCsrBssid));

    //It is not a wild card scan if the bssid is not broadcast and the number of SSID is 1.
    return ((tANI_BOOLEAN)( (f || (0xff == pCommand->u.scanCmd.u.scanRequest.bssid[0])) &&
        (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs != 1) ));
}


eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry;
    tSmeCmd *pCommand;
    eCsrScanStatus scanStatus;
    tSirSmeScanRsp *pScanRsp;
    tSmeGetScanChnRsp *pScanChnInfo;
    tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
    eCsrScanReason reason = eCsrScanOther;

    if (pMac->fScanOffload)
        pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList,
                               LL_ACCESS_LOCK);
    else
        pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);

    if ( pEntry )
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        if ( eSmeCommandScan == pCommand->command )
        {
            /* Purge the scan results based on Aging */
            if (pEntry && pMac->scan.scanResultCfgAgingTime)
                csrPurgeScanResultByAge(pMac);
            reason = pCommand->u.scanCmd.reason;
            switch(pCommand->u.scanCmd.reason)
            {
            case eCsrScanAbortBgScan:
            case eCsrScanAbortNormalScan:
            case eCsrScanBGScanAbort:
            case eCsrScanBGScanEnable:
                pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
                scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ?
                              eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
                break;
            case eCsrScanGetScanChnInfo:
                pScanChnInfo = (tSmeGetScanChnRsp *)pMsgBuf;
                /*
                 * status code not available in tSmeGetScanChnRsp, so 
                 * by default considereing it to be success
                 */
                scanStatus = eSIR_SME_SUCCESS;
                csrScanAgeResults(pMac, pScanChnInfo);
                break;
            case eCsrScanForCapsChange:
                pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
                scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ?
                              eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
                csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand );
                break;
            case eCsrScanP2PFindPeer:
                pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
                scanStatus = ((eSIR_SME_SUCCESS == pScanRsp->statusCode) &&
                             (pScanRsp->length > 50)) ? eCSR_SCAN_FOUND_PEER : eCSR_SCAN_FAILURE;
                csrScanProcessScanResults( pMac, pCommand, pScanRsp, NULL );
                break;
            case eCsrScanSetBGScanParam:
            default:
                pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
                scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ?
                              eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
                if(csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand ))
                {
                    //Not to get channel info if the scan is not a wildcard scan because
                    //it may cause scan results got aged out incorrectly.
                    if(csrScanIsWildCardScan( pMac, pCommand ) &&
                             (!pCommand->u.scanCmd.u.scanRequest.p2pSearch)
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
                        && (pCommand->u.scanCmd.reason != eCsrScanGetLfrResult)
#endif
                      )
                    {
                         csrScanGetScanChnInfo(pMac, pCommand);
                    }
                }
                break;
            }//switch
            if(fRemoveCommand)
            {

                csrReleaseScanCommand(pMac, pCommand, scanStatus);

            }
            smeProcessPendingQueue( pMac );
        }
        else
        {
            smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." );
            status = eHAL_STATUS_FAILURE;
        }
    }
    else
    {
        smsLog( pMac, LOGW, "CSR: Scan Completion called but NO commands are ACTIVE ..." );
        status = eHAL_STATUS_FAILURE;
    }
    
    return (status);
}




tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal pMac, tScanResultHandle hScanResult)
{
    tListElem *pEntry;
    tCsrScanResult *pResult;
    tCsrScanResultInfo *pRet = NULL;
    tScanResultList *pResultList = (tScanResultList *)hScanResult;
    
    if(pResultList)
    {
        csrLLLock(&pResultList->List);
        pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
        if(pEntry)
        {
            pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
            pRet = &pResult->Result;
        }
        pResultList->pCurEntry = pEntry;
        csrLLUnlock(&pResultList->List);
    }
    
    return pRet;
}


tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal pMac, tScanResultHandle hScanResult)
{
    tListElem *pEntry = NULL;
    tCsrScanResult *pResult = NULL;
    tCsrScanResultInfo *pRet = NULL;
    tScanResultList *pResultList = (tScanResultList *)hScanResult;
    
    if(pResultList)
    {
        csrLLLock(&pResultList->List);
        if(NULL == pResultList->pCurEntry)
        {
            pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
        }
        else
        {
            pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK);
        }
        if(pEntry)
        {
            pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
            pRet = &pResult->Result;
        }
        pResultList->pCurEntry = pEntry;
        csrLLUnlock(&pResultList->List);
    }
    
    return pRet;
}


//This function moves the first BSS that matches the bssid to the head of the result
eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tScanResultList *pResultList = (tScanResultList *)hScanResult;
    tCsrScanResult *pResult = NULL;
    tListElem *pEntry = NULL;
   
    if(pResultList && bssid)
    {
        csrLLLock(&pResultList->List);
        pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
        while(pEntry)
        {
            pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
            if (vos_mem_compare(bssid, pResult->Result.BssDescriptor.bssId, sizeof(tCsrBssid)))
            {
                status = eHAL_STATUS_SUCCESS;
                csrLLRemoveEntry(&pResultList->List, pEntry, LL_ACCESS_NOLOCK);
                csrLLInsertHead(&pResultList->List, pEntry, LL_ACCESS_NOLOCK);
                break;
            }
            pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK);
        }
        csrLLUnlock(&pResultList->List);
    }
    
    return (status);
}


//Remove the BSS if possible.
//Return -- TRUE == the BSS is remove. False == Fail to remove it
//This function is called when list lock is held. Be caution what functions it can call.
tANI_BOOLEAN csrScanAgeOutBss(tpAniSirGlobal pMac, tCsrScanResult *pResult)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
    tANI_U32 i;
    tCsrRoamSession *pSession;
    tANI_BOOLEAN isConnBssfound = eANI_BOOLEAN_FALSE;

    for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
    {
        if( CSR_IS_SESSION_VALID( pMac, i ) )
        {
            pSession = CSR_GET_SESSION( pMac, i );
            //Not to remove the BSS we are connected to.
            if(csrIsConnStateConnectedInfra(pMac, i) && (NULL != pSession->pConnectBssDesc) &&
              (csrIsDuplicateBssDescription(pMac, &pResult->Result.BssDescriptor,
                                             pSession->pConnectBssDesc, NULL, FALSE))
              )
              {
                isConnBssfound = eANI_BOOLEAN_TRUE;
                break;
              }
        }
    }

    if( isConnBssfound )
    {
        //Reset the counter so that aging out of connected BSS won't hapeen too soon
        pResult->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
        pResult->Result.BssDescriptor.nReceivedTime =
                                        vos_timer_get_system_time();

        return (fRet);
    }
    else
    {
        smsLog(pMac, LOGW, "Aging out BSS "MAC_ADDRESS_STR" Channel %d",
               MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId),
               pResult->Result.BssDescriptor.channelId);
        //No need to hold the spin lock because caller should hold the lock for pMac->scan.scanResultList
        if( csrLLRemoveEntry(&pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_NOLOCK) )
        {
            if (csrIsMacAddressEqual(pMac,
                       (tCsrBssid *) pResult->Result.BssDescriptor.bssId,
                       (tCsrBssid *) pMac->scan.currentCountryBssid))
            {
                smsLog(pMac, LOGW, "Aging out 11d BSS "MAC_ADDRESS_STR,
                       MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId));
                pMac->scan.currentCountryRSSI = -128;
            }
            csrFreeScanResultEntry(pMac, pResult);
            fRet = eANI_BOOLEAN_TRUE;
        }
    }

    return (fRet);
}


eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry, *tmpEntry;
    tCsrScanResult *pResult;
    tLimScanChn *pChnInfo;
    tANI_U8 i;

    csrLLLock(&pMac->scan.scanResultList);
    for(i = 0; i < pScanChnInfo->numChn; i++)
    {
        pChnInfo = &pScanChnInfo->scanChn[i];
        pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
        while( pEntry ) 
        {
            tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
            pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
            if(pResult->Result.BssDescriptor.channelId == pChnInfo->channelId)
            {
                if(pResult->AgingCount <= 0)
                {
                    smsLog(pMac, LOGW, " age out due to ref count");
                    csrScanAgeOutBss(pMac, pResult);
                }
                else
                {
                    pResult->AgingCount--;
                }
            }
            pEntry = tmpEntry;
        }
    }
    csrLLUnlock(&pMac->scan.scanResultList);

    return (status);
}

eHalStatus csrIbssAgeBss(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry, *tmpEntry;
    tCsrScanResult *pResult;

    csrLLLock(&pMac->scan.scanResultList);
    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
    while( pEntry )
    {
       tmpEntry = csrLLNext(&pMac->scan.scanResultList,
                                             pEntry, LL_ACCESS_NOLOCK);
       pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );

       smsLog(pMac, LOGW, FL(" age out due Forced IBSS leave"));
       csrScanAgeOutBss(pMac, pResult);
       pEntry = tmpEntry;
    }
    csrLLUnlock(&pMac->scan.scanResultList);

    return (status);
}

/**
 * csr_remove_bssid_from_scan_list() - remove the bssid from
 * scan list
 * @pMac: mac context.
 * @bssid: bssid to be removed
 *
 * This function remove the given bssid from scan list.
 *
 * Return: void.
 */
void csr_remove_bssid_from_scan_list(tpAniSirGlobal pMac,
     tSirMacAddr bssid)
{
    tListElem *entry,*free_elem;
    tCsrScanResult *bss_desc;
    tDblLinkList *list = &pMac->scan.scanResultList;

    csrLLLock(list);
    entry = csrLLPeekHead(list, LL_ACCESS_NOLOCK);
    while (entry != NULL) {
        bss_desc = GET_BASE_ADDR( entry, tCsrScanResult, Link);
        if (vos_mem_compare(bss_desc->Result.BssDescriptor.bssId,
           bssid, sizeof(tSirMacAddr))) {
            free_elem = entry;
            entry = csrLLNext(list, entry, LL_ACCESS_NOLOCK);
            csrLLRemoveEntry(list, free_elem, LL_ACCESS_NOLOCK);
            csrFreeScanResultEntry(pMac, bss_desc);
            smsLog(pMac, LOGW, FL("Removed BSS entry:%pM"),
                   bssid);
            continue;
        }
        entry = csrLLNext(list, entry, LL_ACCESS_NOLOCK);
    }
    csrLLUnlock(list);
}

eHalStatus csrSendMBScanReq( tpAniSirGlobal pMac, tANI_U16 sessionId, 
                    tCsrScanRequest *pScanReq, tScanReqParam *pScanReqParam )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirSmeScanReq *pMsg;
    tANI_U16 msgLen;
    tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0};
    tSirScanType scanType = pScanReq->scanType;
    tANI_U32 minChnTime;    //in units of milliseconds
    tANI_U32 maxChnTime;    //in units of milliseconds
    tANI_U32 i;
    tANI_U8 selfMacAddr[WNI_CFG_BSSID_LEN];
    tANI_U8 *pSelfMac = NULL;

    msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) + 
                        ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) +
                   ( pScanReq->uIEFieldLen ) ;

    pMsg = vos_mem_malloc(msgLen);
    if ( NULL == pMsg )
        status = eHAL_STATUS_FAILURE;
    else
        status = eHAL_STATUS_SUCCESS;
    if (HAL_STATUS_SUCCESS(status))
    {
        do
        {
            vos_mem_set(pMsg, msgLen, 0);
            pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ);
            pMsg->length = pal_cpu_to_be16(msgLen);
            //ToDO: Fill in session info when we need to do scan base on session.
            if ((pMac->fScanOffload) && (sessionId != CSR_SESSION_ID_INVALID))
            {
                pMsg->sessionId = sessionId;
            }
            else
            {
                /* if sessionId == CSR_SESSION_ID_INVALID, then send the scan
                   request on first available session */
                pMsg->sessionId = 0;
            }

            pMsg->transactionId = 0;
            pMsg->dot11mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode ));
            pMsg->bssType = pal_cpu_to_be32(csrTranslateBsstypeToMacType(pScanReq->BSSType));

            if ( CSR_IS_SESSION_VALID( pMac, sessionId ) )
            {
              pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[sessionId].selfMacAddr;
            }
            else
            {
              // Since we don't have session for the scanning, we find a valid session. In case we fail to
              // do so, get the WNI_CFG_STA_ID
              for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
              {
                if( CSR_IS_SESSION_VALID( pMac, i ) )
                {
                  pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[i].selfMacAddr;
                  break;
                }
              }
              if( CSR_ROAM_SESSION_MAX == i )
              {
                tANI_U32 len = WNI_CFG_BSSID_LEN;
                pSelfMac = selfMacAddr;
                status = ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pSelfMac, &len );
                if( !HAL_STATUS_SUCCESS( status ) || 
                    ( len < WNI_CFG_BSSID_LEN ) )
                {
                  smsLog( pMac, LOGE, FL(" Can not get self MAC address from CFG status = %d"), status );
                  //Force failed status
                  status = eHAL_STATUS_FAILURE;
                  break;
                }
              }
            }
            vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, pSelfMac, sizeof(tSirMacAddr));

            //sirCopyMacAddr
            vos_mem_copy((tANI_U8 *)pMsg->bssId, (tANI_U8 *)&pScanReq->bssid, sizeof(tSirMacAddr));
            if ( vos_mem_compare(pScanReq->bssid, bssid, sizeof(tCsrBssid)))
            {
                vos_mem_set(pMsg->bssId, sizeof(tSirMacAddr), 0xff);
            }
            else
            {
                vos_mem_copy(pMsg->bssId, pScanReq->bssid, WNI_CFG_BSSID_LEN);
            }
            minChnTime = pScanReq->minChnTime;
            maxChnTime = pScanReq->maxChnTime;

            //Verify the scan type first, if the scan is active scan, we need to make sure we 
            //are allowed to do so.
            /* if 11d is enabled & we don't see any beacon around, scan type falls
               back to passive. But in BT AMP STA mode we need to send out a
               directed probe*/
            if( (eSIR_PASSIVE_SCAN != scanType) && (eCSR_SCAN_P2P_DISCOVERY != pScanReq->requestType)
                && (eCSR_BSS_TYPE_WDS_STA != pScanReq->BSSType)
                && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d))
            {
                scanType = pMac->scan.curScanType;
                if(eSIR_PASSIVE_SCAN == pMac->scan.curScanType)
                {
                    if(minChnTime < pMac->roam.configParam.nPassiveMinChnTime) 
                    {
                        minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
                    }
                    if(maxChnTime < pMac->roam.configParam.nPassiveMaxChnTime)
                    {
                        maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
                    }
                }
            }
            pMsg->scanType = pal_cpu_to_be32(scanType);

            pMsg->numSsid =
             (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ?
             pScanReq->SSIDs.numOfSSIDs : SIR_SCAN_MAX_NUM_SSID;
            if((pScanReq->SSIDs.numOfSSIDs != 0) && ( eSIR_PASSIVE_SCAN != scanType ))
            {
                for (i = 0; i < pMsg->numSsid; i++)
                {
                    vos_mem_copy(&pMsg->ssId[i],
                                 &pScanReq->SSIDs.SSIDList[i].SSID, sizeof(tSirMacSSid));
                }
            }
            else
            {
                //Otherwise we scan all SSID and let the result filter later
                for (i = 0; i < SIR_SCAN_MAX_NUM_SSID; i++)
                {
                    pMsg->ssId[i].length = 0;
                }
            }

            pMsg->minChannelTime = pal_cpu_to_be32(minChnTime);
            pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime);
            pMsg->min_chntime_btc_esco =
                pMac->roam.configParam.min_chntime_btc_esco;
            pMsg->max_chntime_btc_esco =
                pMac->roam.configParam.max_chntime_btc_esco;
            //hidden SSID option
            pMsg->hiddenSsid = pScanReqParam->hiddenSsid;
            //rest time
            //pMsg->restTime = pScanReq->restTime;
            pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
            // All the scan results caching will be done by Roaming
            // We do not want LIM to do any caching of scan results,
            // so delete the LIM cache on all scan requests
            pMsg->returnFreshResults = pScanReqParam->freshScan;
            //Always ask for unique result
            pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
            pMsg->channelList.numChannels = (tANI_U8)pScanReq->ChannelInfo.numOfChannels;
            if(pScanReq->ChannelInfo.numOfChannels)
            {
                //Assuming the channelNumber is tANI_U8 (1 byte)
                vos_mem_copy(pMsg->channelList.channelNumber,
                             pScanReq->ChannelInfo.ChannelList,
                             pScanReq->ChannelInfo.numOfChannels);
            }

            pMsg->uIEFieldLen = (tANI_U16) pScanReq->uIEFieldLen;
            pMsg->uIEFieldOffset = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) + 
                  ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) ;
            if(pScanReq->uIEFieldLen != 0) 
            {
                vos_mem_copy((tANI_U8 *)pMsg+pMsg->uIEFieldOffset, pScanReq->pIEField,
                              pScanReq->uIEFieldLen);
            }
            pMsg->p2pSearch = pScanReq->p2pSearch;
            pMsg->scan_randomize= pScanReq->scan_randomize;
            pMsg->nl_scan = pScanReq->nl_scan;

            if (pScanReq->requestType == eCSR_SCAN_HO_BG_SCAN) 
            {
                pMsg->backgroundScanMode = eSIR_ROAMING_SCAN;
            } 

        }while(0);
        smsLog(pMac, LOG1, FL("domainIdCurrent %s (%d) scanType %s (%d)"
                              "bssType %s (%d), requestType %s(%d)"
                              "numChannels %d"),
               voss_DomainIdtoString(pMac->scan.domainIdCurrent),
               pMac->scan.domainIdCurrent,
               lim_ScanTypetoString(pMsg->scanType), pMsg->scanType,
               lim_BssTypetoString(pMsg->bssType), pMsg->bssType,
               sme_requestTypetoString(pScanReq->requestType),
               pScanReq->requestType,
               pMsg->channelList.numChannels);

        for(i = 0; i < pMsg->channelList.numChannels; i++)
        {
            smsLog(pMac, LOG3, FL("channelNumber[%d]= %d"), i, pMsg->channelList.channelNumber[i]);
        }

        if(HAL_STATUS_SUCCESS(status))
        {
            status = palSendMBMessage(pMac->hHdd, pMsg);
        }
        else 
        {
            smsLog( pMac, LOGE, FL(" failed to send down scan req with status = %d"), status );
            vos_mem_free(pMsg);
        }
    }//Success allocated memory
    else
    {
        smsLog( pMac, LOGE, FL(" memory allocation failure"));
    }

    if(!HAL_STATUS_SUCCESS(status))
    {
        smsLog( pMac, LOG1, FL("Failed: SId: %d FirstMatch = %d"
                 " UniqueResult = %d freshScan = %d hiddenSsid = %d"),
                 sessionId, pScanReqParam->bReturnAfter1stMatch,
                 pScanReqParam->fUniqueResult, pScanReqParam->freshScan,
                 pScanReqParam->hiddenSsid );
        smsLog( pMac, LOG1, FL("scanType = %s (%d) BSSType = %s (%d) "
                "numOfSSIDs = %d numOfChannels = %d requestType = %s (%d)"
                " p2pSearch = %d\n"),
                 lim_ScanTypetoString(pScanReq->scanType),
                 pScanReq->scanType,
                 lim_BssTypetoString(pScanReq->BSSType),
                 pScanReq->BSSType,
                 pScanReq->SSIDs.numOfSSIDs,
                 pScanReq->ChannelInfo.numOfChannels,
                 sme_requestTypetoString(pScanReq->requestType),
                 pScanReq->requestType,
                 pScanReq->p2pSearch );

    }

    return( status );
}

eHalStatus csrSendMBScanResultReq( tpAniSirGlobal pMac, tANI_U32 sessionId, tScanReqParam *pScanReqParam )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirSmeScanReq *pMsg;
    tANI_U16 msgLen;

    msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ));
    pMsg = vos_mem_malloc(msgLen);
    if ( NULL == pMsg )
       status = eHAL_STATUS_FAILURE;
    else
    {
        vos_mem_set(pMsg, msgLen, 0);
        pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ);
        pMsg->length = pal_cpu_to_be16(msgLen);
        pMsg->sessionId = sessionId;
        pMsg->transactionId = 0;
        pMsg->returnFreshResults = pScanReqParam->freshScan;
        //Always ask for unique result
        pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
        pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
        status = palSendMBMessage(pMac->hHdd, pMsg);
        if (!HAL_STATUS_SUCCESS(status))
        {
            smsLog( pMac, LOGE, FL(" failed to send down scan req with status = %d\n"), status );
        }

    }                             

    return( status );
}



eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tScanReqParam scanReq;
    
    do
    {    
        scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE | TRUE;
        scanReq.fUniqueResult = TRUE;
        scanReq.hiddenSsid = SIR_SCAN_NO_HIDDEN_SSID;
        if(eCsrScanForSsid == pCommand->u.scanCmd.reason)
        {
            scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_FIRST_MATCH;
        }
        else
        {
            // Basically do scan on all channels even for 11D 1st scan case.
            scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
        }
        if((eCsrScanBgScan == pCommand->u.scanCmd.reason)||
           (eCsrScanProbeBss == pCommand->u.scanCmd.reason))
        {
            scanReq.hiddenSsid = SIR_SCAN_HIDDEN_SSID_PE_DECISION;
        }

#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
        {
            vos_log_scan_pkt_type *pScanLog = NULL;

            WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
            if(pScanLog)
            {
                if(eCsrScanBgScan == pCommand->u.scanCmd.reason || 
                    eCsrScanProbeBss == pCommand->u.scanCmd.reason)
                {
                    pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
                }
                else
                {
                    if( (eSIR_PASSIVE_SCAN != pCommand->u.scanCmd.u.scanRequest.scanType) && 
                        (eSIR_PASSIVE_SCAN != pMac->scan.curScanType) )
                    {
                        pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ;
                    }
                    else
                    {
                        pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ;
                    }
                }
                pScanLog->minChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.minChnTime;
                pScanLog->maxChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.maxChnTime;
                pScanLog->numChannel = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
                if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL))
                {
                    vos_mem_copy(pScanLog->channels,
                                 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
                                 pScanLog->numChannel);
                }
                WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
            }
        }
#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR

        csrClearVotesForCountryInfo(pMac);
        status = csrSendMBScanReq(pMac, pCommand->sessionId,
                                &pCommand->u.scanCmd.u.scanRequest, &scanReq);
    }while(0);
    
    return( status );
}


eHalStatus csrScanRetrieveResult(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tScanReqParam scanReq;
    
    do
    {    
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
        if (eCsrScanGetLfrResult == pCommand->u.scanCmd.reason)
        {
            //to get the LFR candidates from PE cache
            scanReq.freshScan = SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS|SIR_BG_SCAN_PURGE_LFR_RESULTS;
            scanReq.fUniqueResult = TRUE;
            scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
        }
        else
#endif
        {
           //not a fresh scan
           scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE;
           scanReq.fUniqueResult = TRUE;
           scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
        }
        status = csrSendMBScanResultReq(pMac, pCommand->sessionId, &scanReq);
    }while(0);
    
    return (status);
}

eHalStatus csrProcessMacAddrSpoofCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
   tSirSpoofMacAddrReq *pMsg;
   tANI_U16 msgLen;
   eHalStatus status = eHAL_STATUS_FAILURE;
   do {
      msgLen = sizeof(tSirSpoofMacAddrReq);

      pMsg = vos_mem_malloc(msgLen);
      if ( NULL == pMsg )
          return eHAL_STATUS_FAILURE;
      pMsg->messageType= pal_cpu_to_be16((tANI_U16)eWNI_SME_MAC_SPOOF_ADDR_IND);
      pMsg->length= pal_cpu_to_be16(msgLen);
      // spoof mac address
      vos_mem_copy((tANI_U8 *)pMsg->macAddr,
           (tANI_U8 *)pCommand->u.macAddrSpoofCmd.macAddr, sizeof(tSirMacAddr));
      pMsg->spoof_mac_oui =
       pal_cpu_to_be16(pCommand->u.macAddrSpoofCmd.spoof_mac_oui);

      status = palSendMBMessage(pMac->hHdd, pMsg);
   } while( 0 );
   return( status );
}

eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tCsrChannelInfo newChannelInfo = {0, NULL};
    int i, j;
    tANI_U8 *pChannel = NULL;
    tANI_U32 len = 0;

    // Transition to Scanning state...
    if (!pMac->fScanOffload)
    {
        for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
        {
            pMac->roam.prev_state[i]=
                csrRoamStateChange( pMac, eCSR_ROAMING_STATE_SCANNING, i);
            smsLog( pMac, LOG3, "starting SCAN command from %d state...."
                    " reason is %d", pMac->roam.prev_state[i],
                    pCommand->u.scanCmd.reason );
        }
    }
    else
    {
        pMac->roam.prev_state[pCommand->sessionId] =
            csrRoamStateChange(pMac, eCSR_ROAMING_STATE_SCANNING,
                               pCommand->sessionId);
        smsLog( pMac, LOG3,
                "starting SCAN command from %d state.... reason is %d",
                pMac->roam.prev_state[pCommand->sessionId],
                pCommand->u.scanCmd.reason );
    }

    switch(pCommand->u.scanCmd.reason)
    {
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    case eCsrScanGetLfrResult:
#endif
    case eCsrScanGetResult:
    case eCsrScanForCapsChange:     //For cap change, LIM already save BSS description
        status = csrScanRetrieveResult(pMac, pCommand);
        break;
    case eCsrScanSetBGScanParam:
        status = csrProcessSetBGScanParam(pMac, pCommand);
        break;
    case eCsrScanBGScanAbort:
        status = csrSetCfgBackgroundScanPeriod(pMac, 0);
        break;
    case eCsrScanBGScanEnable:
        status = csrSetCfgBackgroundScanPeriod(pMac, pMac->roam.configParam.bgScanInterval);
        break;
    case eCsrScanGetScanChnInfo:
        status = csrScanGetScanChannelInfo(pMac, pCommand->sessionId);
        break;
    case eCsrScanUserRequest:
        if(pMac->roam.configParam.fScanTwice)
        {
            //We scan 2.4 channel twice
            if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels &&
               (NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList))
            {
                len = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
                //allocate twice the channel
                newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2);
                pChannel = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
            }
            else
            {
                //get the valid channel list to scan all.
                len = sizeof(pMac->roam.validChannelList);

                if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
                {
                    //allocate twice the channel
                    newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2);
                    pChannel = pMac->roam.validChannelList;
                }
            }
            if(NULL == newChannelInfo.ChannelList)
            {
                newChannelInfo.numOfChannels = 0;
            }
            else
            {
                j = 0;
                for(i = 0; i < len; i++)
                {
                    newChannelInfo.ChannelList[j++] = pChannel[i];
                    if(CSR_MAX_24GHz_CHANNEL_NUMBER >= pChannel[i])
                    {
                        newChannelInfo.ChannelList[j++] = pChannel[i];
                    }
                }
                if(NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
                {
                    //pChannel points to the channellist from the command, free it.
                    vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
                    pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
                }
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = j;
                pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = newChannelInfo.ChannelList;
            }
        } //if(pMac->roam.configParam.fScanTwice)

        status = csrScanChannels(pMac, pCommand);

        break;
    default:
        status = csrScanChannels(pMac, pCommand);
        break;
    }    
    
    if(!HAL_STATUS_SUCCESS(status))
    {
        csrReleaseScanCommand(pMac, pCommand, eCSR_SCAN_FAILURE);
    }
    
    return (status);
}


eHalStatus csrScanSetBGScanparams(tpAniSirGlobal pMac, tCsrBGScanRequest *pScanReq)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pCommand = NULL;
    
    if(pScanReq)
    {
        do
        {
            pCommand = csrGetCommandBuffer(pMac);
            if(!pCommand)
            {
                status = eHAL_STATUS_RESOURCES;
                break;
            }
            vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
            pCommand->command = eSmeCommandScan;
            pCommand->u.scanCmd.reason = eCsrScanSetBGScanParam;
            pCommand->u.scanCmd.callback = NULL;
            pCommand->u.scanCmd.pContext = NULL;
            vos_mem_copy(&pCommand->u.scanCmd.u.bgScanRequest, pScanReq, sizeof(tCsrBGScanRequest));
            //we have to do the follow
            if(pScanReq->ChannelInfo.numOfChannels == 0)
            {
                pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL;
            }
            else
            {
                pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList
                                 = vos_mem_malloc(pScanReq->ChannelInfo.numOfChannels);
                if ( NULL != pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList )
                {
                    vos_mem_copy(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList,
                                 pScanReq->ChannelInfo.ChannelList,
                                 pScanReq->ChannelInfo.numOfChannels);
                }
                else
                {
                    smsLog(pMac, LOGE, FL("ran out of memory"));
                    csrReleaseCommandScan(pMac, pCommand);
                    return eHAL_STATUS_FAILURE;
                }
            }

            //scan req for SSID
            if(pScanReq->SSID.length)
            {
               vos_mem_copy(pCommand->u.scanCmd.u.bgScanRequest.SSID.ssId,
                            pScanReq->SSID.ssId, pScanReq->SSID.length);
               pCommand->u.scanCmd.u.bgScanRequest.SSID.length = pScanReq->SSID.length;

            }
            pCommand->u.scanCmd.u.bgScanRequest.maxChnTime= pScanReq->maxChnTime;
            pCommand->u.scanCmd.u.bgScanRequest.minChnTime = pScanReq->minChnTime;
            pCommand->u.scanCmd.u.bgScanRequest.scanInterval = pScanReq->scanInterval;


            status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                csrReleaseCommandScan( pMac, pCommand );
                break;
            }
        }while(0);
    }
    
    return (status);
}

eHalStatus csrScanBGScanAbort( tpAniSirGlobal pMac )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pCommand = NULL;
    
    do
    {
        pCommand = csrGetCommandBuffer(pMac);
        if(!pCommand)
        {
            status = eHAL_STATUS_RESOURCES;
            break;
        }
        vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
        pCommand->command = eSmeCommandScan; 
        pCommand->u.scanCmd.reason = eCsrScanBGScanAbort;
        pCommand->u.scanCmd.callback = NULL;
        pCommand->u.scanCmd.pContext = NULL;
        status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
        if( !HAL_STATUS_SUCCESS( status ) )
        {
            smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
            csrReleaseCommandScan( pMac, pCommand );
            break;
        }
    }while(0);
    
    return (status);
}


//This will enable the background scan with the non-zero interval 
eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSmeCmd *pCommand = NULL;
    
    if(pMac->roam.configParam.bgScanInterval)
    {
        do
        {
            pCommand = csrGetCommandBuffer(pMac);
            if(!pCommand)
            {
                status = eHAL_STATUS_RESOURCES;
                break;
            }
            vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
            pCommand->command = eSmeCommandScan; 
            pCommand->u.scanCmd.reason = eCsrScanBGScanEnable;
            pCommand->u.scanCmd.callback = NULL;
            pCommand->u.scanCmd.pContext = NULL;
            status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                csrReleaseCommandScan( pMac, pCommand );
                break;
            }
        }while(0);
    }
    else
    {
       smsLog(pMac, LOGE, FL("cannot continue because the bgscan interval is 0"));
       status = eHAL_STATUS_INVALID_PARAMETER;
    }
    return (status);
}


eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_U32 len = sizeof(pMac->roam.validChannelList);
    tANI_U32 index = 0;
    tANI_U32 new_index = 0;
    eNVChannelEnabledType NVchannel_state;
    tANI_U8  ch144_support = 0;

    ch144_support = WDA_getFwWlanFeatCaps(WLAN_CH144);

    do
    {
        status = csrScanFreeRequest(pMac, pDstReq);
        if(HAL_STATUS_SUCCESS(status))
        {
            vos_mem_copy(pDstReq, pSrcReq, sizeof(tCsrScanRequest));
            /* Re-initialize the pointers to NULL since we did a copy */
            pDstReq->pIEField = NULL;
            pDstReq->ChannelInfo.ChannelList = NULL;
            pDstReq->SSIDs.SSIDList = NULL;

            if(pSrcReq->uIEFieldLen == 0)
            {
                pDstReq->pIEField = NULL;
            }
            else
            {
                pDstReq->pIEField = vos_mem_malloc(pSrcReq->uIEFieldLen);
                if ( NULL == pDstReq->pIEField )
                {
                    status = eHAL_STATUS_FAILURE;
                    smsLog(pMac, LOGE, FL("No memory for scanning IE fields"));
                    break;
                }
                else
                {
                    status = eHAL_STATUS_SUCCESS;
                    vos_mem_copy(pDstReq->pIEField, pSrcReq->pIEField,
                                  pSrcReq->uIEFieldLen);
                    pDstReq->uIEFieldLen = pSrcReq->uIEFieldLen;
                }
            }//Allocate memory for IE field
            {
                if(pSrcReq->ChannelInfo.numOfChannels == 0)
                {
                    pDstReq->ChannelInfo.ChannelList = NULL;
                        pDstReq->ChannelInfo.numOfChannels = 0;
                }
                else
                {
                    pDstReq->ChannelInfo.ChannelList = vos_mem_malloc(
                                         pSrcReq->ChannelInfo.numOfChannels
                                         * sizeof(*pDstReq->ChannelInfo.ChannelList));
                    if ( NULL == pDstReq->ChannelInfo.ChannelList )
                    {
                        status = eHAL_STATUS_FAILURE;
                        pDstReq->ChannelInfo.numOfChannels = 0;
                        smsLog(pMac, LOGE, FL("No memory for scanning Channel"
                                              " List"));
                        break;
                    }

                    if((pSrcReq->scanType == eSIR_PASSIVE_SCAN) && (pSrcReq->requestType == eCSR_SCAN_REQUEST_11D_SCAN))
                    {
                       for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ )
                       {
                          /* Skip CH 144 if firmware support not present */
                          if (pSrcReq->ChannelInfo.ChannelList[index] == 144 && !ch144_support)
                              continue;
                          /* Skip channel 12 and 13 when FCC constraint is true */
                          if ((pMac->scan.fcc_constraint) &&
                                 ((pSrcReq->ChannelInfo.ChannelList[index] ==12) ||
                                 (pSrcReq->ChannelInfo.ChannelList[index] ==13)))
                          {
                              VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                                  FL("Ignoring channel : %d "),
                                  pSrcReq->ChannelInfo.ChannelList[index]);
                              continue;
                          }

                          NVchannel_state = vos_nv_getChannelEnabledState(
                                  pSrcReq->ChannelInfo.ChannelList[index]);
                          if ((NV_CHANNEL_ENABLE == NVchannel_state) ||
                                  (NV_CHANNEL_DFS == NVchannel_state))
                          {
                             pDstReq->ChannelInfo.ChannelList[new_index] =
                                 pSrcReq->ChannelInfo.ChannelList[index];
                             new_index++;
                          }
                       }
                       pDstReq->ChannelInfo.numOfChannels = new_index;
                    }
                    else if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
                    {
                        new_index = 0;
                        pMac->roam.numValidChannels = len;

                        /* Since in CsrScanRequest,value of pMac->scan.
                         * nextScanID is incremented before calling
                         * CsrScanCopyRequest, as a result pMac->scan.
                         * nextScanID is equal to ONE for the first scan.
                         * If number of channels is less than max chan
                         * for dwell time no need to skip dfs in first
                         * scan as anyway few channels will be scanned
                         * and it will not take much time to display
                         * results on GUI.
                         */
                        if (((pSrcReq->ChannelInfo.numOfChannels >=
                                     pMac->roam.configParam.
                                     max_chan_for_dwell_time_cfg) &&
                                    (pMac->roam.configParam.
                                    initialScanSkipDFSCh &&
                                     1 == pMac->scan.nextScanID)) ||
                                    (pMac->miracast_mode))
                        {
                            smsLog(pMac, LOG1,
                                FL("Initial scan, scan only non-DFS channels"));

                            for (index = 0; index < pSrcReq->ChannelInfo.
                                    numOfChannels ; index++ )
                            {
                                if((csrRoamIsValidChannel(pMac,
                                                pSrcReq->ChannelInfo.
                                                ChannelList[index])))
                                {
                                    /*Skiipping DFS Channels for 1st scan */
                                    if(NV_CHANNEL_DFS ==
                                            vos_nv_getChannelEnabledState(
                                                pSrcReq->ChannelInfo.
                                                ChannelList[index]))
                                        continue ;

                                     pDstReq->ChannelInfo.
                                        ChannelList[new_index] =
                                        pSrcReq->ChannelInfo.ChannelList[index];
                                    new_index++;

                                }
                            }
                            pMac->roam.configParam.initialScanSkipDFSCh = 0;
                        }
                        else
                            csrValidateScanChannels(pMac, pDstReq, pSrcReq,
                                                    &new_index, ch144_support);
                        pDstReq->ChannelInfo.numOfChannels = new_index;
#ifdef FEATURE_WLAN_LFR
                        if ( ( ( eCSR_SCAN_HO_BG_SCAN ==
                                  pSrcReq->requestType ) ||
                                 ( eCSR_SCAN_P2P_DISCOVERY ==
                                   pSrcReq->requestType ) ) &&
                                 ( 0 == pDstReq->ChannelInfo.numOfChannels ) )
                        {
                            /*
                             * No valid channels found in the request.
                             * Only perform scan on the channels passed
                             * pSrcReq if it is a eCSR_SCAN_HO_BG_SCAN or
                             * eCSR_SCAN_P2P_DISCOVERY.
                             * Passing 0 to LIM will trigger a scan on 
                             * all valid channels which is not desirable.
                             */
                            smsLog(pMac, LOGE, FL(" no valid channels found"
                                        " (request=%d)"), pSrcReq->requestType);
                            for ( index = 0; index < pSrcReq->ChannelInfo.
                                    numOfChannels ; index++ )
                            {
                                smsLog(pMac, LOGE, FL("pSrcReq index=%d"
                                            " channel=%d"), index,
                                       pSrcReq->ChannelInfo.ChannelList[index]);
                            }
                            status = eHAL_STATUS_FAILURE;
                            break;
                        }
#endif
                    }
                    else
                    {
                        smsLog(pMac, LOGE, FL("Couldn't get the valid Channel"
                                " List, keeping requester's list"));
                        vos_mem_copy(pDstReq->ChannelInfo.ChannelList,
                                     pSrcReq->ChannelInfo.ChannelList,
                                     pSrcReq->ChannelInfo.numOfChannels
                                   * sizeof(*pDstReq->ChannelInfo.ChannelList));
                        pDstReq->ChannelInfo.numOfChannels =
                                            pSrcReq->ChannelInfo.numOfChannels;
                    }
                }//Allocate memory for Channel List
            }
            if(pSrcReq->SSIDs.numOfSSIDs == 0)
            {
                pDstReq->SSIDs.numOfSSIDs = 0;
                pDstReq->SSIDs.SSIDList = NULL;
            }
            else
            {
                pDstReq->SSIDs.SSIDList = vos_mem_malloc(
                              pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList));
                if ( NULL == pDstReq->SSIDs.SSIDList )
                        status = eHAL_STATUS_FAILURE;
                else
                        status = eHAL_STATUS_SUCCESS;
                if (HAL_STATUS_SUCCESS(status))
                {
                    pDstReq->SSIDs.numOfSSIDs = pSrcReq->SSIDs.numOfSSIDs;
                    vos_mem_copy(pDstReq->SSIDs.SSIDList,
                                 pSrcReq->SSIDs.SSIDList,
                                 pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList));
                }
                else
                {
                    pDstReq->SSIDs.numOfSSIDs = 0;
                    smsLog(pMac, LOGE, FL("No memory for scanning SSID List"));
                    break;
                }
            }//Allocate memory for SSID List
            pDstReq->scan_randomize = pSrcReq->scan_randomize;
            pDstReq->nl_scan = pSrcReq->nl_scan;
            pDstReq->p2pSearch = pSrcReq->p2pSearch;
            pDstReq->skipDfsChnlInP2pSearch = pSrcReq->skipDfsChnlInP2pSearch;

        }
    }while(0);
    
    if(!HAL_STATUS_SUCCESS(status))
    {
        csrScanFreeRequest(pMac, pDstReq);
    }
    
    return (status);
}


eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq)
{
    
    if(pReq->ChannelInfo.ChannelList)
    {
        vos_mem_free(pReq->ChannelInfo.ChannelList);
        pReq->ChannelInfo.ChannelList = NULL;
    }
    pReq->ChannelInfo.numOfChannels = 0;
    if(pReq->pIEField)
    {
        vos_mem_free(pReq->pIEField);
        pReq->pIEField = NULL;
    }
    pReq->uIEFieldLen = 0;
    if(pReq->SSIDs.SSIDList)
    {
        vos_mem_free(pReq->SSIDs.SSIDList);
        pReq->SSIDs.SSIDList = NULL;
    }
    pReq->SSIDs.numOfSSIDs = 0;
    
    return eHAL_STATUS_SUCCESS;
}


void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus)
{
    if(pCommand->u.scanCmd.callback)
    {
        if (pCommand->u.scanCmd.abortScanIndication){
             if ((pCommand->u.scanCmd.reason != eCsrScanForSsid) ||
                 (scanStatus != eCSR_SCAN_SUCCESS)) {
                 smsLog( pMac, LOG1, FL("scanDone due to abort"));
                 scanStatus = eCSR_SCAN_ABORT;
             }
        }
        pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext, pCommand->u.scanCmd.scanID, scanStatus); 
    } else {
        smsLog(pMac, LOG2,
               FL("Callback NULL cmd reason %d"),
               pCommand->u.scanCmd.reason);
    }
}


void csrScanStopTimers(tpAniSirGlobal pMac)
{
    csrScanStopIdleScanTimer(pMac);
    csrScanStopGetResultTimer(pMac);
}


eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac)
{
    eHalStatus status;
    
    if(pMac->scan.fScanEnable)
    {
        status = vos_timer_start(&pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL/PAL_TIMER_TO_MS_UNIT);
    }
    else
    {
        status = eHAL_STATUS_FAILURE;
    }
    
    return (status);
}


eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac)
{
    return (vos_timer_stop(&pMac->scan.hTimerGetResult));
}


void csrScanGetResultTimerHandler(void *pv)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( pv );
    
    csrScanRequestResult(pMac);

    vos_timer_start(&pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL/PAL_TIMER_TO_MS_UNIT);
}


void csr_handle_disable_scan(void *pv)
{
    tpAniSirGlobal mac = PMAC_STRUCT(pv);

    if (mac->scan.disable_scan_during_sco_timer_info.callback)
        mac->scan.disable_scan_during_sco_timer_info.callback(
        mac,
        mac->scan.disable_scan_during_sco_timer_info.dev,
        mac->scan.disable_scan_during_sco_timer_info.scan_id,
        eHAL_STATUS_SUCCESS);
    else
        smsLog(mac, LOGE, FL("Callback is NULL"));
}

#ifdef WLAN_AP_STA_CONCURRENCY
static void csrStaApConcTimerHandler(void *pv)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( pv );
    tListElem *pEntry;
    tSmeCmd *pScanCmd;

    csrLLLock(&pMac->scan.scanCmdPendingList);

    if ( NULL != ( pEntry = csrLLPeekHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) )
    {    
        tCsrScanRequest scanReq;
        tSmeCmd *pSendScanCmd = NULL;
        tANI_U8 numChn = 0;
        tANI_U8 nNumChanCombinedConc = 0;
        tANI_U8 i, j;
        tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
        tANI_U8    channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
        eHalStatus status;
       
        pScanCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;

        /* if any session is connected and the number of channels to scan is
         * greater than 1 then split the scan into multiple scan operations
         * on each individual channel else continue to perform scan on all
         * specified channels */

        /* split scan if number of channels to scan is greater than 1 and
         * any one of the following:
         * - STA session is connected and the scan is not a P2P search
         * - any P2P session is connected
         * - STA+SAP. In STA+SAP concurrency, scan requests received on
         *   STA interface when not in connected state are not split.
         *   This can result in large time gap between successive beacons
         *   sent by SAP.
         * Do not split scans if no concurrent infra connections are 
         * active and if the scan is a BG scan triggered by LFR (OR)
         * any scan if LFR is in the middle of a BG scan. Splitting
         * the scan is delaying the time it takes for LFR to find
         * candidates and resulting in disconnects.
         */

        if (csrIsInfraApStarted(pMac) && !csrIsP2pGoSessionConnected(pMac))
        {
            nNumChanCombinedConc = 1;
        }
        else if((csrIsStaSessionConnected(pMac) &&
           !csrIsP2pSessionConnected(pMac)))
        {
           nNumChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc;
        }
        else if(csrIsP2pSessionConnected(pMac))
        {
           nNumChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc;
        }

        if ( (numChn > nNumChanCombinedConc) &&
                ((csrIsStaSessionConnected(pMac) && 
#ifdef FEATURE_WLAN_LFR
                  (csrIsConcurrentInfraConnected(pMac) ||
                   ((pScanCmd->u.scanCmd.reason != eCsrScanBgScan) &&
                    (pMac->roam.neighborRoamInfo.neighborRoamState != 
                     eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) &&
#endif
                  (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
              (csrIsP2pSessionConnected(pMac))))
        {
             vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0);

             pSendScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
             if (!pSendScanCmd)
             {
                 smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer") );
                 csrLLUnlock(&pMac->scan.scanCmdPendingList);
                 return;
             }
             pSendScanCmd->command = pScanCmd->command; 
             pSendScanCmd->sessionId = pScanCmd->sessionId;
             pSendScanCmd->u.scanCmd.callback = NULL;
             pSendScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
             pSendScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
             pSendScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around

             /* First copy all the parameters to local variable of scan request */
             csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);
             
             /* Now modify the elements of local var scan request required to be modified for split scan */
             if(scanReq.ChannelInfo.ChannelList != NULL)
             {
                 vos_mem_free(scanReq.ChannelInfo.ChannelList);
                 scanReq.ChannelInfo.ChannelList = NULL;
             }
             
             pChnInfo->numOfChannels = nNumChanCombinedConc;
             vos_mem_copy(&channelToScan[0],
                          &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0],
                          pChnInfo->numOfChannels * sizeof(tANI_U8));//just send one channel
             pChnInfo->ChannelList = &channelToScan[0];

             for (i = 0, j = nNumChanCombinedConc; i < (numChn-nNumChanCombinedConc); i++, j++)
             {
                 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] = 
                 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[j]; //Move all the channels one step
             }
          
             pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn - nNumChanCombinedConc; //reduce outstanding # of channels to be scanned

             scanReq.BSSType = eCSR_BSS_TYPE_ANY;

             //Use concurrency values for min/maxChnTime. 
             //We know csrIsAnySessionConnected(pMac) returns TRUE here
             csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);

             status = csrScanCopyRequest(pMac, &pSendScanCmd->u.scanCmd.u.scanRequest, &scanReq);
             if(!HAL_STATUS_SUCCESS(status))
             {
                 smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d"), status );
                 csrLLUnlock(&pMac->scan.scanCmdPendingList);
                 return;
             }
             /* Clean the local scan variable */
             scanReq.ChannelInfo.ChannelList = NULL;
             scanReq.ChannelInfo.numOfChannels = 0;
             csrScanFreeRequest(pMac, &scanReq);
        }
        else
        {
             /* no active connected session present or numChn == 1
              * scan all remaining channels */
             pSendScanCmd = pScanCmd;
             //remove this command from pending list 
             if (csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) == NULL)
             { //In case between PeekHead and here, the entry got removed by another thread.
                 smsLog( pMac, LOGE, FL(" Failed to remove entry from scanCmdPendingList"));
             }
            
        }               
        csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE);

    }

    csrLLUnlock(&pMac->scan.scanCmdPendingList);
    
}
#endif

//This function returns the maximum time a BSS is allowed in the scan result.
//The time varies base on connection and power saving factors.
//Not connected, No PS
//Not connected, with PS
//Connected w/o traffic, No PS
//Connected w/o traffic, with PS
//Connected w/ traffic, no PS -- Not supported
//Connected w/ traffic, with PS -- Not supported
//the return unit is in seconds. 
tANI_U32 csrScanGetAgeOutTime(tpAniSirGlobal pMac)
{
    tANI_U32 nRet;

    if(pMac->scan.nAgingCountDown)
    {
        //Calculate what should be the timeout value for this
        nRet = pMac->scan.nLastAgeTimeOut * pMac->scan.nAgingCountDown;
        pMac->scan.nAgingCountDown--;
    }
    else
    {
        if( csrIsAllSessionDisconnected( pMac ) )
        {
            if(pmcIsPowerSaveEnabled(pMac, ePMC_IDLE_MODE_POWER_SAVE))
            {
                nRet = pMac->roam.configParam.scanAgeTimeNCPS;
            }
            else
            {
                nRet = pMac->roam.configParam.scanAgeTimeNCNPS;
            }
        }
        else
        {
            if(pmcIsPowerSaveEnabled(pMac, ePMC_BEACON_MODE_POWER_SAVE))
            {
                nRet = pMac->roam.configParam.scanAgeTimeCPS;
            }
            else
            {
                nRet = pMac->roam.configParam.scanAgeTimeCNPS;
            }
        }
        //If state-change causing aging time out change, we want to delay it somewhat to avoid
        //unnecessary removal of BSS. This is mostly due to transition from connect to disconnect.
        if(pMac->scan.nLastAgeTimeOut > nRet)
        {
            if(nRet)
            {
                pMac->scan.nAgingCountDown = (pMac->scan.nLastAgeTimeOut / nRet);
            }
            pMac->scan.nLastAgeTimeOut = nRet;
            nRet *= pMac->scan.nAgingCountDown;
        }
        else
        {
            pMac->scan.nLastAgeTimeOut = nRet;
        }
    }

    return (nRet);
}

static void csrPurgeScanResultByAge(void *pv)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( pv );
    tListElem *pEntry, *tmpEntry;
    tCsrScanResult *pResult;
    v_TIME_t ageOutTime =
       (v_TIME_t)(pMac->scan.scanResultCfgAgingTime * SYSTEM_TIME_SEC_TO_MSEC);
    v_TIME_t curTime = vos_timer_get_system_time();
  
    csrLLLock(&pMac->scan.scanResultList);
    pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
    smsLog(pMac, LOG1, FL("Ageout time=%lu"),ageOutTime);
    while( pEntry ) 
    {
        tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
        pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
        if((curTime - pResult->Result.BssDescriptor.nReceivedTime) > ageOutTime)
        {
            smsLog(pMac, LOG1, FL("age out due to time out for BSSID" MAC_ADDRESS_STR),
                             MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId));
            csrScanAgeOutBss(pMac, pResult);
        }
        pEntry = tmpEntry;
    }
    csrLLUnlock(&pMac->scan.scanResultList);
}

eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval)
{
    eHalStatus status;
    
    smsLog(pMac, LOG1, " csrScanStartIdleScanTimer");
    if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) && interval)
    {
        pMac->scan.nIdleScanTimeGap += interval;
        vos_timer_stop(&pMac->scan.hTimerIdleScan);
        status = vos_timer_start(&pMac->scan.hTimerIdleScan, interval/PAL_TIMER_TO_MS_UNIT);
        if( !HAL_STATUS_SUCCESS(status) )
        {
            smsLog(pMac, LOGE, "  Fail to start Idle scan timer. status = %d interval = %d", status, interval);
            //This should not happen but set the flag to restart when ready
            pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
        }
    }
    else
    {
        if( pMac->scan.fScanEnable && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) )
        {
            pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
        }
        status = eHAL_STATUS_FAILURE;
    }
    
    return (status);
}


eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac)
{
    return (vos_timer_stop(&pMac->scan.hTimerIdleScan));
}


//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR
void csrScanSuspendIMPS( tpAniSirGlobal pMac )
{
    csrScanCancelIdleScan(pMac);
}


//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS
//because IMPS maybe disabled.
void csrScanResumeIMPS( tpAniSirGlobal pMac )
{
    csrScanStartIdleScan( pMac );
}


void csrScanIMPSCallback(void *callbackContext, eHalStatus status)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext );

    if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
    {
        if(pMac->roam.configParam.IsIdleScanEnabled) 
        {
            if(HAL_STATUS_SUCCESS(status))
            {
                if(csrIsAllSessionDisconnected(pMac) && !csrIsRoamCommandWaiting(pMac))
                {
                    smsLog(pMac, LOGW, FL("starts idle mode full scan"));
                    csrScanAllChannels(pMac, eCSR_SCAN_IDLE_MODE_SCAN);
                }
                else
                {
                    smsLog(pMac, LOGW, FL("cannot start idle mode full scan"));
                    //even though we are in timer handle, calling stop timer will make sure the timer
                    //doesn't get to restart.
                    csrScanStopIdleScanTimer(pMac);
                }
            }
            else
            {
                smsLog(pMac, LOGE, FL("sees not success status (%d)"), status);
            }
        }
        else
        {//we might need another flag to check if CSR needs to request imps at all
       
            tANI_U32 nTime = 0;

            pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE;
            if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime)))
            {
                csrScanStartIdleScanTimer(pMac, nTime);
            }
        }
    }
}


//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for
//idle scan timer interval
//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan
eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval)
{
    eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE;

    //Do not trigger IMPS in case of concurrency
    if (vos_concurrent_open_sessions_running() &&
        csrIsAnySessionInConnectState(pMac))
    {
        smsLog( pMac, LOG1, FL("Cannot request IMPS because Concurrent Sessions Running") );
        return (status);
    }

    if(pTimeInterval)
    {
        *pTimeInterval = 0;
    }

    smsLog(pMac, LOG3, FL("called"));
    if( smeCommandPending( pMac ) )
    {
        smsLog( pMac, LOG1, FL("  Cannot request IMPS because command pending") );
        //Not to enter IMPS because more work to do
        if(pTimeInterval)
        {
            *pTimeInterval = 0;
        }
        //restart when ready
        pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;

        return (status);
    }
    if (IsPmcImpsReqFailed (pMac))
    {
        if(pTimeInterval)
        {
            *pTimeInterval = 1000000; //usec
        }
        //restart when ready
        pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;

        return status;
    }

    if ( !pMac->deferImps && pMac->fDeferIMPSTime )
    {
        smsLog( pMac, LOG1, FL("Defer IMPS for %dms as command processed"),
                pMac->fDeferIMPSTime);
        if(pTimeInterval)
        {
            *pTimeInterval = pMac->fDeferIMPSTime * 1000; //usec
        }
        pMac->deferImps = eANI_BOOLEAN_TRUE;
        return status;
    }

    if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) 
    /*&& pMac->roam.configParam.impsSleepTime*/)
    {
        //Stop get result timer because idle scan gets scan result out of PE
        csrScanStopGetResultTimer(pMac);
        if(pTimeInterval)
        {
            *pTimeInterval = pMac->roam.configParam.impsSleepTime;
        }
        //pmcRequestImps take a period in millisecond unit.
        status = pmcRequestImps(pMac, pMac->roam.configParam.impsSleepTime / PAL_TIMER_TO_MS_UNIT, csrScanIMPSCallback, pMac);
        if(!HAL_STATUS_SUCCESS(status))
        {
            if(eHAL_STATUS_PMC_ALREADY_IN_IMPS != status)
            {
                //Do restart the timer if CSR thinks it cannot do IMPS
                if( !csrCheckPSReady( pMac ) )
                {
                    if(pTimeInterval)
                    {
                    *pTimeInterval = 0;
                }
                    //Set the restart flag to true because that idle scan 
                    //can be restarted even though the timer will not be running
                    pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
                }
                else
                {
                    //For not now, we do a quicker retry
                    if(pTimeInterval)
                    {
                    *pTimeInterval = CSR_IDLE_SCAN_WAIT_TIME;
                }
            }
                smsLog(pMac, LOGW, FL("call pmcRequestImps and it returns status code (%d)"), status);
            }
            else
            {
                smsLog(pMac, LOGW, FL("already in IMPS"));
                //Since CSR is the only module to request for IMPS. If it is already in IMPS, CSR assumes
                //the callback will be called in the future. Should not happen though.
                status = eHAL_STATUS_SUCCESS;
                pMac->scan.nIdleScanTimeGap = 0;
            }
        }
        else
        {
            //requested so let's reset the value
            pMac->scan.nIdleScanTimeGap = 0;
        }
    }

    return (status);
}


eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE;
    tANI_U32 nTime = 0;

    smsLog(pMac, LOGW, FL("called"));
    if(pMac->roam.configParam.IsIdleScanEnabled)
    {
        //stop bg scan first
        csrScanBGScanAbort(pMac);
        //Stop get result timer because idle scan gets scan result out of PE
        csrScanStopGetResultTimer(pMac);
    }
    pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE;
    status = csrScanTriggerIdleScan(pMac, &nTime);
    if(!HAL_STATUS_SUCCESS(status))
    {
        csrScanStartIdleScanTimer(pMac, nTime);
    }

    return (status);
}


void csrScanCancelIdleScan(tpAniSirGlobal pMac)
{
    if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
    {
        if (vos_concurrent_open_sessions_running()) {
            return;
        }
        smsLog(pMac, LOG1, "  csrScanCancelIdleScan");
        pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE;
        //Set the restart flag in case later on it is uncancelled
        pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
        csrScanStopIdleScanTimer(pMac);
        csrScanRemoveNotRoamingScanCommand(pMac);
    }
}


void csrScanIdleScanTimerHandler(void *pv)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( pv );
    eHalStatus status;
    tANI_U32 nTime = 0;

    smsLog(pMac, LOGW, "  csrScanIdleScanTimerHandler called  ");
    pmcResetImpsFailStatus (pMac);
    status = csrScanTriggerIdleScan(pMac, &nTime);
    if(!HAL_STATUS_SUCCESS(status) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan))
    {
        //Check whether it is time to actually do an idle scan
        if(pMac->scan.nIdleScanTimeGap >= pMac->roam.configParam.impsSleepTime)
        {
            pMac->scan.nIdleScanTimeGap = 0;
            csrScanIMPSCallback(pMac, eHAL_STATUS_SUCCESS);
        }
        else
        {
            csrScanStartIdleScanTimer(pMac, nTime);
        }
    }
    if(pMac->deferImps)
    {
        pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
        pMac->deferImps = eANI_BOOLEAN_FALSE;
    }
}




tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
    tListElem *pEntry, *pEntryTmp;
    tSmeCmd *pCommand;
    tDblLinkList localList;
    tDblLinkList *pCmdList;

    vos_mem_zero(&localList, sizeof(tDblLinkList));
    if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
    {
        smsLog(pMac, LOGE, FL(" failed to open list"));
        return fRet;
    }
    if (!pMac->fScanOffload)
        pCmdList = &pMac->sme.smeCmdPendingList;
    else
        pCmdList = &pMac->sme.smeScanCmdPendingList;

    csrLLLock(pCmdList);
    pEntry = csrLLPeekHead(pCmdList, LL_ACCESS_NOLOCK);
    while(pEntry)
    {
        pEntryTmp = csrLLNext(pCmdList, pEntry, LL_ACCESS_NOLOCK);
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        if( eSmeCommandScan == pCommand->command )
        {
            switch( pCommand->u.scanCmd.reason )
            {
            case eCsrScanIdleScan:
                if( csrLLRemoveEntry(pCmdList, pEntry, LL_ACCESS_NOLOCK) )
                {
                    csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
                }
                fRet = eANI_BOOLEAN_TRUE;
                break;

            default:
                break;
            } //switch
        }
        pEntry = pEntryTmp;
    }

    csrLLUnlock(pCmdList);

    while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
    {
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        csrReleaseCommandScan( pMac, pCommand );
    }

    csrLLClose(&localList);

    return (fRet);
}


tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
    tListElem *pEntry, *pEntryTmp;
    tSmeCmd *pCommand;
    tDblLinkList localList;
    tDblLinkList *pCmdList;

    vos_mem_zero(&localList, sizeof(tDblLinkList));
    if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
    {
        smsLog(pMac, LOGE, FL(" failed to open list"));
        return fRet;
    }

    if (!pMac->fScanOffload)
        pCmdList = &pMac->sme.smeCmdPendingList;
    else
        pCmdList = &pMac->sme.smeScanCmdPendingList;

    csrLLLock(pCmdList);
    pEntry = csrLLPeekHead(pCmdList, LL_ACCESS_NOLOCK);
    while(pEntry)
    {
        pEntryTmp = csrLLNext(pCmdList, pEntry, LL_ACCESS_NOLOCK);
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        if( (eSmeCommandScan == pCommand->command) && (sessionId == pCommand->sessionId) )
        {
            switch(pCommand->u.scanCmd.reason)
            {
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
            case eCsrScanGetLfrResult:
#endif
            case eCsrScanGetResult:
            case eCsrScanSetBGScanParam:
            case eCsrScanBGScanAbort:
            case eCsrScanBGScanEnable:
            case eCsrScanGetScanChnInfo:
                break;
            default:
                 smsLog (pMac, LOGW, "%s: -------- abort scan command reason = %d",
                    __func__, pCommand->u.scanCmd.reason);
                //The rest are fresh scan requests
                if( csrLLRemoveEntry(pCmdList, pEntry, LL_ACCESS_NOLOCK) )
                {
                    csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
                }
                fRet = eANI_BOOLEAN_TRUE;
                break;
            }
        }
        pEntry = pEntryTmp;
    }

    csrLLUnlock(pCmdList);

    while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
    {
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        if (pCommand->u.scanCmd.callback)
        {
            /* User scan request is pending, 
                                 * send response with status eCSR_SCAN_ABORT*/
            pCommand->u.scanCmd.callback(pMac, 
                     pCommand->u.scanCmd.pContext, 
                     pCommand->u.scanCmd.scanID, 
                     eCSR_SCAN_ABORT);
        }
        csrReleaseCommandScan( pMac, pCommand );
    }
    csrLLClose(&localList);

    return (fRet);
}


void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus)
{
    eCsrScanReason reason = pCommand->u.scanCmd.reason;
    tANI_BOOLEAN status;

    if (!pMac->fScanOffload)
    {
        tANI_U32 i;
        for(i = 0; i < CSR_ROAM_SESSION_MAX; i++)
            csrRoamStateChange(pMac,
              pMac->roam.prev_state[i], i);
    }
    else
    {
        csrRoamStateChange(pMac,
                pMac->roam.prev_state[pCommand->sessionId],
                pCommand->sessionId);
    }

    csrScanCallCallback(pMac, pCommand, scanStatus);

    smsLog(pMac, LOG3, "   Remove Scan command reason = %d", reason);
    if (pMac->fScanOffload)
    {
        status = csrLLRemoveEntry(&pMac->sme.smeScanCmdActiveList,
                                  &pCommand->Link, LL_ACCESS_LOCK);
    }
    else
    {
        status = csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
                                  &pCommand->Link, LL_ACCESS_LOCK);
    }

    if(status)
    {
        csrReleaseCommandScan( pMac, pCommand );
    }
    else
    {
        smsLog(pMac, LOGE,
                " ********csrReleaseScanCommand cannot release command reason %d",
                pCommand->u.scanCmd.reason );
    }
}


eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId,
                                        tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, "  pMac->scan.NumPmkidCandidate = %d", pSession->NumPmkidCandidate);
    csrResetPMKIDCandidateList(pMac, sessionId);
    if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile)
    {
        tCsrScanResultFilter *pScanFilter;
        tCsrScanResultInfo *pScanResult;
        tScanResultHandle hBSSList;
        tANI_U32 nItems = *pNumItems;

        *pNumItems = 0;
        pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
        if ( NULL == pScanFilter )
           status = eHAL_STATUS_FAILURE;
        else
        {
            vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
            //Here is the profile we need to connect to
            status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
            if(HAL_STATUS_SUCCESS(status))
            {
                status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
                if(HAL_STATUS_SUCCESS(status))
                {
                    while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumPmkidCandidate < nItems))
                    {
                        //NumPmkidCandidate adds up here
                        csrProcessBSSDescForPMKIDList(pMac, &pScanResult->BssDescriptor, 
                                                      (tDot11fBeaconIEs *)( pScanResult->pvIes ));
                    }
                    if(pSession->NumPmkidCandidate)
                    {
                        *pNumItems = pSession->NumPmkidCandidate;
                        vos_mem_copy(pPmkidList, pSession->PmkidCandidateInfo,
                                     pSession->NumPmkidCandidate * sizeof(tPmkidCandidateInfo));
                    }
                    csrScanResultPurge(pMac, hBSSList);
                }//Have scan result
                csrFreeScanFilter(pMac, pScanFilter);
            }
            vos_mem_free(pScanFilter);
        }
    }

    return (status);
}



#ifdef FEATURE_WLAN_WAPI
eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId,
                                       tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    smsLog(pMac, LOGW, "  pMac->scan.NumBkidCandidate = %d", pSession->NumBkidCandidate);
    csrResetBKIDCandidateList(pMac, sessionId);
    if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile)
    {
        tCsrScanResultFilter *pScanFilter;
        tCsrScanResultInfo *pScanResult;
        tScanResultHandle hBSSList;
        tANI_U32 nItems = *pNumItems;
        *pNumItems = 0;
        pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
        if ( NULL == pScanFilter )
            status = eHAL_STATUS_FAILURE;
        else
        {
            vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
            //Here is the profile we need to connect to
            status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
            if(HAL_STATUS_SUCCESS(status))
            {
                status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
                if(HAL_STATUS_SUCCESS(status))
                {
                    while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumBkidCandidate < nItems))
                    {
                        //pMac->scan.NumBkidCandidate adds up here
                        csrProcessBSSDescForBKIDList(pMac, &pScanResult->BssDescriptor,
                              (tDot11fBeaconIEs *)( pScanResult->pvIes ));

                    }
                    if(pSession->NumBkidCandidate)
                    {
                        *pNumItems = pSession->NumBkidCandidate;
                        vos_mem_copy(pBkidList, pSession->BkidCandidateInfo, pSession->NumBkidCandidate * sizeof(tBkidCandidateInfo));
                    }
                    csrScanResultPurge(pMac, hBSSList);
                }//Have scan result
            }
            vos_mem_free(pScanFilter);
        }
    }

    return (status);
}
#endif /* FEATURE_WLAN_WAPI */

/**
 * csr_scan_request_set_chan_time() - Populate max and min
 *                            channel time in Scan request
 * @pMac - pointer to mac context
 * @pScanCmd - pointer to the Scan command
 *
 * Return - None
 */
#ifndef QCA_WIFI_ISOC
static void csr_scan_request_set_chan_time(tpAniSirGlobal pMac,
						tSmeCmd *pScanCmd)
{
	if (pMac->roam.neighborRoamInfo.handoffReqInfo.src
							== FASTREASSOC) {
		pScanCmd->u.scanCmd.u.scanRequest.maxChnTime
			= MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC;
		pScanCmd->u.scanCmd.u.scanRequest.minChnTime
			= MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC;
		pMac->roam.neighborRoamInfo.handoffReqInfo.src = 0;
	} else {
		pScanCmd->u.scanCmd.u.scanRequest.maxChnTime
			= MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL;
		pScanCmd->u.scanCmd.u.scanRequest.minChnTime
			= MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL;
	}
}
#else
static void csr_scan_request_set_chan_time(tpAniSirGlobal pMac,
						tSmeCmd *pScanCmd)
{
	pScanCmd->u.scanCmd.u.scanRequest.maxChnTime
			= MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL;
	pScanCmd->u.scanCmd.u.scanRequest.minChnTime
			= MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL;
}
#endif

/**
 * csr_ssid_scan_done_callback() - Callback to indicate
 *                            scan is done for ssid scan
 * @halHandle: handle to hal
 * @context: SSID scan context
 * @scanId: Scan id for the scheduled scan
 * @status: scan done status
 *
 * Return - eHalStatus
 */
static eHalStatus csr_ssid_scan_done_callback(tHalHandle halHandle,
                                              void *context,
                                              tANI_U32 scanId,
                                              eCsrScanStatus status)
{
    struct csr_scan_for_ssid_context *scan_context =
                    (struct csr_scan_for_ssid_context *)context;

    if (NULL == scan_context) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("scan for ssid context not found"));
        return eHAL_STATUS_FAILURE;
    }

    if (eCSR_SCAN_ABORT == status)
        csrRoamCallCallback(scan_context->pMac, scan_context->sessionId,
                            NULL, scan_context->roamId,
                            eCSR_ROAM_ASSOCIATION_FAILURE,
                            eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE);
    vos_mem_free(scan_context);
    return eHAL_STATUS_SUCCESS;
}

//This function is usually used for BSSs that suppresses SSID so the profile 
//shall have one and only one SSID
eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    tSmeCmd *pScanCmd = NULL;
    tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
    tANI_U8  index = 0;
    tANI_U32 numSsid = pProfile->SSIDs.numOfSSIDs;
    struct csr_scan_for_ssid_context *context;

    smsLog(pMac, LOG2, FL("called"));
    //For WDS, we use the index 0. There must be at least one in there
    if( CSR_IS_WDS_STA( pProfile ) && numSsid )
    {
        numSsid = 1;
    }
    if(pMac->scan.fScanEnable && ( numSsid == 1 ) )
    {
        do
        {
            pScanCmd = csrGetCommandBuffer(pMac);
            if(!pScanCmd)
            {
                smsLog(pMac, LOGE, FL("failed to allocate command buffer"));
                break;
            }
            vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
            pScanCmd->u.scanCmd.pToRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile));
            if ( NULL == pScanCmd->u.scanCmd.pToRoamProfile )
            {
                status = eHAL_STATUS_FAILURE;
            }
            else
            {
                status = csrRoamCopyProfile(pMac, pScanCmd->u.scanCmd.pToRoamProfile, pProfile);
            }
            context = vos_mem_malloc(sizeof(*context));
            if (NULL == context)
            {
                smsLog(pMac, LOGE,
                       "Failed to allocate memory for ssid scan context");
                status = eHAL_STATUS_FAILED_ALLOC;
            }
            if(!HAL_STATUS_SUCCESS(status))
                break;
            context->pMac = pMac;
            context->sessionId = sessionId;
            context->roamId = roamId;
            pScanCmd->u.scanCmd.roamId = roamId;
            pScanCmd->command = eSmeCommandScan;
            pScanCmd->sessionId = (tANI_U8)sessionId;
            pScanCmd->u.scanCmd.callback = csr_ssid_scan_done_callback;
            pScanCmd->u.scanCmd.pContext = context;
            pScanCmd->u.scanCmd.reason = eCsrScanForSsid;//Need to check: might need a new reason for SSID scan for LFR during multisession with p2p
            pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
            vos_mem_set(&pScanCmd->u.scanCmd.u.scanRequest, sizeof(tCsrScanRequest), 0);
            pScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
            pScanCmd->u.scanCmd.u.scanRequest.BSSType = pProfile->BSSType;
            // To avoid 11b rate in probe request Set p2pSearch flag as 1 for P2P Client Mode
            if(VOS_P2P_CLIENT_MODE == pProfile->csrPersona)
            {
                pScanCmd->u.scanCmd.u.scanRequest.p2pSearch = 1;
            }
            if(pProfile->nAddIEScanLength)
            {
                pScanCmd->u.scanCmd.u.scanRequest.pIEField = vos_mem_malloc(
                                                    pProfile->nAddIEScanLength);
                if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.pIEField )
                    status = eHAL_STATUS_FAILURE;
                else
                    status = eHAL_STATUS_SUCCESS;
                vos_mem_set(pScanCmd->u.scanCmd.u.scanRequest.pIEField,
                            pProfile->nAddIEScanLength, 0);
                if (HAL_STATUS_SUCCESS(status))
                {
                    vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.pIEField,
                                 pProfile->addIEScan, pProfile->nAddIEScanLength);
                    pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = pProfile->nAddIEScanLength;
                }
                else
                {
                    smsLog(pMac, LOGE, "No memory for scanning IE fields");
                }
            } //Allocate memory for IE field
            else
            {
                pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = 0;
            }
            /* For one channel be good enpugh time to receive beacon atleast */
            if(  1 == pProfile->ChannelInfo.numOfChannels )
            {
                 csr_scan_request_set_chan_time(pMac, pScanCmd);
            } else {
                 pScanCmd->u.scanCmd.u.scanRequest.maxChnTime =
                                   pMac->roam.configParam.nActiveMaxChnTime;
                 pScanCmd->u.scanCmd.u.scanRequest.minChnTime =
                                   pMac->roam.configParam.nActiveMinChnTime;
            }
            pScanCmd->u.scanCmd.u.scanRequest.max_chntime_btc_esco =
                                   pMac->roam.configParam.max_chntime_btc_esco;
            pScanCmd->u.scanCmd.u.scanRequest.min_chntime_btc_esco =
                                   pMac->roam.configParam.min_chntime_btc_esco;
            if(pProfile->BSSIDs.numOfBSSIDs == 1)
            {
                vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.bssid,
                             pProfile->BSSIDs.bssid, sizeof(tCsrBssid));
            }
            else
            {
                vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.bssid, bAddr, 6);
            }
            if(pProfile->ChannelInfo.numOfChannels)
            {
                pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(
                                 sizeof(*pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
                                 * pProfile->ChannelInfo.numOfChannels);
                if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList )
                    status = eHAL_STATUS_FAILURE;
                else
                    status = eHAL_STATUS_SUCCESS;
                pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0;
                if(HAL_STATUS_SUCCESS(status))
                {
                  csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[0]);
                  for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++)
                  {
                     if(csrRoamIsValidChannel(pMac, pProfile->ChannelInfo.ChannelList[index]))
                     {
                        pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels] 
                           = pProfile->ChannelInfo.ChannelList[index];
                        pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels++;
                     }
                     else 
                     {
                         smsLog(pMac, LOGW, FL("process a channel (%d) that is invalid"), pProfile->ChannelInfo.ChannelList[index]);
                     }

                  }
               }
               else
                {
                    break;
                }

            }
            else
            {
                pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0;
            }
            if(pProfile->SSIDs.numOfSSIDs)
            {
                pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList = vos_mem_malloc(
                                     pProfile->SSIDs.numOfSSIDs * sizeof(tCsrSSIDInfo));
                if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList )
                    status = eHAL_STATUS_FAILURE;
                else
                    status = eHAL_STATUS_SUCCESS;
                if(!HAL_STATUS_SUCCESS(status))
                {
                    break;
                }
                pScanCmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1;
                vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList,
                             pProfile->SSIDs.SSIDList, sizeof(tCsrSSIDInfo));
            }
            //Start process the command
            status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                break;
            }
        }while(0);
        if(!HAL_STATUS_SUCCESS(status))
        {
            if(pScanCmd)
            {
                csrReleaseCommandScan(pMac, pScanCmd);
                //TODO:free the memory that is allocated in this function
            }
            if(notify)
            {
            csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
        }
        }
    }//valid
    else
    {
        smsLog(pMac, LOGE, FL("cannot scan because scanEnable (%d) or numSSID (%d) is invalid"),
                pMac->scan.fScanEnable, pProfile->SSIDs.numOfSSIDs);
    }
    
    return (status);
}


//Issue a scan base on the new capability infomation
//This should only happen when the associated AP changes its capability.
//After this scan is done, CSR reroams base on the new scan results
eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    tSmeCmd *pScanCmd = NULL;

    if(pNewCaps)
    {
        do
        {
            pScanCmd = csrGetCommandBuffer(pMac);
            if(!pScanCmd)
            {
                smsLog(pMac, LOGE, FL("failed to allocate command buffer"));
                status = eHAL_STATUS_RESOURCES;
                break;
            }
            vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0);
            status = eHAL_STATUS_SUCCESS;
            pScanCmd->u.scanCmd.roamId = 0;
            pScanCmd->command = eSmeCommandScan; 
            pScanCmd->u.scanCmd.callback = NULL;
            pScanCmd->u.scanCmd.pContext = NULL;
            pScanCmd->u.scanCmd.reason = eCsrScanForCapsChange;
            pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
            status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
            if( !HAL_STATUS_SUCCESS( status ) )
            {
                smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status );
                break;
            }
        }while(0);
        if(!HAL_STATUS_SUCCESS(status))
        {
            if(pScanCmd)
            {
                csrReleaseCommandScan(pMac, pScanCmd);
            }
        }    
    }

    return (status);
}



void csrInitBGScanChannelList(tpAniSirGlobal pMac)
{
    tANI_U32 len = CSR_MIN(sizeof(pMac->roam.validChannelList), sizeof(pMac->scan.bgScanChannelList));

    vos_mem_set(pMac->scan.bgScanChannelList, len, 0);
    pMac->scan.numBGScanChannel = 0;

    if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
    {
        pMac->roam.numValidChannels = len;
        pMac->scan.numBGScanChannel = (tANI_U8)CSR_MIN(len, WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN);
        vos_mem_copy(pMac->scan.bgScanChannelList, pMac->roam.validChannelList,
                     pMac->scan.numBGScanChannel);
        csrSetBGScanChannelList(pMac, pMac->scan.bgScanChannelList, pMac->scan.numBGScanChannel);
    }
}


//This function return TRUE if background scan channel list is adjusted. 
//this function will only shrink the background scan channel list
tANI_BOOLEAN csrAdjustBGScanChannelList(tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels,
                                        tANI_U8 *pAdjustChannels, tANI_U8 *pNumAdjustChannels)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
    tANI_U8 i, j, count = *pNumAdjustChannels;

    i = 0;
    while(i < count)
    {
        for(j = 0; j < NumChannels; j++)
        {
            if(pChannelList[j] == pAdjustChannels[i])
                break;
        }
        if(j == NumChannels)
        {
            //This channel is not in the list, remove it
            fRet = eANI_BOOLEAN_TRUE;
            count--;
            if(count - i)
            {
                vos_mem_copy(&pAdjustChannels[i], &pAdjustChannels[i+1], count - i);
            }
            else
            {
                //already remove the last one. Done.
                break;
            }
        }
        else
        {
            i++;
        }
    }//while(i<count)
    *pNumAdjustChannels = count;

    return (fRet);
}


//Get the list of the base channels to scan for passively 11d info
eHalStatus csrScanGetSupportedChannels( tpAniSirGlobal pMac )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    int n = WNI_CFG_VALID_CHANNEL_LIST_LEN;

    status = vos_nv_getSupportedChannels( pMac->scan.baseChannels.channelList, &n, NULL, NULL );
    if( HAL_STATUS_SUCCESS(status) )
    {
        pMac->scan.baseChannels.numChannels = (tANI_U8)n;
    }
    else
    {
        smsLog( pMac, LOGE, FL(" failed") );
        pMac->scan.baseChannels.numChannels = 0;
    }
    
    return ( status );
}

//This function use the input pChannelList to validate the current saved channel list
eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels)
{
    tANI_U32 dataLen = sizeof( tANI_U8 ) * NumAdjustChannels;

    return (ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pAdjustChannels, dataLen, NULL, eANI_BOOLEAN_FALSE));
}


void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels )
{
    tANI_U32 dataLen = sizeof( tANI_U8 ) * NumChannels;
    eHalStatus status;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                "%s: dump valid channel list(NumChannels(%d))",
                __func__,NumChannels);
    VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                       pChannelList, NumChannels);

    ccmCfgSetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE);
#ifdef QCA_WIFI_2_0
    if (pMac->fScanOffload)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                "Scan offload is enabled, update default chan list");
        status = csrUpdateChannelList(pMac);
    }
#else
    status = csrUpdateChannelList(pMac);
#endif

    if (eHAL_STATUS_SUCCESS != status)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "failed to update the supported channel list");
    }
    return;
}



/*
 * The Tx power limits are saved in the cfg for future usage.
 */
void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId )
{
    tListElem *pEntry;
    tANI_U32 cbLen = 0, dataLen;
    tCsrChannelPowerInfo *pChannelSet;
    tANI_U32 idx;
    tSirMacChanInfo *pChannelPowerSet;
    tANI_U8 *pBuf = NULL;

    //allocate maximum space for all channels
    dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo);
    if ( (pBuf = vos_mem_malloc(dataLen)) != NULL )
    {
        vos_mem_set(pBuf, dataLen, 0);
        pChannelPowerSet = (tSirMacChanInfo *)(pBuf);

        pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
        // write the tuples (startChan, numChan, txPower) for each channel found in the channel power list.
        while( pEntry )
        {
            pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
            if ( 1 != pChannelSet->interChannelOffset )
            {
                // we keep the 5G channel sets internally with an interchannel offset of 4.  Expand these
                // to the right format... (inter channel offset of 1 is the only option for the triplets
                // that 11d advertises.
                if ((cbLen + (pChannelSet->numChannels * sizeof(tSirMacChanInfo))) >= dataLen)
                {
                    // expanding this entry will overflow our allocation
                    smsLog(pMac, LOGE,
                           "%s: Buffer overflow, start %d, num %d, offset %d",
                           __func__,
                           pChannelSet->firstChannel,
                           pChannelSet->numChannels,
                           pChannelSet->interChannelOffset);
                    break;
                }

                for( idx = 0; idx < pChannelSet->numChannels; idx++ )
                {
                    pChannelPowerSet->firstChanNum = (tSirMacChanNum)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset ));
                    smsLog(pMac, LOG3, " Setting Channel Number %d", pChannelPowerSet->firstChanNum);
                    pChannelPowerSet->numChannels  = 1;
                    pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap );
                    smsLog(pMac, LOG3, " Setting Max Transmit Power %d", pChannelPowerSet->maxTxPower);
                    cbLen += sizeof( tSirMacChanInfo );
                    pChannelPowerSet++;
                }
            }
            else
            {
                if (cbLen >= dataLen)
                {
                    // this entry will overflow our allocation
                    smsLog(pMac, LOGE,
                           "%s: Buffer overflow, start %d, num %d, offset %d",
                           __func__,
                           pChannelSet->firstChannel,
                           pChannelSet->numChannels,
                           pChannelSet->interChannelOffset);
                    break;
                }
                pChannelPowerSet->firstChanNum = pChannelSet->firstChannel;
                smsLog(pMac, LOG3, " Setting Channel Number %d", pChannelPowerSet->firstChanNum);
                pChannelPowerSet->numChannels = pChannelSet->numChannels;
                pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap );
                smsLog(pMac, LOG3, " Setting Max Transmit Power %d, nTxPower %d", pChannelPowerSet->maxTxPower,pMac->roam.configParam.nTxPowerCap );


                cbLen += sizeof( tSirMacChanInfo );
                pChannelPowerSet++;
            }

            pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK );
        }

        if(cbLen)
        {
            ccmCfgSetStr(pMac, cfgId, (tANI_U8 *)pBuf, cbLen, NULL, eANI_BOOLEAN_FALSE); 
        }
        vos_mem_free(pBuf);
    }//Allocate memory
}


void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode )
{
    tANI_U8 cc[WNI_CFG_COUNTRY_CODE_LEN];
    ///v_REGDOMAIN_t DomainId;
    
    smsLog( pMac, LOG3, "Setting Country Code in Cfg from csrSetCfgCountryCode %s",countryCode );
    vos_mem_copy(cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN);

    // don't program the bogus country codes that we created for Korea in the MAC.  if we see
    // the bogus country codes, program the MAC with the right country code.
    if ( ( 'K'  == countryCode[ 0 ] && '1' == countryCode[ 1 ]  ) ||
         ( 'K'  == countryCode[ 0 ] && '2' == countryCode[ 1 ]  ) ||
         ( 'K'  == countryCode[ 0 ] && '3' == countryCode[ 1 ]  ) ||
         ( 'K'  == countryCode[ 0 ] && '4' == countryCode[ 1 ]  )    )
    {
        // replace the alternate Korea country codes, 'K1', 'K2', .. with 'KR' for Korea
        cc[ 1 ] = 'R';
    }
    ccmCfgSetStr(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN, NULL, eANI_BOOLEAN_FALSE);

    //Need to let HALPHY know about the current domain so it can apply some 
    //domain-specific settings (TX filter...)
    /*if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, cc, &DomainId)))
    {
        halPhySetRegDomain(pMac, DomainId);
    }*/
}



eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    tANI_U32 len;

    if(pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN))
    {
        len = *pbLen;
        status = ccmCfgGetStr(pMac, WNI_CFG_COUNTRY_CODE, pBuf, &len);
        if(HAL_STATUS_SUCCESS(status))
        {
            *pbLen = (tANI_U8)len;
        }
    }
    
    return (status);
}


void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList  )
{   
    tANI_U8 i, j, k;
    tANI_BOOLEAN found=FALSE;  
    tANI_U8 *pControlList = NULL;
    tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
    tANI_U8 cfgActiveDFSChannels = 0;
    tANI_U8 *cfgActiveDFSChannelLIst = NULL;

    if ( (pControlList = vos_mem_malloc(WNI_CFG_SCAN_CONTROL_LIST_LEN)) != NULL )
    {
        vos_mem_set((void *)pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN, 0);
        if(HAL_STATUS_SUCCESS(ccmCfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, &len)))
        {
            for (i = 0; i < pChannelList->numChannels; i++)
            {
                for (j = 0; j < len; j += 2) 
                {
                    if (pControlList[j] == pChannelList->channelList[i]) 
                    {
                        found = TRUE;
                        break;
                    }
                }
                   
                if (found)    // insert a pair(channel#, flag)
                {
                    pControlList[j+1] = csrGetScanType(pMac, pControlList[j]);
                    found = FALSE;  // reset the flag

                    // When DFS mode is 2, mark static channels as active
                    if (pMac->scan.fEnableDFSChnlScan ==
                                   DFS_CHNL_SCAN_ENABLED_ACTIVE)
                    {
                        cfgActiveDFSChannels =
                          pMac->roam.neighborRoamInfo.cfgParams.
                                               channelInfo.numOfChannels;
                        cfgActiveDFSChannelLIst =
                          pMac->roam.neighborRoamInfo.cfgParams.
                                               channelInfo.ChannelList;
                        if (cfgActiveDFSChannelLIst)
                        {
                           for (k=0; k < cfgActiveDFSChannels; k++)
                           {
                               if(CSR_IS_CHANNEL_DFS(cfgActiveDFSChannelLIst[k])
                                   && (pControlList[j] ==
                                                  cfgActiveDFSChannelLIst[k]))
                               {
                                   pControlList[j+1] = eSIR_ACTIVE_SCAN;
                                   smsLog(pMac, LOG1, FL("Marked DFS ch %d"
                                          " as active"),
                                          cfgActiveDFSChannelLIst[k]);
                               }
                           }
                        }
                    }
                }
            }
            smsLog(pMac, LOG1, FL("fEnableDFSChnlScan %d"),
                                       pMac->scan.fEnableDFSChnlScan);
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                      "%s: dump scan control list",__func__);
            VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                               pControlList, len);

            ccmCfgSetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, len, NULL, eANI_BOOLEAN_FALSE);
        }//Successfully getting scan control list
        vos_mem_free(pControlList);
    }//AllocateMemory

    /* Send msg to Lim to clear DFS channel list */
    smsLog(pMac, LOG1, FL("csrClearDfsChannelList"));
    csrClearDfsChannelList(pMac);
}

//if bgPeriod is 0, background scan is disabled. It is in millisecond units
eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod)
{
    return (ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, bgPeriod, (tCcmCfgSetCallback) csrScanCcmCfgSetCallback, eANI_BOOLEAN_FALSE));
}
    

void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result)
{
    tListElem *pEntry = NULL;
    tSmeCmd *pCommand = NULL;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tDblLinkList *pCmdList ;

    if (!pMac->fScanOffload)
        pCmdList = &pMac->sme.smeCmdActiveList;
    else
        pCmdList = &pMac->sme.smeScanCmdActiveList;

    pEntry = csrLLPeekHead( pCmdList, LL_ACCESS_LOCK );
    if ( pEntry )
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        if ( eSmeCommandScan == pCommand->command )
        {
            eCsrScanStatus scanStatus = (CCM_IS_RESULT_SUCCESS(result)) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
            csrReleaseScanCommand(pMac, pCommand, scanStatus);
        }
        else
        {
            smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." );
        }
    }   
    smeProcessPendingQueue( pMac );
}

eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
{
    eHalStatus status;
    tCsrBGScanRequest *pScanReq = &pCommand->u.scanCmd.u.bgScanRequest;
    tANI_U32 dataLen = sizeof( tANI_U8 ) * pScanReq->ChannelInfo.numOfChannels;
        
    //***setcfg for background scan channel list
    status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, pScanReq->minChnTime, NULL, eANI_BOOLEAN_FALSE);
    status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, pScanReq->maxChnTime, NULL, eANI_BOOLEAN_FALSE);
    //Not set the background scan interval if not connected because bd scan should not be run if not connected
    if(!csrIsAllSessionDisconnected(pMac))
    {

#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
        {
            vos_log_scan_pkt_type *pScanLog = NULL;

            WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
            if(pScanLog)
            {
                pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
                pScanLog->minChnTime = (v_U8_t)pScanReq->minChnTime;
                pScanLog->maxChnTime = (v_U8_t)pScanReq->maxChnTime;
                pScanLog->timeBetweenBgScan = (v_U8_t)pScanReq->scanInterval;
                pScanLog->numChannel = pScanReq->ChannelInfo.numOfChannels;
                if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL))
                {
                    vos_mem_copy(pScanLog->channels,
                                 pScanReq->ChannelInfo.ChannelList,
                                 pScanLog->numChannel);
                }
                WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
            }
        }
#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR

        status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, pScanReq->scanInterval, NULL, eANI_BOOLEAN_FALSE);
    }
    else
    {
        //No need to stop aging because IDLE scan is still running
        status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, 0, NULL, eANI_BOOLEAN_FALSE);
    }
    
    if(pScanReq->SSID.length > WNI_CFG_SSID_LEN)
    {
        pScanReq->SSID.length = WNI_CFG_SSID_LEN;
    }
    
    status = ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pScanReq->ChannelInfo.ChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE);
    status = ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pScanReq->SSID.ssId, pScanReq->SSID.length, NULL, eANI_BOOLEAN_FALSE);



    return (status);
}


tSirAbortScanStatus csrScanAbortMacScan(tpAniSirGlobal pMac,
                                        tANI_U8 sessionId,
                                        eCsrAbortReason reason)
{
    tSirAbortScanStatus abortScanStatus = eSIR_ABORT_ACTIVE_SCAN_LIST_EMPTY;
    tSirSmeScanAbortReq *pMsg;
    tANI_U16 msgLen;
    tListElem *pEntry;
    tSmeCmd *pCommand;

    if (!pMac->fScanOffload)
    {
#ifdef WLAN_AP_STA_CONCURRENCY
        csrLLLock(&pMac->scan.scanCmdPendingList);
        while(NULL !=
               (pEntry = csrLLRemoveHead(&pMac->scan.scanCmdPendingList,
                                LL_ACCESS_NOLOCK)))
        {

            pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
            csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
        }
        csrLLUnlock(&pMac->scan.scanCmdPendingList);
#endif

        pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
        csrRemoveCmdFromPendingList( pMac, &pMac->roam.roamCmdPendingList, eSmeCommandScan);
        csrRemoveCmdFromPendingList( pMac, &pMac->sme.smeCmdPendingList, eSmeCommandScan);
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;

        pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
    }
    else
    {
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
        csrRemoveCmdWithSessionIdFromPendingList(pMac,
                sessionId,
                &pMac->sme.smeScanCmdPendingList,
                eSmeCommandScan);
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;

        pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK);
    }

    //We need to abort scan only if we are scanning
    if(NULL != pEntry)
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        if(eSmeCommandScan == pCommand->command &&
           pCommand->sessionId == sessionId)
        {
            msgLen = (tANI_U16)(sizeof(tSirSmeScanAbortReq));
            pMsg = vos_mem_malloc(msgLen);
            if ( NULL == pMsg )
            {
               smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq"));
               abortScanStatus = eSIR_ABORT_SCAN_FAILURE;
            }
            else
            {
                pCommand->u.scanCmd.abortScanIndication = eCSR_SCAN_ABORT_DEFAULT;
                if(reason == eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE)
                {
                    pCommand->u.scanCmd.abortScanIndication
                        = eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE;
                }
                vos_mem_set((void *)pMsg, msgLen, 0);
                pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND);
                pMsg->msgLen = pal_cpu_to_be16(msgLen);
                pMsg->sessionId = sessionId;
                if (eHAL_STATUS_SUCCESS != palSendMBMessage(pMac->hHdd, pMsg))
                {
                    smsLog(pMac, LOGE,
                           FL("Failed to post eWNI_SME_SCAN_ABORT_IND"));
                    abortScanStatus = eSIR_ABORT_SCAN_FAILURE;
                    pCommand->u.scanCmd.abortScanIndication = 0;
                }
                else
                {
                    abortScanStatus = eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY;
                }
            }
        }
    }

    return(abortScanStatus);
}

void csrRemoveCmdWithSessionIdFromPendingList(tpAniSirGlobal pMac,
                                              tANI_U8 sessionId,
                                              tDblLinkList *pList,
                                              eSmeCommandType commandType)
{
    tDblLinkList localList;
    tListElem *pEntry;
    tSmeCmd   *pCommand;
    tListElem  *pEntryToRemove;

    vos_mem_zero(&localList, sizeof(tDblLinkList));
    if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
    {
        smsLog(pMac, LOGE, FL(" failed to open list"));
        return;
    }

    csrLLLock(pList);
    if ((pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK)))
    {

        /* Have to make sure we don't loop back to the head of the list,
         * which will happen if the entry is NOT on the list */
        while (pEntry)
        {
            pEntryToRemove = pEntry;
            pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
            pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link );
            if ((pCommand->command == commandType)  &&
                    (pCommand->sessionId == sessionId))
            {
                /* Remove that entry only */
                if (csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK))
                {
                    csrLLInsertTail(&localList, pEntryToRemove,
                                    LL_ACCESS_NOLOCK);
                }
            }
        }
    }
    csrLLUnlock(pList);

    while ((pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)))
    {
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        csrAbortCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
    }

    csrLLClose(&localList);
}

void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList,
                                 eSmeCommandType commandType )
{
    tDblLinkList localList;
    tListElem *pEntry;
    tSmeCmd   *pCommand;
    tListElem  *pEntryToRemove;

    vos_mem_zero(&localList, sizeof(tDblLinkList));
    if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
    {
        smsLog(pMac, LOGE, FL(" failed to open list"));
        return;
    }

    csrLLLock(pList);
    if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) )
    {
        pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK);

        // Have to make sure we don't loop back to the head of the list, which will
        // happen if the entry is NOT on the list...
        while( pEntry )
        {
            pEntryToRemove = pEntry;
            pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
            pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link );
            if ( pCommand->command == commandType )
            {
                // Remove that entry only
                if(csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK))
                {
                    csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK);
                }
            }
        }


    }
    csrLLUnlock(pList);

    while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
    }
    csrLLClose(&localList);

}

eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirSmeScanAbortReq *pMsg;
    tANI_U16 msgLen;
    tListElem *pEntry;
    tSmeCmd *pCommand;

    if (!pMac->fScanOffload)
    {
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
#ifdef WLAN_AP_STA_CONCURRENCY
        csrRemoveScanForSSIDFromPendingList( pMac, &pMac->scan.scanCmdPendingList, sessionId);
#endif
        csrRemoveScanForSSIDFromPendingList( pMac, &pMac->roam.roamCmdPendingList, sessionId);
        csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeCmdPendingList, sessionId);
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;
        pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
    }
    else
    {
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
        csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeScanCmdPendingList, sessionId);
        pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;
        pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK);
    }

    if(NULL != pEntry)
    {
       pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );

       if ( (eSmeCommandScan == pCommand->command ) &&
                        (sessionId == pCommand->sessionId))
       {
          if ( eCsrScanForSsid == pCommand->u.scanCmd.reason)
          {
             msgLen = (tANI_U16)(sizeof( tSirSmeScanAbortReq ));
             pMsg = vos_mem_malloc(msgLen);
             if ( NULL == pMsg )
             {
                status = eHAL_STATUS_FAILURE;
                smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq"));
             }
             else
             {
                vos_mem_zero((void *)pMsg, msgLen);
                pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND);
                pMsg->msgLen = pal_cpu_to_be16(msgLen);
                pMsg->sessionId = sessionId;
                status = palSendMBMessage(pMac->hHdd, pMsg);
             }
          }
       }
    }
    return( status );
}

void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId)
{
    tDblLinkList localList;
    tListElem *pEntry;
    tSmeCmd   *pCommand;
    tListElem  *pEntryToRemove;

    vos_mem_zero(&localList, sizeof(tDblLinkList));
    if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
    {
        smsLog(pMac, LOGE, FL(" failed to open list"));
        return;
    }

    csrLLLock(pList);
    if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) )
    {
        pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK);

        // Have to make sure we don't loop back to the head of the list, which will
        // happen if the entry is NOT on the list...
        while( pEntry )
        {
            pEntryToRemove = pEntry;
            pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
            pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link );
            if ( (eSmeCommandScan == pCommand->command ) &&
                             (sessionId == pCommand->sessionId) )
            {
               if ( eCsrScanForSsid == pCommand->u.scanCmd.reason)
               {
                 // Remove that entry only
                 if ( csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK))
                 {
                    csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK);
                 }
               }
            }
        }
    }
    csrLLUnlock(pList);

    while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
    {
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
    }
    csrLLClose(&localList);
}

eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac,
                                            tANI_U8 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;

    if( !csrIsScanForRoamCommandActive( pMac ) )
    {
        //Only abort the scan if it is not used for other roam/connect purpose
        if (eSIR_ABORT_SCAN_FAILURE ==
                csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT))
        {
            smsLog(pMac, LOGE, FL("fail to abort scan"));
            status = eHAL_STATUS_FAILURE;
        }
    }

    return (status);
}


eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirMbMsg *pMsg;
    tANI_U16 msgLen;

    if (pMac->fScanOffload)
        msgLen = (tANI_U16)(sizeof(tSirSmeGetScanChanReq));
    else
        msgLen = (tANI_U16)(sizeof(tSirMbMsg));

    pMsg = vos_mem_malloc(msgLen);
    if ( NULL == pMsg )
        status = eHAL_STATUS_FAILURE;
    else
    {
        vos_mem_set(pMsg, msgLen, 0);
        pMsg->type = eWNI_SME_GET_SCANNED_CHANNEL_REQ;
        pMsg->msgLen = msgLen;
        if (pMac->fScanOffload)
            ((tSirSmeGetScanChanReq *)pMsg)->sessionId = sessionId;
        status = palSendMBMessage(pMac->hHdd, pMsg);
    }                             

    return( status );
}

tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel )
{
    tANI_BOOLEAN fValid = FALSE;
    tANI_U32 idxValidChannels;
    tANI_U32 len = pMac->roam.numValidChannels;
    
    for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ )
    {
       if ( channel == pMac->roam.validChannelList[ idxValidChannels ] )
       {
          fValid = TRUE;
          break;
       }
    }
        
    return fValid;
}

#ifdef FEATURE_WLAN_SCAN_PNO
eHalStatus csrScanSavePreferredNetworkFound(tpAniSirGlobal pMac,
            tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
{
   v_U32_t uLen = 0;
   tpSirProbeRespBeacon pParsedFrame;
   tCsrScanResult *pScanResult = NULL;
   tSirBssDescription *pBssDescr = NULL;
   tANI_BOOLEAN fDupBss;
   tDot11fBeaconIEs *pIesLocal = NULL;
   tAniSSID tmpSsid;
   v_TIME_t timer=0;
   tpSirMacMgmtHdr macHeader = (tpSirMacMgmtHdr)pPrefNetworkFoundInd->data;
   boolean bFoundonAppliedChannel = FALSE;
   v_U32_t indx;
   u8 channelsAllowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
   v_U32_t numChannelsAllowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
   tListElem *pEntry;


   pParsedFrame =
       (tpSirProbeRespBeacon)vos_mem_vmalloc(sizeof(tSirProbeRespBeacon));

   if (NULL == pParsedFrame)
   {
      smsLog(pMac, LOGE, FL(" fail to allocate memory for frame"));
      return eHAL_STATUS_RESOURCES;
   }

   if ( pPrefNetworkFoundInd->frameLength <= SIR_MAC_HDR_LEN_3A )
   {
      smsLog(pMac, LOGE,
         FL("Not enough bytes in PNO indication probe resp frame! length=%d"),
         pPrefNetworkFoundInd->frameLength);
      vos_mem_vfree(pParsedFrame);
      return eHAL_STATUS_FAILURE;
   }

   if (sirConvertProbeFrame2Struct(pMac,
               &pPrefNetworkFoundInd->data[SIR_MAC_HDR_LEN_3A],
               pPrefNetworkFoundInd->frameLength - SIR_MAC_HDR_LEN_3A,
               pParsedFrame) != eSIR_SUCCESS ||
         !pParsedFrame->ssidPresent)
   {
      smsLog(pMac, LOGE,
         FL("Parse error ProbeResponse, length=%d"),
         pPrefNetworkFoundInd->frameLength);
      vos_mem_vfree(pParsedFrame);
      return eHAL_STATUS_FAILURE;
   }
   //24 byte MAC header and 12 byte to ssid IE
   if (pPrefNetworkFoundInd->frameLength >
           (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET))
   {
      uLen = pPrefNetworkFoundInd->frameLength -
          (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
   }

   if (uLen > (UINT_MAX - sizeof(tCsrScanResult))) {
       smsLog(pMac, LOGE, FL("Incorrect len: %d, may leads to int overflow, uLen %d"),
              pPrefNetworkFoundInd->frameLength, uLen);
       vos_mem_vfree(pParsedFrame);
       return eHAL_STATUS_FAILURE;
   }

   pScanResult = vos_mem_malloc(sizeof(tCsrScanResult) + uLen);
   if ( NULL == pScanResult )
   {
      smsLog(pMac, LOGE, FL(" fail to allocate memory for frame"));
      vos_mem_free(pParsedFrame);
      return eHAL_STATUS_RESOURCES;
   }

   vos_mem_set(pScanResult, sizeof(tCsrScanResult) + uLen, 0);
   pBssDescr = &pScanResult->Result.BssDescriptor;
   /**
      * Length of BSS desription is without length of
      * length itself and length of pointer
      * that holds the next BSS description
      */
   pBssDescr->length = (tANI_U16)(
        ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields))
        - sizeof(pBssDescr->length) + uLen);
   if (pParsedFrame->dsParamsPresent)
   {
      pBssDescr->channelId = pParsedFrame->channelNumber;
   }
   else if (pParsedFrame->HTInfo.present)
   {
      pBssDescr->channelId = pParsedFrame->HTInfo.primaryChannel;
   }
   else
   {
      /**
        * If Probe Responce received in PNO indication does not
        * contain DSParam IE or HT Info IE then add dummy channel
        * to the received BSS info so that Scan result received as
        * a part of PNO is updated to the supplicant. Specially
        * applicable in case of AP configured in 11A only mode.
        */
      if ((pMac->roam.configParam.bandCapability == eCSR_BAND_ALL) ||
          (pMac->roam.configParam.bandCapability == eCSR_BAND_24))
      {
          pBssDescr->channelId = 1;
      }
      else if(pMac->roam.configParam.bandCapability == eCSR_BAND_5G)
      {
         pBssDescr->channelId = 36;
      }
      /* Restrict the logic to ignore the pno indication for invalid channel
       * only if valid channel info is present in beacon/probe resp.
       * If no channel info is present in beacon/probe resp, always process
       * the pno indication.
       */
      bFoundonAppliedChannel = TRUE;
   }

   if (0 != sme_GetCfgValidChannels(pMac, channelsAllowed, &numChannelsAllowed))
   {
      smsLog(pMac, LOGE, FL(" sme_GetCfgValidChannels failed "));
      csrFreeScanResultEntry(pMac, pScanResult);
      vos_mem_vfree(pParsedFrame);
      return eHAL_STATUS_FAILURE;
   }
   /* Checking chhanelId with allowed channel list */
   for (indx = 0; indx < numChannelsAllowed; indx++)
   {
      if (pBssDescr->channelId == channelsAllowed[indx])
      {
         bFoundonAppliedChannel = TRUE;
         smsLog(pMac, LOG1, FL(" pno ind found on applied channel =%d\n "),
                                                     pBssDescr->channelId);
         break;
      }
   }
   /* Ignore PNO indication if AP is on Invalid channel.
    */
   if(FALSE == bFoundonAppliedChannel)
   {
      smsLog(pMac, LOGW, FL(" prefered network found on invalid channel = %d"),
                                                         pBssDescr->channelId);
      csrFreeScanResultEntry(pMac, pScanResult);
      vos_mem_vfree(pParsedFrame);
      return eHAL_STATUS_FAILURE;
   }

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

   pBssDescr->sinr = 0;
   pBssDescr->rssi = -1 * pPrefNetworkFoundInd->rssi;
   pBssDescr->beaconInterval = pParsedFrame->beaconInterval;
 if (!pBssDescr->beaconInterval)
   {
      smsLog(pMac, LOGW,
         FL("Bcn Interval is Zero , default to 100" MAC_ADDRESS_STR),
         MAC_ADDR_ARRAY(pBssDescr->bssId) );
      pBssDescr->beaconInterval = 100;
   }
   pBssDescr->timeStamp[0]   = pParsedFrame->timeStamp[0];
   pBssDescr->timeStamp[1]   = pParsedFrame->timeStamp[1];
   pBssDescr->capabilityInfo = *((tANI_U16 *)&pParsedFrame->capabilityInfo);
   vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) macHeader->bssId, sizeof(tSirMacAddr));
   pBssDescr->nReceivedTime = vos_timer_get_system_time();

#ifdef WLAN_FEATURE_VOWIFI_11R
    // MobilityDomain
    pBssDescr->mdie[0] = 0;
    pBssDescr->mdie[1] = 0;
    pBssDescr->mdie[2] = 0;
    pBssDescr->mdiePresent = FALSE;
    // If mdie is present in the probe resp we fill it in the bss description
    if(pParsedFrame->mdiePresent)
    {
        pBssDescr->mdiePresent = TRUE;
        pBssDescr->mdie[0] = pParsedFrame->mdie[0];
        pBssDescr->mdie[1] = pParsedFrame->mdie[1];
        pBssDescr->mdie[2] = pParsedFrame->mdie[2];
    }
    smsLog(pMac, LOG1, FL("mdie=%02x%02x%02x"),
           (unsigned int)pBssDescr->mdie[0], (unsigned int)pBssDescr->mdie[1],
           (unsigned int)pBssDescr->mdie[2]);
#endif

   smsLog( pMac, LOG1, FL("Bssid= "MAC_ADDRESS_STR
                       " chan= %d, rssi = %d "),
                       MAC_ADDR_ARRAY(pBssDescr->bssId),
                       pBssDescr->channelId,
                       pBssDescr->rssi);

   //IEs
   if (uLen)
   {
      vos_mem_copy(&pBssDescr->ieFields,
                   pPrefNetworkFoundInd->data + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET),
                   uLen);
   }

   pIesLocal = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes );
   if ( !pIesLocal &&
       (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
            &pScanResult->Result.BssDescriptor, &pIesLocal))) )
   {
      smsLog(pMac, LOGE, FL("  Cannot parse IEs"));
      csrFreeScanResultEntry(pMac, pScanResult);
      vos_mem_vfree(pParsedFrame);
      return eHAL_STATUS_RESOURCES;
   }

   fDupBss = csrRemoveDupBssDescription( pMac,
           &pScanResult->Result.BssDescriptor, pIesLocal, &tmpSsid, &timer, FALSE);
   //Check whether we have reach out limit
   if ( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) )
   {
      //Limit reach
      smsLog(pMac, LOGE, FL("  BSS limit reached"));
      //Free the resources
      if( (pScanResult->Result.pvIes == NULL) && pIesLocal )
      {
         vos_mem_free(pIesLocal);
      }
      csrFreeScanResultEntry(pMac, pScanResult);
      vos_mem_free(pParsedFrame);
      return eHAL_STATUS_RESOURCES;
   }

    if ((macHeader->fc.type == SIR_MAC_MGMT_FRAME) &&
        (macHeader->fc.subType == SIR_MAC_MGMT_PROBE_RSP))
    {
        pScanResult->Result.BssDescriptor.fProbeRsp = 1;
    }
   //Add to scan cache
   csrScanAddResult(pMac, pScanResult, pIesLocal);
   pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
   if( (pScanResult->Result.pvIes == NULL) && pIesLocal )
   {
       vos_mem_free(pIesLocal);
   }

   vos_mem_vfree(pParsedFrame);

   return eHAL_STATUS_SUCCESS;
}
#endif //FEATURE_WLAN_SCAN_PNO

#ifdef FEATURE_WLAN_LFR
void csrInitOccupiedChannelsList(tpAniSirGlobal pMac)
{
  tListElem *pEntry = NULL;
  tCsrScanResult *pBssDesc = NULL;
  tDot11fBeaconIEs *pIes = NULL;
  tpCsrNeighborRoamControlInfo    pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;

  if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
  {
       smsLog(pMac, LOG1, FL("%s: Ini file contains neighbor scan channel list,"
             " hence NO need to build occupied channel list (numChannels = %d)"),
              __func__, pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
      return;
  }

  if (!csrNeighborRoamIsNewConnectedProfile(pMac))
  {
      smsLog(pMac, LOG2, FL("%s: donot flush occupied list since current roam profile"
             " matches previous (numChannels = %d)"),
              __func__, pMac->scan.occupiedChannels.numChannels);
      return;
  }

  /* Empty occupied channels here */
  pMac->scan.occupiedChannels.numChannels = 0;

  csrLLLock(&pMac->scan.scanResultList);
  pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
  while( pEntry )
  {
      pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
      pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes );

      //At this time, pBssDescription->Result.pvIes may be NULL
      if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, 
                    &pBssDesc->Result.BssDescriptor, &pIes))) )
      {
          continue;
      }

      csrScanAddToOccupiedChannels(pMac, pBssDesc, &pMac->scan.occupiedChannels, pIes);

      /*
       * Free the memory allocated for pIes in csrGetParsedBssDescriptionIEs
       */
      if( (pBssDesc->Result.pvIes == NULL) && pIes )
      {
          vos_mem_free(pIes);
      }

      pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK );
  }//while
  csrLLUnlock(&pMac->scan.scanResultList);
    
}
#endif

eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId,
                                         tCsrBssid bssid, tANI_U8 channel)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tDot11fBeaconIEs *pNewIes = NULL;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
    tSirBssDescription *pNewBssDescriptor = NULL;
    tANI_U32 size = 0;

    if(NULL == pSession)
    {
       status = eHAL_STATUS_FAILURE;
       return status;
    }
    smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: Current bssid::"
                          MAC_ADDRESS_STR),
                          MAC_ADDR_ARRAY(pSession->pConnectBssDesc->bssId));
    smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: My bssid::"
                          MAC_ADDRESS_STR" channel %d"),
                          MAC_ADDR_ARRAY(bssid), channel);

    do
    {
        if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
                                                             pSession->pConnectBssDesc, &pNewIes)))
        {
            smsLog(pMac, LOGE, FL("%s: Failed to parse IEs"),
                                  __func__);
            status = eHAL_STATUS_FAILURE;
            break;
        }

        size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length);
        if (size)
        {
            pNewBssDescriptor = vos_mem_malloc(size);
            if ( NULL == pNewBssDescriptor )
                status = eHAL_STATUS_FAILURE;
            else
                status = eHAL_STATUS_SUCCESS;
            if (HAL_STATUS_SUCCESS(status))
            {
                vos_mem_copy(pNewBssDescriptor, pSession->pConnectBssDesc, size);
            }
            else
            {
                smsLog(pMac, LOGE, FL("%s: memory allocation failed"),
                                      __func__);
                status = eHAL_STATUS_FAILURE;
                break;
            }

            //change the BSSID & channel as passed
            vos_mem_copy(pNewBssDescriptor->bssId, bssid, sizeof(tSirMacAddr));
            pNewBssDescriptor->channelId = channel;
            if(NULL == csrScanAppendBssDescription( pMac, pNewBssDescriptor, pNewIes, TRUE ))
            {
                smsLog(pMac, LOGE, FL("%s: csrScanAppendBssDescription failed"),
                                      __func__);
                status = eHAL_STATUS_FAILURE;
                break;
            }
        }
        else
        {
            smsLog(pMac, LOGE, FL("%s: length of bss descriptor is 0"),
                                  __func__);
            status = eHAL_STATUS_FAILURE;
            break;
        }
        smsLog(pMac, LOGE, FL("%s: entry successfully added in scan cache"),
                              __func__);
    }while(0);

    if(pNewIes)
    {
        vos_mem_free(pNewIes);
    }
    if(pNewBssDescriptor)
    {
        vos_mem_free(pNewBssDescriptor);
    }
    return status;
}

#ifdef FEATURE_WLAN_ESE
//  Update the TSF with the difference in system time
void UpdateCCKMTSF(tANI_U32 *timeStamp0, tANI_U32 *timeStamp1, tANI_U32 *incr)
{
    tANI_U64 timeStamp64 = ((tANI_U64)*timeStamp1 << 32) | (*timeStamp0);

    timeStamp64 = (tANI_U64)(timeStamp64 + (tANI_U64)*incr);
    *timeStamp0 = (tANI_U32)(timeStamp64 & 0xffffffff);
    *timeStamp1 = (tANI_U32)((timeStamp64 >> 32) & 0xffffffff);
}
#endif

void csrValidateScanChannels(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq,
        tCsrScanRequest *pSrcReq, tANI_U32 *new_index, tANI_U8 ch144_support)
{

    int index;
    for ( index = 0; index < pSrcReq->ChannelInfo.
            numOfChannels ; index++ )
    {
        /* Skip CH 144 if firmware support not present */
        if (pSrcReq->ChannelInfo.ChannelList[index] == 144 && !ch144_support)
            continue;

        /* Allow scan on valid channels only.
         */
        if ( ( csrRoamIsValidChannel(pMac,
                        pSrcReq->ChannelInfo.ChannelList[index]) ) )
        {
            if( ((pSrcReq->skipDfsChnlInP2pSearch ||
                            (pMac->scan.fEnableDFSChnlScan ==
                             DFS_CHNL_SCAN_DISABLED)) &&
                        (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(
                              pSrcReq->ChannelInfo.ChannelList[index])) &&
                        (pSrcReq->ChannelInfo.numOfChannels > 1))
#ifdef FEATURE_WLAN_LFR
                    /*
                     * If LFR is requesting a contiguous scan
                     * (i.e. numOfChannels > 1), then ignore
                     * DFS channels.
                     * TODO: vos_nv_getChannelEnabledState is returning
                     * 120, 124 and 128 as non-DFS channels. Hence, the
                     * use of direct check for channels below.
                     */
                    || ((eCSR_SCAN_HO_BG_SCAN == pSrcReq->requestType) &&
                        (pSrcReq->ChannelInfo.numOfChannels > 1) &&
                        (CSR_IS_CHANNEL_DFS(
                            pSrcReq->ChannelInfo.ChannelList[index])) &&
                        !pMac->roam.configParam.allowDFSChannelRoam)
#endif
                        )
                        {
#ifdef FEATURE_WLAN_LFR
                            smsLog(pMac, LOG1,
                                  FL(" reqType=%s (%d), numOfChannels=%d,"
                                      " ignoring DFS channel:%d"),
                                  sme_requestTypetoString(pSrcReq->requestType),
                                  pSrcReq->requestType,
                                  pSrcReq->ChannelInfo.numOfChannels,
                                  pSrcReq->ChannelInfo.ChannelList[index]);
#endif
                            continue;
                        }

            pDstReq->ChannelInfo.ChannelList[*new_index] =
                pSrcReq->ChannelInfo.ChannelList[index];
            (*new_index)++;
        }
    }
}
