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

  \brief Definitions for SME APIs

  ========================================================================*/

/*===========================================================================

                      EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.



  when           who                 what, where, why
----------       ---                --------------------------------------------------------
06/03/10     js                     Added support to hostapd driven
 *                                  deauth/disassoc/mic failure

===========================================================================*/

/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/

#include "smsDebug.h"
#include "sme_Api.h"
#include "csrInsideApi.h"
#include "smeInside.h"
#include "csrInternal.h"
#include "wlan_qct_wda.h"
#include "halMsgApi.h"
#include "vos_trace.h"
#include "sme_Trace.h"
#include "vos_types.h"
#include "vos_trace.h"
#include "vos_utils.h"
#include "sapApi.h"
#include "macTrace.h"
#ifdef WLAN_FEATURE_NAN
#include "nan_Api.h"
#endif
#include "regdomain_common.h"
#include "schApi.h"
#include "sme_nan_datapath.h"
#include "csrApi.h"
#include "utilsApi.h"
#include "limUtils.h"

extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);

#define LOG_SIZE 256
#define TL_INIT_STATE            0

static tSelfRecoveryStats gSelfRecoveryStats;


// TxMB Functions
extern eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, tANI_U32 sessionId,
                                     eSmeCommandType cmdType, void *pvParam,
                                     tANI_U32 size, tSmeCmd **ppCmd);
extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand );
extern void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand );
extern void csr_release_roc_req_cmd(tpAniSirGlobal mac_ctx);
extern eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn);
extern eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg);
extern eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg);
extern eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd);

static eHalStatus initSmeCmdList(tpAniSirGlobal pMac);
static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping );

eCsrPhyMode sme_GetPhyMode(tHalHandle hHal);

eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac,  void *pMsgBuf);

void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac);

eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac,  void *pMsgBuf);

eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal, void *pMsgBuf);

eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal);

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId);
#endif

#ifdef WLAN_FEATURE_11W
eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
                                      tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm );
#endif

/* Message processor for events from DFS */
eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac,
                           v_U16_t msg_type,void *pMsgBuf);

/* Channel Change Response Indication Handler */
eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac,
                           v_U16_t msg_type,void *pMsgBuf);
eHalStatus sme_process_set_max_tx_power(tpAniSirGlobal pMac,
						tSmeCmd *command);
eHalStatus
sme_process_set_max_tx_power_per_band(tpAniSirGlobal mac_ctx,
						tSmeCmd *command);

//Internal SME APIs
eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;

    if(psSme)
    {
        if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psSme->lkSmeGlobalLock) ) )
        {
            status = eHAL_STATUS_SUCCESS;
        }
    }

    return (status);
}


eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;

    if(psSme)
    {
        if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psSme->lkSmeGlobalLock) ) )
        {
            status = eHAL_STATUS_SUCCESS;
        }
    }

    return (status);
}

/**
 * free_sme_cmds() - This function frees memory allocated for SME commands
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function frees memory allocated for SME commands
 *
 * @Return: void
 */
static void free_sme_cmds(tpAniSirGlobal mac_ctx)
{
	uint32_t idx;
	if (NULL == mac_ctx->sme.pSmeCmdBufAddr)
		return;

	for (idx = 0; idx < mac_ctx->sme.totalSmeCmd; idx++)
		vos_mem_free(mac_ctx->sme.pSmeCmdBufAddr[idx]);

	vos_mem_free(mac_ctx->sme.pSmeCmdBufAddr);
	mac_ctx->sme.pSmeCmdBufAddr = NULL;
}

static eHalStatus initSmeCmdList(tpAniSirGlobal pMac)
{
    eHalStatus status;
    tSmeCmd *pCmd;
    tANI_U32 cmd_idx;
    uint32_t sme_cmd_ptr_ary_sz;
    VOS_STATUS vosStatus;
    vos_timer_t* cmdTimeoutTimer = NULL;

    pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND;
    if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd,
                           &pMac->sme.smeCmdActiveList)))
       goto end;

    if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd,
                           &pMac->sme.smeCmdPendingList)))
       goto end;

    if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd,
                           &pMac->sme.smeScanCmdActiveList)))
       goto end;

    if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd,
                                            &pMac->sme.smeScanCmdPendingList)))
       goto end;

    if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd,
                                             &pMac->sme.smeCmdFreeList)))
       goto end;

    /* following pointer contains array of pointers for tSmeCmd* */
    sme_cmd_ptr_ary_sz = sizeof(void*) * pMac->sme.totalSmeCmd;
    pMac->sme.pSmeCmdBufAddr = vos_mem_malloc(sme_cmd_ptr_ary_sz);
    if (NULL == pMac->sme.pSmeCmdBufAddr) {
        status = eHAL_STATUS_FAILURE;
        goto end;
    }

    status = eHAL_STATUS_SUCCESS;
    vos_mem_set(pMac->sme.pSmeCmdBufAddr, sme_cmd_ptr_ary_sz, 0);
    for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) {
       /*
        * Since total size of all commands together can be huge chunk of
        * memory, allocate SME cmd individually. These SME CMDs are moved
        * between pending and active queues. And these freeing of these
        * queues just manipulates the list but does not actually frees SME
        * CMD pointers. Hence store each SME CMD address in the array,
        * sme.pSmeCmdBufAddr. This will later facilitate freeing up of all
        * SME CMDs with just a for loop.
        */
        pMac->sme.pSmeCmdBufAddr[cmd_idx] = vos_mem_malloc(sizeof(tSmeCmd));
        if (NULL == pMac->sme.pSmeCmdBufAddr[cmd_idx]) {
           status = eHAL_STATUS_FAILURE;
           free_sme_cmds(pMac);
           goto end;
        }
        pCmd = (tSmeCmd*)pMac->sme.pSmeCmdBufAddr[cmd_idx];
        csrLLInsertTail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK);
    }

    /* This timer is only to debug the active list command timeout */

    cmdTimeoutTimer = (vos_timer_t*)vos_mem_malloc(sizeof(vos_timer_t));
    if (cmdTimeoutTimer)
    {
        pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer;
       vosStatus =
            vos_timer_init( pMac->sme.smeCmdActiveList.cmdTimeoutTimer,
                              VOS_TIMER_TYPE_SW,
                              activeListCmdTimeoutHandle,
                              (void*) pMac);

        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "Init Timer fail for active list command process time out");
            vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
        }
        else
        {
            pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
                CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
        }
    }

end:
    if (!HAL_STATUS_SUCCESS(status))
       smsLog(pMac, LOGE, "failed to initialize sme command list:%d\n",
              status);

    return (status);
}


void smeReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd)
{
    pCmd->command = eSmeNoCommand;
    csrLLInsertTail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK);
}



static void smeReleaseCmdList(tpAniSirGlobal pMac, tDblLinkList *pList)
{
    tListElem *pEntry;
    tSmeCmd *pCommand;

    while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_LOCK)) != NULL)
    {
        //TODO: base on command type to call release functions
        //reinitialize different command types so they can be reused
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE);
    }
}

static void purgeSmeCmdList(tpAniSirGlobal pMac)
{
    //release any out standing commands back to free command list
    smeReleaseCmdList(pMac, &pMac->sme.smeCmdPendingList);
    smeReleaseCmdList(pMac, &pMac->sme.smeCmdActiveList);
    smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdPendingList);
    smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdActiveList);
}

void purgeSmeSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId,
        tDblLinkList *pList)
{
    //release any out standing commands back to free command list
    tListElem *pEntry, *pNext;
    tSmeCmd *pCommand;
    tDblLinkList localList;

    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);
    pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK);
    while(pEntry != NULL)
    {
        pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
        pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        if(pCommand->sessionId == sessionId)
        {
            if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK))
            {
                csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
            }
        }
        pEntry = pNext;
    }
    csrLLUnlock(pList);

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


static eHalStatus freeSmeCmdList(tpAniSirGlobal pMac)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    purgeSmeCmdList(pMac);
    csrLLClose(&pMac->sme.smeCmdPendingList);
    csrLLClose(&pMac->sme.smeCmdActiveList);
    csrLLClose(&pMac->sme.smeScanCmdPendingList);
    csrLLClose(&pMac->sme.smeScanCmdActiveList);
    csrLLClose(&pMac->sme.smeCmdFreeList);

    /*destroy active list command time out timer */
    vos_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
    vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
    pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL;

    status = vos_lock_acquire(&pMac->sme.lkSmeGlobalLock);
    if(status != eHAL_STATUS_SUCCESS)
    {
        smsLog(pMac, LOGE,
            FL("Failed to acquire the lock status = %d"), status);
        goto done;
    }

    free_sme_cmds(pMac);

    status = vos_lock_release(&pMac->sme.lkSmeGlobalLock);
    if(status != eHAL_STATUS_SUCCESS)
    {
        smsLog(pMac, LOGE,
            FL("Failed to release the lock status = %d"), status);
    }
done:
    return (status);
}


void dumpCsrCommandInfo(tpAniSirGlobal pMac, tSmeCmd *pCmd)
{
    switch( pCmd->command )
    {
    case eSmeCommandScan:
        smsLog( pMac, LOGE, " scan command reason is %d", pCmd->u.scanCmd.reason );
        break;

    case eSmeCommandRoam:
        smsLog( pMac, LOGE, " roam command reason is %d", pCmd->u.roamCmd.roamReason );
        break;

    case eSmeCommandWmStatusChange:
        smsLog( pMac, LOGE, " WMStatusChange command type is %d", pCmd->u.wmStatusChangeCmd.Type );
        break;

    case eSmeCommandSetKey:
        smsLog( pMac, LOGE, " setKey command auth(%d) enc(%d)",
                        pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType );
        break;

    case eSmeCommandRemoveKey:
        smsLog( pMac, LOGE, " removeKey command auth(%d) enc(%d)",
                        pCmd->u.removeKeyCmd.authType, pCmd->u.removeKeyCmd.encType );
        break;

    default:
        smsLog( pMac, LOGE, " default: Unhandled command %d",
                pCmd->command);
        break;
    }
}

tSmeCmd *smeGetCommandBuffer( tpAniSirGlobal pMac )
{
    tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL;
    tListElem *pEntry;
    static int smeCommandQueueFull = 0;

    pEntry = csrLLRemoveHead( &pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK );

    /*
     * If we can get another MS Msg buffer, then we are ok.  Just link
     * the entry onto the linked list.  (We are using the linked list
     * to keep track of the message buffers).
     */
    if ( pEntry )
    {
        pRetCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        /* reset when free list is available */
        smeCommandQueueFull = 0;
    }
    else
    {
        int idx = 1;

        //Cannot change pRetCmd here since it needs to return later.
        pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
        if( pEntry )
        {
           pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
        }
        smsLog( pMac, LOGE, "Out of command buffer.... command (0x%X) stuck",
           (pTempCmd) ? pTempCmd->command : eSmeNoCommand );
        if(pTempCmd)
        {
            if( eSmeCsrCommandMask & pTempCmd->command )
            {
                //CSR command is stuck. See what the reason code is for that command
                dumpCsrCommandInfo(pMac, pTempCmd);
            }
        } //if(pTempCmd)

        //dump what is in the pending queue
        csrLLLock(&pMac->sme.smeCmdPendingList);
        pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK );
        while(pEntry && !smeCommandQueueFull)
        {
            pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
            /* Print only 1st five commands from pending queue. */
            if (idx <= 5)
                smsLog( pMac, LOGE, "Out of command buffer.... SME pending command #%d (0x%X)",
                        idx, pTempCmd->command );
            idx++;
            if( eSmeCsrCommandMask & pTempCmd->command )
            {
                //CSR command is stuck. See what the reason code is for that command
                dumpCsrCommandInfo(pMac, pTempCmd);
            }
            pEntry = csrLLNext( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK );
        }
        csrLLUnlock(&pMac->sme.smeCmdPendingList);

        idx = 1;
        //There may be some more command in CSR's own pending queue
        csrLLLock(&pMac->roam.roamCmdPendingList);
        pEntry = csrLLPeekHead( &pMac->roam.roamCmdPendingList, LL_ACCESS_NOLOCK );
        while(pEntry && !smeCommandQueueFull)
        {
            pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
            /* Print only 1st five commands from CSR pending queue */
            if (idx <= 5)
                smsLog( pMac, LOGE,
                     "Out of command buffer.... CSR roamCmdPendingList command #%d (0x%X)",
                     idx, pTempCmd->command );
            idx++;
            dumpCsrCommandInfo(pMac, pTempCmd);
            pEntry = csrLLNext( &pMac->roam.roamCmdPendingList, pEntry, LL_ACCESS_NOLOCK );
        }
        /* Increament static variable so that it prints pending command only once*/
        smeCommandQueueFull++;
        csrLLUnlock(&pMac->roam.roamCmdPendingList);

        /* panic with out-of-command */
        if (pMac->roam.configParam.enable_fatal_event) {
            vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                           WLAN_LOG_INDICATOR_HOST_DRIVER,
                           WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
                           DUMP_NO_TRACE);
        } else {
            /* Trigger SSR */
            vos_wlanRestart();
        }
    }

    /* memset to zero */
    if (pRetCmd) {
        vos_mem_set((tANI_U8 *)&pRetCmd->command, sizeof(pRetCmd->command), 0);
        vos_mem_set((tANI_U8 *)&pRetCmd->sessionId,
                    sizeof(pRetCmd->sessionId), 0);
        vos_mem_set((tANI_U8 *)&pRetCmd->u, sizeof(pRetCmd->u), 0);
    }

    return(pRetCmd);
}


void smePushCommand( tpAniSirGlobal pMac, tSmeCmd *pCmd, tANI_BOOLEAN fHighPriority )
{
    if (!SME_IS_START(pMac)) {
        smsLog(pMac, LOGE, FL("Sme in stop state"));
        return;
    }

    if ( fHighPriority )
    {
        csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK );
    }
    else
    {
        csrLLInsertTail( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK );
    }

    // process the command queue...
    smeProcessPendingQueue( pMac );

    return;
}


static eSmeCommandType smeIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
    eSmeCommandType pmcCommand = eSmeNoCommand;
    tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE;
    tPmcState pmcState;
    eHalStatus status;

    do
    {
        pmcState = pmcGetPmcState(pMac);

        status = csrIsFullPowerNeeded( pMac, pCommand, NULL, &fFullPowerNeeded );
        if( !HAL_STATUS_SUCCESS(status) )
        {
            //PMC state is not right for the command, drop it
            return ( eSmeDropCommand );
        }
        if( fFullPowerNeeded  ) break;
        fFullPowerNeeded = ( ( eSmeCommandAddTs == pCommand->command ) ||
                    ( eSmeCommandDelTs ==  pCommand->command ) );
        if( fFullPowerNeeded ) break;
#ifdef FEATURE_OEM_DATA_SUPPORT
        fFullPowerNeeded = (pmcState == IMPS &&
                                       eSmeCommandOemDataReq == pCommand->command);
        if(fFullPowerNeeded) break;
#endif
        fFullPowerNeeded = (pmcState == IMPS &&
                            eSmeCommandRemainOnChannel == pCommand->command);
        if(fFullPowerNeeded) break;
    } while(0);

    if( fFullPowerNeeded )
    {
        switch( pmcState )
        {
        case IMPS:
        case STANDBY:
            pmcCommand = eSmeCommandExitImps;
            break;

        case BMPS:
            pmcCommand = eSmeCommandExitBmps;
            break;

        case UAPSD:
            pmcCommand = eSmeCommandExitUapsd;
            break;

        case WOWL:
            pmcCommand = eSmeCommandExitWowl;
            break;

        default:
            break;
        }
    }

    return ( pmcCommand );
}

static eSmeCommandType smePsOffloadIsFullPowerNeeded(tpAniSirGlobal pMac,
                                                     tSmeCmd *pCommand)
{
    eSmeCommandType pmcCommand = eSmeNoCommand;
    tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE;
    eHalStatus status;
    tPmcState pmcState;

    do
    {
        /* Check for CSR Commands which require full power */
        status = csrPsOffloadIsFullPowerNeeded(pMac, pCommand, NULL,
                                               &fFullPowerNeeded);
        if(!HAL_STATUS_SUCCESS(status))
        {
            /* PMC state is not right for the command, drop it */
            return eSmeDropCommand;
        }
        if(fFullPowerNeeded) break;

        /* Check for SME Commands which require Full Power */
        if((eSmeCommandAddTs == pCommand->command) ||
           ((eSmeCommandDelTs ==  pCommand->command)))
        {
           /* Get the PMC State */
           pmcState = pmcOffloadGetPmcState(pMac, pCommand->sessionId);
           switch(pmcState)
           {
               case REQUEST_BMPS:
               case BMPS:
               case REQUEST_START_UAPSD:
               case REQUEST_STOP_UAPSD:
               case UAPSD:
                   fFullPowerNeeded = eANI_BOOLEAN_TRUE;
                 break;
               case STOPPED:
                 break;
               default:
                 break;
           }
           break;
        }
    } while(0);

    if(fFullPowerNeeded)
    {
        pmcCommand = eSmeCommandExitBmps;
    }

    return pmcCommand;
}


//For commands that need to do extra cleanup.
static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping )
{
    if( eSmePmcCommandMask & pCommand->command )
    {
        if(!pMac->psOffloadEnabled)
            pmcAbortCommand( pMac, pCommand, fStopping );
        else
            pmcOffloadAbortCommand(pMac, pCommand, fStopping);
    }
    else if ( eSmeCsrCommandMask & pCommand->command )
    {
        csrAbortCommand( pMac, pCommand, fStopping );
    }
    else
    {
        switch( pCommand->command )
        {
            case eSmeCommandRemainOnChannel:
                if (NULL != pCommand->u.remainChlCmd.callback)
                {
                    remainOnChanCallback callback =
                                            pCommand->u.remainChlCmd.callback;
                    /* process the msg */
                    if( callback )
                    {
                        callback(pMac, pCommand->u.remainChlCmd.callbackCtx,
                                            eCSR_SCAN_ABORT );
                    }
                }
                smeReleaseCommand( pMac, pCommand );
                break;
            default:
                smeReleaseCommand( pMac, pCommand );
                break;
        }
    }
}

tListElem *csrGetCmdToProcess(tpAniSirGlobal pMac, tDblLinkList *pList,
                              tANI_U8 sessionId, tANI_BOOLEAN fInterlocked)
{
    tListElem *pCurEntry = NULL;
    tSmeCmd *pCommand;

    /* Go through the list and return the command whose session id is not
     * matching with the current ongoing scan cmd sessionId */
    pCurEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
    while (pCurEntry)
    {
        pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link);
        if (pCommand->sessionId != sessionId)
        {
            smsLog(pMac, LOG1, "selected the command with different sessionId");
            return pCurEntry;
        }

        pCurEntry = csrLLNext(pList, pCurEntry, fInterlocked);
    }

    smsLog(pMac, LOG1, "No command pending with different sessionId");
    return NULL;
}

tANI_BOOLEAN smeProcessScanQueue(tpAniSirGlobal pMac)
{
    tListElem *pEntry;
    tSmeCmd *pCommand;
    tListElem *pSmeEntry = NULL;
    tSmeCmd *pSmeCommand = NULL;
    tANI_BOOLEAN status = eANI_BOOLEAN_TRUE;

    if ((!csrLLIsListEmpty(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ))) {
        pSmeEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList,
                        LL_ACCESS_LOCK);
        if (pSmeEntry)
            pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link) ;
    }

    csrLLLock( &pMac->sme.smeScanCmdActiveList );
    if (csrLLIsListEmpty( &pMac->sme.smeScanCmdActiveList,
                LL_ACCESS_NOLOCK ))
    {
        if (!csrLLIsListEmpty(&pMac->sme.smeScanCmdPendingList,
                    LL_ACCESS_LOCK))
        {
            pEntry = csrLLPeekHead( &pMac->sme.smeScanCmdPendingList,
                    LL_ACCESS_LOCK );
            if (pEntry) {
                pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
                if (pSmeCommand != NULL) {
                    /* if there is an active SME command, do not process
                     * the pending scan cmd
                     */
                    smsLog(pMac, LOG1, "SME scan cmd is pending on session %d",
                           pSmeCommand->sessionId);
                    status = eANI_BOOLEAN_FALSE;
                    goto end;
                }
                //We cannot execute any command in wait-for-key state until setKey is through.
                if (CSR_IS_WAIT_FOR_KEY( pMac, pCommand->sessionId))
                {
                    if (!CSR_IS_SET_KEY_COMMAND(pCommand))
                    {
                        smsLog(pMac, LOGE,
                                "  Cannot process command(%d) while waiting for key",
                                pCommand->command);
                        status = eANI_BOOLEAN_FALSE;
                        goto end;
                    }
                }
                if ( csrLLRemoveEntry( &pMac->sme.smeScanCmdPendingList,
                            pEntry, LL_ACCESS_LOCK ) )
                {
                    csrLLInsertHead( &pMac->sme.smeScanCmdActiveList,
                            &pCommand->Link, LL_ACCESS_NOLOCK );

                    switch (pCommand->command)
                    {
                        case eSmeCommandScan:
                            smsLog(pMac, LOG1,
                                    " Processing scan offload command ");
                            csrProcessScanCommand( pMac, pCommand );
                            break;
                        case eSmeCommandRemainOnChannel:
                            smsLog(pMac, LOG1,
                                    "Processing req remain on channel offload"
                                    " command");
                            p2pProcessRemainOnChannelCmd(pMac, pCommand);
                            break;
                        default:
                            smsLog(pMac, LOGE,
                                    " Something wrong, wrong command enqueued"
                                    " to smeScanCmdPendingList");
                            pEntry = csrLLRemoveHead(
                                    &pMac->sme.smeScanCmdActiveList,
                                    LL_ACCESS_NOLOCK );
                            pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
                            smeReleaseCommand( pMac, pCommand );
                            break;
                    }
                }
            }
        }
    }
end:
    csrLLUnlock(&pMac->sme.smeScanCmdActiveList);
    return status;
}

tANI_BOOLEAN smeProcessCommand( tpAniSirGlobal pMac )
{
    tANI_BOOLEAN fContinue = eANI_BOOLEAN_FALSE;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry;
    tSmeCmd *pCommand;
    tListElem *pSmeEntry;
    tSmeCmd *pSmeCommand;
    eSmeCommandType pmcCommand = eSmeNoCommand;

    /*
     * If the ActiveList is empty, then nothing is active so we can process a
     * pending command.
     * Always lock active list before locking pending list.
     */
    csrLLLock( &pMac->sme.smeCmdActiveList );
    if ( csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) )
    {
        if(!csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK))
        {
            /* If scan command is pending in the smeScanCmdActive list
             * then pick the command from smeCmdPendingList which is
             * not matching with the scan command session id.
             * At any point of time only one command will be allowed
             * on a single session. */
            if ((pMac->fScanOffload) &&
                    (!csrLLIsListEmpty(&pMac->sme.smeScanCmdActiveList,
                                       LL_ACCESS_LOCK)))
            {
                pSmeEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList,
                        LL_ACCESS_LOCK);
                if (pSmeEntry)
                {
                    pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link);

                    pEntry = csrGetCmdToProcess(pMac,
                            &pMac->sme.smeCmdPendingList,
                            pSmeCommand->sessionId,
                            LL_ACCESS_LOCK);
                    goto sme_process_cmd;
                }
            }

            //Peek the command
            pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK );
sme_process_cmd:
            if( pEntry )
            {
                pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );

                /* Allow only disconnect command
                 * in wait-for-key state until setKey is through.
                 */
                if( CSR_IS_WAIT_FOR_KEY( pMac, pCommand->sessionId ) &&
                    !CSR_IS_DISCONNECT_COMMAND( pCommand ) )
                {
                    if (CSR_IS_CLOSE_SESSION_COMMAND(pCommand)) {
                        tSmeCmd *sme_cmd = NULL;

                        smsLog(pMac, LOGE,
                                 FL("SessionId %d: close session command issued while waiting for key, issue disconnect first"),
                                 pCommand->sessionId);
                        status = csr_prepare_disconnect_command(pMac,
                                             pCommand->sessionId, &sme_cmd);
                        if (HAL_STATUS_SUCCESS(status) && sme_cmd) {
                            csrLLLock(&pMac->sme.smeCmdPendingList);
                            csrLLInsertHead(&pMac->sme.smeCmdPendingList,
                                              &sme_cmd->Link, LL_ACCESS_NOLOCK);
                            pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList,
                                                      LL_ACCESS_NOLOCK);
                            csrLLUnlock(&pMac->sme.smeCmdPendingList);
                            goto sme_process_cmd;
                        }
                    }

                    if( !CSR_IS_SET_KEY_COMMAND( pCommand ) )
                    {
                        csrLLUnlock( &pMac->sme.smeCmdActiveList );
                        smsLog(pMac, LOGE, FL("SessionId %d:  Cannot process "
                               "command(%d) while waiting for key"),
                               pCommand->sessionId, pCommand->command);
                        fContinue = eANI_BOOLEAN_FALSE;
                        goto sme_process_scan_queue;
                    }
                }
                if(pMac->psOffloadEnabled)
                    pmcCommand = smePsOffloadIsFullPowerNeeded(pMac, pCommand);
                else
                   pmcCommand = smeIsFullPowerNeeded( pMac, pCommand );
                if( eSmeDropCommand == pmcCommand )
                {
                    csrLLUnlock(&pMac->sme.smeCmdActiveList);
                    //This command is not ok for current PMC state
                    if( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) )
                    {
                        smeAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE );
                    }
                    //tell caller to continue
                    fContinue = eANI_BOOLEAN_TRUE;
                    goto sme_process_scan_queue;
                }
                else if( eSmeNoCommand != pmcCommand )
                {
                    tExitBmpsInfo exitBmpsInfo;
                    void *pv = NULL;
                    tANI_U32 size = 0;
                    tSmeCmd *pPmcCmd = NULL;

                    if( eSmeCommandExitBmps == pmcCommand )
                    {
                        exitBmpsInfo.exitBmpsReason = eSME_REASON_OTHER;
                        pv = (void *)&exitBmpsInfo;
                        size = sizeof(tExitBmpsInfo);
                    }
                    //pmcCommand has to be one of the exit power save command
                    status = pmcPrepareCommand(pMac, pCommand->sessionId,
                                               pmcCommand, pv, size,
                                               &pPmcCmd);
                    if( HAL_STATUS_SUCCESS( status ) && pPmcCmd )
                    {
                        //Force this command to wake up the chip
                        csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK );
                        MTRACE(vos_trace(VOS_MODULE_ID_SME,
                           TRACE_CODE_SME_COMMAND, pPmcCmd->sessionId, pPmcCmd->command));
                        csrLLUnlock( &pMac->sme.smeCmdActiveList );
                        /* Handle PS Offload Case Separately */
                        if(pMac->psOffloadEnabled)
                        {
                           fContinue = pmcOffloadProcessCommand(pMac, pPmcCmd);
                        }
                        else
                        {
                            fContinue = pmcProcessCommand( pMac, pPmcCmd );
                        }
                        if( fContinue )
                        {
                            //The command failed, remove it
                            if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ) )
                            {
                                pmcReleaseCommand( pMac, pPmcCmd );
                            }
                        }
                    }
                    else
                    {
                        csrLLUnlock( &pMac->sme.smeCmdActiveList );
                        smsLog( pMac, LOGE, FL(  "Cannot issue command(0x%X) to wake up the chip. Status = %d"), pmcCommand, status );
                        //Let it retry
                        fContinue = eANI_BOOLEAN_TRUE;
                    }
                    goto sme_process_scan_queue;
                }
                if ( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) )
                {
                    // we can reuse the pCommand

                    // Insert the command onto the ActiveList...
                    csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_NOLOCK );

                    // .... and process the command.

                    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                       TRACE_CODE_SME_COMMAND, pCommand->sessionId, pCommand->command));
                    switch ( pCommand->command )
                    {

                        case eSmeCommandScan:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            status = csrProcessScanCommand( pMac, pCommand );
                            break;

                        case eSmeCommandRoam:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            status  = csrRoamProcessCommand( pMac, pCommand );
                            if(!HAL_STATUS_SUCCESS(status))
                            {
                                if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                            &pCommand->Link, LL_ACCESS_LOCK ) )
                                {
                                    csrReleaseCommandRoam( pMac, pCommand );
                                }
                            }
                            break;

                        case eSmeCommandWmStatusChange:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            csrRoamProcessWmStatusChangeCommand(pMac, pCommand);
                            fContinue = eANI_BOOLEAN_TRUE;
                            break;

                        case eSmeCommandSetKey:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            status = csrRoamProcessSetKeyCommand( pMac, pCommand );
                            if(!HAL_STATUS_SUCCESS(status))
                            {
                                if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                            &pCommand->Link, LL_ACCESS_LOCK ) )
                                {
                                    csrReleaseCommandSetKey( pMac, pCommand );
                                }
                            }
                            break;

                        case eSmeCommandRemoveKey:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            status = csrRoamProcessRemoveKeyCommand( pMac, pCommand );
                            if(!HAL_STATUS_SUCCESS(status))
                            {
                                if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                            &pCommand->Link, LL_ACCESS_LOCK ) )
                                {
                                    csrReleaseCommandRemoveKey( pMac, pCommand );
                                }
                            }
                            break;

                        case eSmeCommandAddStaSession:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            csrProcessAddStaSessionCommand( pMac, pCommand );
                            break;
                        case eSmeCommandNdpInitiatorRequest:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            if (csr_process_ndp_initiator_request(pMac,
                                        pCommand) != eHAL_STATUS_SUCCESS) {
                                if (csrLLRemoveEntry(
                                        &pMac->sme.smeCmdActiveList,
                                        &pCommand->Link, LL_ACCESS_LOCK)) {
                                    csrReleaseCommand(pMac, pCommand);
                                }
                            }
                            break;
                        case eSmeCommandNdpResponderRequest:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            status =
                                 csr_process_ndp_responder_request(pMac,
                                                                   pCommand);
                            if (!HAL_STATUS_SUCCESS(status)) {
                                if (csrLLRemoveEntry(
                                          &pMac->sme.smeCmdActiveList,
                                             &pCommand->Link, LL_ACCESS_LOCK))
                                    csrReleaseCommand(pMac, pCommand);
                            }
                            break;
                        case eSmeCommandNdpDataEndInitiatorRequest:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            status = csr_process_ndp_data_end_request(pMac,
                                                                      pCommand);
                            if (!HAL_STATUS_SUCCESS(status)) {
                                if (csrLLRemoveEntry(
                                          &pMac->sme.smeCmdActiveList,
                                             &pCommand->Link, LL_ACCESS_LOCK))
                                    csrReleaseCommand(pMac, pCommand);
                            }
                            break;
                        case eSmeCommandDelStaSession:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            csrProcessDelStaSessionCommand( pMac, pCommand );
                            break;
                        case eSmeCommandSetMaxTxPower:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            sme_process_set_max_tx_power(pMac, pCommand);
                            /* We need to re-run the command */
                            fContinue = eANI_BOOLEAN_TRUE;
                            /* No Rsp expected, free cmd from active list */
                            if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
                                        &pCommand->Link, LL_ACCESS_LOCK)) {
                               csrReleaseCommand(pMac, pCommand);
                            }
                            pMac->max_power_cmd_pending = false;
                            break;
                        case eSmeCommandSetMaxTxPowerPerBand:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            sme_process_set_max_tx_power_per_band(pMac,
                                                                     pCommand);
                            /* We need to re-run the command */
                            fContinue = eANI_BOOLEAN_TRUE;
                            /* No Rsp expected, free cmd from active list */
                            if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
                                        &pCommand->Link, LL_ACCESS_LOCK)) {
                               csrReleaseCommand(pMac, pCommand);
                            }
                            pMac->max_power_cmd_pending = false;
                            break;

#ifdef FEATURE_OEM_DATA_SUPPORT
                        case eSmeCommandOemDataReq:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            oemData_ProcessOemDataReqCommand(pMac, pCommand);
                            break;
#endif
                        case eSmeCommandRemainOnChannel:
                            csrLLUnlock(&pMac->sme.smeCmdActiveList);
                            p2pProcessRemainOnChannelCmd(pMac, pCommand);
                            break;
                        case eSmeCommandNoAUpdate:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            p2pProcessNoAReq(pMac,pCommand);
                            break;
                        case eSmeCommandEnterImps:
                        case eSmeCommandExitImps:
                        case eSmeCommandEnterBmps:
                        case eSmeCommandExitBmps:
                        case eSmeCommandEnterUapsd:
                        case eSmeCommandExitUapsd:
                        case eSmeCommandEnterWowl:
                        case eSmeCommandExitWowl:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            if(pMac->psOffloadEnabled)
                            {
                                fContinue =
                                  pmcOffloadProcessCommand(pMac, pCommand);
                            }
                            else
                            {
                                fContinue = pmcProcessCommand(pMac, pCommand);
                            }
                            if( fContinue )
                            {
                                //The command failed, remove it
                                if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                            &pCommand->Link, LL_ACCESS_LOCK ) )
                                {
                                    pmcReleaseCommand( pMac, pCommand );
                                }
                            }
                            break;

                        //Treat standby differently here because caller may not be able to handle
                        //the failure so we do our best here
                        case eSmeCommandEnterStandby:
                            if( csrIsConnStateDisconnected( pMac, pCommand->sessionId ) )
                            {
                                //It can continue
                                csrLLUnlock( &pMac->sme.smeCmdActiveList );
                                if(pMac->psOffloadEnabled)
                                {
                                    fContinue =
                                        pmcOffloadProcessCommand(pMac, pCommand);
                                }
                                else
                                {
                                    fContinue =
                                        pmcProcessCommand(pMac, pCommand);
                                }
                                if( fContinue )
                                {
                                    //The command failed, remove it
                                    if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                                &pCommand->Link, LL_ACCESS_LOCK ) )
                                    {
                                        pmcReleaseCommand( pMac, pCommand );
                                    }
                                }
                            }
                            else
                            {
                                //Need to issue a disconnect first before processing this command
                                tSmeCmd *pNewCmd;

                                //We need to re-run the command
                                fContinue = eANI_BOOLEAN_TRUE;
                                //Pull off the standby command first
                                if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                                &pCommand->Link, LL_ACCESS_NOLOCK ) )
                                {
                                    csrLLUnlock( &pMac->sme.smeCmdActiveList );
                                    //Need to call CSR function here because the disconnect command
                                    //is handled by CSR
                                    pNewCmd = csrGetCommandBuffer( pMac );
                                    if( NULL != pNewCmd )
                                    {
                                        //Put the standby command to the head of the pending list first
                                        csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCommand->Link,
                                                        LL_ACCESS_LOCK );
                                        pNewCmd->command = eSmeCommandRoam;
                                        pNewCmd->u.roamCmd.roamReason = eCsrForcedDisassoc;
                                        //Put the disassoc command before the standby command
                                        csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pNewCmd->Link,
                                                        LL_ACCESS_LOCK );
                                    }
                                    else
                                    {
                                        //Continue the command here
                                        if(pMac->psOffloadEnabled)
                                        {
                                            fContinue =
                                                 pmcOffloadProcessCommand(pMac,
                                                                     pCommand);
                                        }
                                        else
                                        {
                                            fContinue = pmcProcessCommand(pMac,
                                                                     pCommand);
                                        }
                                        if( fContinue )
                                        {
                                            //The command failed, remove it
                                            if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                                        &pCommand->Link, LL_ACCESS_LOCK ) )
                                            {
                                                pmcReleaseCommand( pMac, pCommand );
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    csrLLUnlock( &pMac->sme.smeCmdActiveList );
                                    smsLog( pMac, LOGE, FL(" failed to remove standby command") );
                                    VOS_ASSERT(0);
                                }
                            }
                            break;

                        case eSmeCommandAddTs:
                        case eSmeCommandDelTs:
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
                            fContinue = qosProcessCommand( pMac, pCommand );
                            if( fContinue )
                            {
                                //The command failed, remove it
                                if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList,
                                            &pCommand->Link, LL_ACCESS_NOLOCK ) )
                                {
//#ifndef WLAN_MDM_CODE_REDUCTION_OPT
                                    qosReleaseCommand( pMac, pCommand );
//#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/
                                }
                            }
#endif
                            break;
#ifdef FEATURE_WLAN_TDLS
                        case eSmeCommandTdlsSendMgmt:
                        case eSmeCommandTdlsAddPeer:
                        case eSmeCommandTdlsDelPeer:
                        case eSmeCommandTdlsLinkEstablish:
                            {
                                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                                        "sending TDLS Command 0x%x to PE", pCommand->command);

                                csrLLUnlock(&pMac->sme.smeCmdActiveList);
                                status = csrTdlsProcessCmd(pMac, pCommand);
                                if (!HAL_STATUS_SUCCESS(status)) {
                                    if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
                                                         &pCommand->Link,
                                                         LL_ACCESS_LOCK)) {
                                        vos_mem_zero(&pCommand->u.tdlsCmd,
                                                     sizeof(tTdlsCmd));
                                        csrReleaseCommand(pMac, pCommand);
                                    }
                                }
                            }
                            break ;
#endif

                        default:
                            //something is wrong
                            //remove it from the active list
                            smsLog(pMac, LOGE, " csrProcessCommand processes an unknown command %d", pCommand->command);
                            pEntry = csrLLRemoveHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK );
                            csrLLUnlock( &pMac->sme.smeCmdActiveList );
                            pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
                            smeReleaseCommand( pMac, pCommand );
                            status = eHAL_STATUS_FAILURE;
                            break;
                    }
                    if(!HAL_STATUS_SUCCESS(status))
                    {
                        fContinue = eANI_BOOLEAN_TRUE;
                    }
                }//if(pEntry)
                else
                {
                    //This is odd. Some one else pull off the command.
                    csrLLUnlock( &pMac->sme.smeCmdActiveList );
                    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                                "Remove entry failed");
                }
            }
            else
            {
                csrLLUnlock( &pMac->sme.smeCmdActiveList );
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                                "Get Pending command failed");
            }
        }
        else
        {
            //No command waiting
            csrLLUnlock( &pMac->sme.smeCmdActiveList );
            /*
             * This is only used to restart an idle mode scan,
             * it means at least one other idle scan has finished.
             * Moreover Idle Scan is not supported with power
             * save offload supported
             */
            if(!pMac->psOffloadEnabled &&
               pMac->scan.fRestartIdleScan &&
               eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
            {
                tANI_U32 nTime = 0;

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

sme_process_scan_queue:
    if (pMac->fScanOffload && !(smeProcessScanQueue(pMac)))
        fContinue = eANI_BOOLEAN_FALSE;

    return ( fContinue );
}

void smeProcessPendingQueue( tpAniSirGlobal pMac )
{
    while( smeProcessCommand( pMac ) );
}


tANI_BOOLEAN smeCommandPending(tpAniSirGlobal pMac)
{
    return ( !csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) ||
        !csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK) );
}

/**
 * sme_get_sessionid_from_activelist() - gets session id
 * @mac: mac context
 *
 * This function is used to get session id from sme command
 * active list
 *
 * Return: returns session id
 */
uint32_t sme_get_sessionid_from_activelist(tpAniSirGlobal mac)
{
	tListElem *entry;
	tSmeCmd *command;
	uint32_t session_id = 0;

	entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
	if (entry) {
		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
		session_id = command->sessionId;
	}

	return session_id;
}

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

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

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

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

	mac = PMAC_STRUCT(hal);
	smsLog(mac, LOG1, FL("size of buffer: %d"), *size);

	session_id = sme_get_sessionid_from_activelist(mac);

	len += vos_scnprintf(buf + len, *size - len,
		"\n active command sessionid %d", session_id);
	len += vos_scnprintf(buf + len, *size - len,
		"\n NeighborRoamState: %d",
		mac->roam.neighborRoamInfo[session_id].neighborRoamState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n RoamState: %d", mac->roam.curState[session_id]);
	len += vos_scnprintf(buf + len, *size - len,
		"\n RoamSubState: %d", mac->roam.curSubState[session_id]);
	len += vos_scnprintf(buf + len, *size - len,
		"\n ConnectState: %d",
		mac->roam.roamSession[session_id].connectState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n pmcState: %d", mac->pmc.pmcState);
	len += vos_scnprintf(buf + len, *size - len,
		"\n PmmState: %d", mac->pmm.gPmmState);

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

/**
 * sme_register_debug_callback() - registration function sme layer
 * to print sme state information
 *
 * Return: None
 */
static void sme_register_debug_callback(void)
{
	vos_register_debug_callback(VOS_MODULE_ID_SME, &sme_state_info_dump);
}

//Global APIs

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

  \brief sme_Open() - Initialize all SME modules and put them at idle state

  The function initializes each module inside SME, PMC, CCM, CSR, etc. . Upon
  successfully return, all modules are at idle state ready to start.

  smeOpen must be called before any other SME APIs can be involved.
  smeOpen must be called after macOpen.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.

  \return eHAL_STATUS_SUCCESS - SME is successfully initialized.

          Other status means SME is failed to be initialized
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_Open(tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   do {
      pMac->sme.state = SME_STATE_STOP;
      pMac->sme.currDeviceMode = VOS_STA_MODE;
      if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pMac->sme.lkSmeGlobalLock ) ) )
      {
          smsLog( pMac, LOGE, "sme_Open failed init lock" );
          status = eHAL_STATUS_FAILURE;
          break;
      }

      status = ccmOpen(hHal);
      if ( ! HAL_STATUS_SUCCESS( status ) ) {
         smsLog( pMac, LOGE,
                 "ccmOpen failed during initialization with status=%d", status );
         break;
      }

      status = csrOpen(pMac);
      if ( ! HAL_STATUS_SUCCESS( status ) ) {
         smsLog( pMac, LOGE,
                 "csrOpen failed during initialization with status=%d", status );
         break;
      }

      if(!pMac->psOffloadEnabled)
      {
          status = pmcOpen(hHal);
          if ( ! HAL_STATUS_SUCCESS( status ) ) {
             smsLog( pMac, LOGE,
                 "pmcOpen failed during initialization with status=%d",
                 status );
             break;
          }
      }
      else
      {
          status = pmcOffloadOpen(hHal);
          if (! HAL_STATUS_SUCCESS(status)) {
             smsLog( pMac, LOGE,
                 "pmcOffloadOpen failed during initialization with status=%d",
                 status );
             break;
          }
      }

#ifdef FEATURE_WLAN_TDLS
      pMac->isTdlsPowerSaveProhibited = 0;
#endif

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
      status = sme_QosOpen(pMac);
      if ( ! HAL_STATUS_SUCCESS( status ) ) {
         smsLog( pMac, LOGE,
                 "Qos open failed during initialization with status=%d", status );
         break;
      }

#endif
#ifdef FEATURE_OEM_DATA_SUPPORT
      status = oemData_OemDataReqOpen(pMac);
      if ( ! HAL_STATUS_SUCCESS( status ) ) {
         smsLog(pMac, LOGE,
                "oemData_OemDataReqOpen failed during initialization with status=%d", status );
         break;
      }
#endif

      if(!HAL_STATUS_SUCCESS((status = initSmeCmdList(pMac))))
          break;

#if defined WLAN_FEATURE_VOWIFI
      status = rrmOpen(pMac);
      if ( ! HAL_STATUS_SUCCESS( status ) ) {
         smsLog( pMac, LOGE,
                 "rrmOpen open failed during initialization with status=%d", status );
         break;
      }
#endif

      sme_p2pOpen(pMac);
      smeTraceInit(pMac);
      sme_register_debug_callback();

   }while (0);

   return status;
}

/*
 * sme_init_chan_list, triggers channel setup based on country code.
 */
eHalStatus sme_init_chan_list(tHalHandle hal, v_U8_t *alpha2,
                              COUNTRY_CODE_SOURCE cc_src)
{
    tpAniSirGlobal pmac = PMAC_STRUCT(hal);

    if ((cc_src == COUNTRY_CODE_SET_BY_USER) &&
        (pmac->roam.configParam.fSupplicantCountryCodeHasPriority))
    {
        pmac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE;
    }

    return csr_init_chan_list(pmac, alpha2);
}

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

  \brief sme_set11dinfo() - Set the 11d information about valid channels
   and there power using information from nvRAM
   This function is called only for AP.

  This is a synchronous call

  \param hHal - The handle returned by macOpen.
  \Param pSmeConfigParams - a pointer to a caller allocated object of
  typedef struct _smeConfigParams.

  \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully.

          Other status means SME is failed to update the config parameters.
  \sa
--------------------------------------------------------------------------*/

eHalStatus sme_set11dinfo(tHalHandle hHal,  tpSmeConfigParams pSmeConfigParams)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                      TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0));
   if (NULL == pSmeConfigParams ) {
      smsLog( pMac, LOGE,
              "Empty config param structure for SME, nothing to update");
      return status;
   }

   status = csrSetChannels(hHal, &pSmeConfigParams->csrConfig );
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d",
              status );
   }
    return status;
}

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

  \brief sme_getSoftApDomain() - Get the current regulatory domain of softAp.

  This is a synchronous call

  \param hHal - The handle returned by HostapdAdapter.
  \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp.

  \return eHAL_STATUS_SUCCESS - SME successfully completed the request.

          Other status means, failed to get the current regulatory domain.
  \sa
--------------------------------------------------------------------------*/

eHalStatus sme_getSoftApDomain(tHalHandle hHal,  v_REGDOMAIN_t *domainIdSoftAp)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, NO_SESSION, 0));
   if (NULL == domainIdSoftAp ) {
      smsLog( pMac, LOGE, "Uninitialized domain Id");
      return status;
   }

   *domainIdSoftAp = pMac->scan.domainIdCurrent;
   status = eHAL_STATUS_SUCCESS;

   return status;
}


eHalStatus sme_setRegInfo(tHalHandle hHal,  tANI_U8 *apCntryCode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0));
   if (NULL == apCntryCode ) {
      smsLog( pMac, LOGE, "Empty Country Code, nothing to update");
      return status;
   }

   status = csrSetRegInfo(hHal, apCntryCode );
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "csrSetRegInfo failed with status=%d",
              status );
   }
    return status;
}

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
eHalStatus sme_SetPlmRequest(tHalHandle hHal, tpSirPlmReq pPlmReq)
{
    eHalStatus status;
    tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
    tANI_U8 count, valid_count = 0;
    vos_msg_t msg;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
    {
        tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pPlmReq->sessionId );

        if(!pSession)
        {
            smsLog(pMac, LOGE, FL("session %d not found"), pPlmReq->sessionId);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        if( !pSession->sessionActive )
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s Invalid Sessionid", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        if (pPlmReq->enable) {

           /* validating channel numbers */
           for (count = 0; count < pPlmReq->plmNumCh; count++) {

              ret = csrIsSupportedChannel(pMac, pPlmReq->plmChList[count]);
              if (ret && pPlmReq->plmChList[count] > 14)
              {
                  if (NV_CHANNEL_DFS ==
                       vos_nv_getChannelEnabledState(pPlmReq->plmChList[count]))
                  {
                      /* DFS channel is provided, no PLM bursts can be
                      * transmitted. Ignoring these channels.
                      */
                      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                                "%s DFS channel %d ignored for PLM", __func__,
                                pPlmReq->plmChList[count]);
                      continue;
                  }
              }
              else if (!ret)
              {
                   /* Not supported, ignore the channel */
                   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                             "%s Unsupported channel %d ignored for PLM",
                             __func__, pPlmReq->plmChList[count]);
                   continue;
              }
              ch_list[valid_count] = pPlmReq->plmChList[count];
              valid_count++;
           } /* End of for () */

           /* Copying back the valid channel list to plm struct */
           vos_mem_set((void *)pPlmReq->plmChList, pPlmReq->plmNumCh, 0);
           if (valid_count)
              vos_mem_copy(pPlmReq->plmChList, ch_list, valid_count);
           /* All are invalid channels, FW need to send the PLM
           *  report with "incapable" bit set.
           */
           pPlmReq->plmNumCh = valid_count;
        } /* PLM START */

        msg.type     = WDA_SET_PLM_REQ;
        msg.reserved = 0;
        msg.bodyptr  = pPlmReq;

        if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: Not able to post WDA_SET_PLM_REQ message to WDA",
                      __func__);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return (status);
}
#endif

#ifdef FEATURE_WLAN_SCAN_PNO
/*--------------------------------------------------------------------------

  \brief sme_UpdateChannelConfig() - Update channel configuration in RIVA.

  It is used at driver start up to inform RIVA of the default channel
  configuration.

  This is a synchronous call

  \param hHal - The handle returned by macOpen.

  \return eHAL_STATUS_SUCCESS - SME update the channel config successfully.

          Other status means SME is failed to update the channel config.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_UpdateChannelConfig(tHalHandle hHal)
{
  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

  MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG, NO_SESSION, 0));
  pmcUpdateScanParams( pMac, &(pMac->roam.configParam),
                      &pMac->scan.base20MHzChannels, FALSE);
  return eHAL_STATUS_SUCCESS;
}
#endif // FEATURE_WLAN_SCAN_PNLO

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

  \brief sme_UpdateConfig() - Change configurations for all SME modules

  The function updates some configuration for modules in SME, CCM, CSR, etc
  during SMEs close open sequence.

  Modules inside SME apply the new configuration at the next transaction.

  This is a synchronous call

  \param hHal - The handle returned by macOpen.
  \Param pSmeConfigParams - a pointer to a caller allocated object of
  typedef struct _smeConfigParams.

  \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully.

          Other status means SME is failed to update the config parameters.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                   TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION, 0));
   if (NULL == pSmeConfigParams ) {
      smsLog( pMac, LOGE,
              "Empty config param structure for SME, nothing to update");
      return status;
   }

   status = csrChangeDefaultConfigParam(pMac, &pSmeConfigParams->csrConfig);

   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d",
              status );
   }
#if defined WLAN_FEATURE_VOWIFI
   status = rrmChangeDefaultConfigParam(hHal, &pSmeConfigParams->rrmConfig);

   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "rrmChangeDefaultConfigParam failed with status=%d",
              status );
   }
#endif
   //For SOC, CFG is set before start
   //We don't want to apply global CFG in connect state because that may cause some side affect
   if(
      csrIsAllSessionDisconnected( pMac) )
   {
       csrSetGlobalCfgs(pMac);
   }

   /* update the directed scan offload setting */
   pMac->fScanOffload = pSmeConfigParams->fScanOffload;

   if (pMac->fScanOffload)
   {
       /*
        * If scan offload is enabled then lim has allow the sending of
        * scan request to firmware even in power save mode. The firmware has
        * to take care of exiting from power save mode
        */
       status = ccmCfgSetInt(hHal, WNI_CFG_SCAN_IN_POWERSAVE,
                   eANI_BOOLEAN_TRUE, NULL, eANI_BOOLEAN_FALSE);

       if (eHAL_STATUS_SUCCESS != status)
       {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                   "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CCM");
       }
   }
   pMac->isCoalesingInIBSSAllowed =
         pSmeConfigParams->csrConfig.isCoalesingInIBSSAllowed;

   /* update the p2p listen offload setting */
   pMac->fP2pListenOffload = pSmeConfigParams->fP2pListenOffload;

   /* update p2p offload status */
   pMac->pnoOffload = pSmeConfigParams->pnoOffload;

   pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog;

   /* update interface configuration */
   pMac->sme.max_intf_count = pSmeConfigParams->max_intf_count;

   pMac->enable5gEBT = pSmeConfigParams->enable5gEBT;
   pMac->sme.enableSelfRecovery = pSmeConfigParams->enableSelfRecovery;

   pMac->f_sta_miracast_mcc_rest_time_val =
        pSmeConfigParams->f_sta_miracast_mcc_rest_time_val;

#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
   pMac->sap.sap_channel_avoidance = pSmeConfigParams->sap_channel_avoidance;
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */

   pMac->f_prefer_non_dfs_on_radar =
                       pSmeConfigParams->f_prefer_non_dfs_on_radar;
   pMac->fine_time_meas_cap = pSmeConfigParams->fine_time_meas_cap;

   pMac->snr_monitor_enabled = pSmeConfigParams->snr_monitor_enabled;
   pMac->sub20_config_info = pSmeConfigParams->sub20_config_info;
   pMac->sub20_channelwidth = pSmeConfigParams->sub20_channelwidth;
   pMac->sub20_dynamic_channelwidth =
       pSmeConfigParams->sub20_dynamic_channelwidth;

   pMac->sta_auth_retries_for_code17 =
         pSmeConfigParams->csrConfig.sta_auth_retries_for_code17;

   pMac->sta_change_cc_via_beacon =
         pSmeConfigParams->sta_change_cc_via_beacon;

   return status;
}

/**
 * sme_update_roam_params - Store/Update the roaming params
 * @hHal                    Handle for Hal layer
 * @session_id              SME Session ID
 * @roam_params_src         The source buffer to copy
 * @update_param            Type of parameter to be updated
 *
 * Return: Return the status of the updation.
 */
eHalStatus sme_update_roam_params(tHalHandle hHal,
	uint8_t session_id, struct roam_ext_params roam_params_src,
	int update_param)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	struct roam_ext_params *roam_params_dst;
	uint8_t i;

	roam_params_dst = &pMac->roam.configParam.roam_params;
	switch(update_param) {
	case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED:
		roam_params_dst->raise_rssi_thresh_5g =
			roam_params_src.raise_rssi_thresh_5g;
		roam_params_dst->drop_rssi_thresh_5g =
			roam_params_src.drop_rssi_thresh_5g;
		roam_params_dst->raise_factor_5g=
			roam_params_src.raise_factor_5g;
		roam_params_dst->drop_factor_5g =
			roam_params_src.drop_factor_5g;
		roam_params_dst->max_raise_rssi_5g =
			roam_params_src.max_raise_rssi_5g;
		roam_params_dst->max_drop_rssi_5g=
			roam_params_src.max_drop_rssi_5g;
		roam_params_dst->alert_rssi_threshold =
			roam_params_src.alert_rssi_threshold;
		roam_params_dst->is_5g_pref_enabled = true;
		break;
	case REASON_ROAM_SET_SSID_ALLOWED:
		vos_mem_set(&roam_params_dst->ssid_allowed_list, 0,
				sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST);
		roam_params_dst->num_ssid_allowed_list=
			roam_params_src.num_ssid_allowed_list;
		for (i=0; i<roam_params_dst->num_ssid_allowed_list; i++) {
			roam_params_dst->ssid_allowed_list[i].length =
				roam_params_src.ssid_allowed_list[i].length;
			vos_mem_copy(roam_params_dst->ssid_allowed_list[i].ssId,
				roam_params_src.ssid_allowed_list[i].ssId,
				roam_params_dst->ssid_allowed_list[i].length);
		}
		break;
	case REASON_ROAM_SET_FAVORED_BSSID:
		vos_mem_set(&roam_params_dst->bssid_favored, 0,
			sizeof(tSirMacAddr) * MAX_BSSID_FAVORED);
		roam_params_dst->num_bssid_favored=
			roam_params_src.num_bssid_favored;
		for (i=0; i<roam_params_dst->num_bssid_favored; i++) {
			vos_mem_copy(&roam_params_dst->bssid_favored[i],
				&roam_params_src.bssid_favored[i],
				sizeof(tSirMacAddr));
			roam_params_dst->bssid_favored_factor[i] =
				roam_params_src.bssid_favored_factor[i];
		}
		break;
	case REASON_ROAM_SET_BLACKLIST_BSSID:
		vos_mem_set(&roam_params_dst->bssid_avoid_list, 0,
			sizeof(tSirMacAddr) * MAX_BSSID_AVOID_LIST);
		roam_params_dst->num_bssid_avoid_list =
			roam_params_src.num_bssid_avoid_list;
		for (i=0; i<roam_params_dst->num_bssid_avoid_list; i++) {
			vos_mem_copy(&roam_params_dst->bssid_avoid_list[i],
				&roam_params_src.bssid_avoid_list[i],
				sizeof(tSirMacAddr));
		}
		break;
	case REASON_ROAM_GOOD_RSSI_CHANGED:
		roam_params_dst->good_rssi_roam =
			roam_params_src.good_rssi_roam;
		break;
	default:
		break;
	}
	csrRoamOffloadScan(pMac, session_id,
		ROAM_SCAN_OFFLOAD_UPDATE_CFG, update_param);
	return 0;
}
#ifdef WLAN_FEATURE_GTK_OFFLOAD
void sme_ProcessGetGtkInfoRsp( tHalHandle hHal,
                            tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (NULL == pMac)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
           "%s: pMac is null", __func__);
       return ;
   }
   if (pMac->pmc.GtkOffloadGetInfoCB == NULL)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
           "%s: HDD callback is null", __func__);
       return ;
   }
   pMac->pmc.GtkOffloadGetInfoCB(pMac->pmc.GtkOffloadGetInfoCBContext,
                                 pGtkOffloadGetInfoRsp);
}
#endif

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

  \fn    - sme_ProcessReadyToSuspend
  \brief - On getting ready to suspend indication, this function calls
           callback registered (HDD callbacks) with SME to inform
           ready to suspend indication.

  \param hHal - Handle returned by macOpen.
         pReadyToSuspend - Parameter received along with ready to suspend
                           indication from WMA.

  \return None

  \sa

  --------------------------------------------------------------------------*/
void sme_ProcessReadyToSuspend( tHalHandle hHal,
                                tpSirReadyToSuspendInd pReadyToSuspend)
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (NULL == pMac)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
           "%s: pMac is null", __func__);
       return ;
   }

   if (NULL != pMac->readyToSuspendCallback)
   {
       pMac->readyToSuspendCallback (pMac->readyToSuspendContext,
                                     pReadyToSuspend->suspended);
       pMac->readyToSuspendCallback = NULL;
   }
}

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
/*--------------------------------------------------------------------------

  \fn - sme_ProcessReadyToExtWoW
  \brief - On getting ready to Ext WoW indication, this function calls
             callback registered (HDD callbacks) with SME to inform
             ready to ExtWoW indication.

  \param hHal - Handle returned by macOpen.
   pReadyToExtWoW - Parameter received along with ready to Ext WoW
                                indication from WMA.

  \return None

  \sa

 --------------------------------------------------------------------------*/
void sme_ProcessReadyToExtWoW( tHalHandle hHal,
                                 tpSirReadyToExtWoWInd pReadyToExtWoW)
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (NULL == pMac)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
             "%s: pMac is null", __func__);
       return ;
   }

   if (NULL != pMac->readyToExtWoWCallback)
   {
       pMac->readyToExtWoWCallback (pMac->readyToExtWoWContext,
                                    pReadyToExtWoW->status);
       pMac->readyToExtWoWCallback = NULL;
       pMac->readyToExtWoWContext = NULL;
   }

}
#endif

/* ---------------------------------------------------------------------------
    \fn sme_ChangeConfigParams
    \brief The SME API exposed for HDD to provide config params to SME during
    SMEs stop -> start sequence.

    If HDD changed the domain that will cause a reset. This function will
    provide the new set of 11d information for the new domain. Currently this
    API provides info regarding 11d only at reset but we can extend this for
    other params (PMC, QoS) which needs to be initialized again at reset.

    This is a synchronous call

    \param hHal - The handle returned by macOpen.

    \Param
    pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that
                currently provides 11d related information like Country code,
                Regulatory domain, valid channel list, Tx power per channel, a
                list with active/passive scan allowed per valid channel.

    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ChangeConfigParams(tHalHandle hHal,
                                 tCsrUpdateConfigParam *pUpdateConfigParam)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (NULL == pUpdateConfigParam ) {
      smsLog( pMac, LOGE,
              "Empty config param structure for SME, nothing to reset");
      return status;
   }

   status = csrChangeConfigParams(pMac, pUpdateConfigParam);

   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "csrUpdateConfigParam failed with status=%d",
              status );
   }

   return status;

}

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

  \brief sme_HDDReadyInd() - SME sends eWNI_SME_SYS_READY_IND to PE to inform
  that the NIC is ready to run.

  The function is called by HDD at the end of initialization stage so PE/HAL can
  enable the NIC to running state.

  This is a synchronous call
  \param hHal - The handle returned by macOpen.

  \return eHAL_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE
                                successfully.

          Other status means SME failed to send the message to PE.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_HDDReadyInd(tHalHandle hHal)
{
   tSirSmeReadyReq Msg;
   eHalStatus status = eHAL_STATUS_FAILURE;
   tPmcPowerState powerState;
   tPmcSwitchState hwWlanSwitchState;
   tPmcSwitchState swWlanSwitchState;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                  TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0));
   do
   {

      Msg.messageType = eWNI_SME_SYS_READY_IND;
      Msg.length      = sizeof( tSirSmeReadyReq );

      if (eSIR_FAILURE != uMacPostCtrlMsg( hHal, (tSirMbMsg*)&Msg ))
      {
         status = eHAL_STATUS_SUCCESS;
      }
      else
      {
         smsLog( pMac, LOGE,
                 "uMacPostCtrlMsg failed to send eWNI_SME_SYS_READY_IND");
         break;
      }

      if(!pMac->psOffloadEnabled)
      {
         status = pmcQueryPowerState( hHal, &powerState,
                                     &hwWlanSwitchState, &swWlanSwitchState );
         if ( ! HAL_STATUS_SUCCESS( status ) )
         {
              smsLog( pMac, LOGE, "pmcQueryPowerState failed with status=%d",
                      status );
              break;
         }

         if ( (ePMC_SWITCH_OFF != hwWlanSwitchState) &&
              (ePMC_SWITCH_OFF != swWlanSwitchState) )
         {
             status = csrReady(pMac);
             if ( ! HAL_STATUS_SUCCESS( status ) )
             {
                 smsLog( pMac, LOGE, "csrReady failed with status=%d", status );
                 break;
             }
             status = pmcReady(hHal);
             if ( ! HAL_STATUS_SUCCESS( status ) )
             {
                 smsLog( pMac, LOGE, "pmcReady failed with status=%d", status );
                 break;
             }

#if defined WLAN_FEATURE_VOWIFI
             if(VOS_STATUS_SUCCESS != rrmReady(hHal))
             {
                 status = eHAL_STATUS_FAILURE;
                 smsLog( pMac, LOGE, "rrmReady failed");
                 break;
             }
#endif
         }
      }
      else
      {
          status = csrReady(pMac);
          if (!HAL_STATUS_SUCCESS(status))
          {
              smsLog( pMac, LOGE, "csrReady failed with status=%d", status );
              break;
          }

#if defined WLAN_FEATURE_VOWIFI
          if(VOS_STATUS_SUCCESS != rrmReady(hHal))
          {
              status = eHAL_STATUS_FAILURE;
              smsLog( pMac, LOGE, "rrmReady failed");
              break;
          }
#endif
      }
      pMac->sme.state = SME_STATE_READY;
   } while( 0 );

   return status;
}

/**
 * sme_set_allowed_action_frames() - Set allowed action frames to wma
 * @hal: Handler to HAL
 * @bitmap0: bitmap to set
 * @is_sta: boolean to indicate sta interface
 *
 * This function conveys the list of action frames that needs to be forwarded
 * to driver by FW. Rest of the action frames can be dropped in FW. Bitmask is
 * set with ALLOWED_ACTION_FRAMES_BITMAP0~7
 *
 * Return: None
 */
void sme_set_allowed_action_frames(tHalHandle hal,
				   uint32_t bitmap0, bool is_sta)
{
	eHalStatus status;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	vos_msg_t message;
	VOS_STATUS vos_status;
	struct sir_allowed_action_frames *sir_allowed_action_frames;

	sir_allowed_action_frames =
			vos_mem_malloc(sizeof(*sir_allowed_action_frames));
	if (!sir_allowed_action_frames) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"Not able to allocate memory for WDA_SET_ALLOWED_ACTION_FRAMES_IND");
		return;
	}

	vos_mem_zero(sir_allowed_action_frames,
			sizeof(*sir_allowed_action_frames));
	sir_allowed_action_frames->operation = WOW_ACTION_WAKEUP_OPERATION_SET;

	sir_allowed_action_frames->action_category_map[0] = bitmap0;
	sir_allowed_action_frames->action_category_map[1] =
				(ALLOWED_ACTION_FRAMES_BITMAP1);
	sir_allowed_action_frames->action_category_map[2] =
				(ALLOWED_ACTION_FRAMES_BITMAP2);
	sir_allowed_action_frames->action_category_map[3] =
				(ALLOWED_ACTION_FRAMES_BITMAP3);
	sir_allowed_action_frames->action_category_map[4] =
				(ALLOWED_ACTION_FRAMES_BITMAP4);
	sir_allowed_action_frames->action_category_map[5] =
				(ALLOWED_ACTION_FRAMES_BITMAP5);
	sir_allowed_action_frames->action_category_map[6] =
				(ALLOWED_ACTION_FRAMES_BITMAP6);
	sir_allowed_action_frames->action_category_map[7] =
				(ALLOWED_ACTION_FRAMES_BITMAP7);
	if (is_sta)
		sir_allowed_action_frames->
			action_per_category[SIR_MAC_ACTION_SPECTRUM_MGMT] =
			DROP_SPEC_MGMT_ACTION_FRAME_BITMAP;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		/* serialize the req through MC thread */
		message.bodyptr = sir_allowed_action_frames;
		message.type = SIR_HAL_SET_ALLOWED_ACTION_FRAMES;

		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &message);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"Not able to post SIR_HAL_SET_ALLOWED_ACTION_FRAMES message to HAL");
			vos_mem_free(sir_allowed_action_frames);
		}

		sme_ReleaseGlobalLock( &mac->sme );
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
			"sme_AcquireGlobalLock error", __func__);
		vos_mem_free(sir_allowed_action_frames);
	}

	return;
}

/**
 * sme_handle_cc_change_ind() - handle new country code
 * @hal_ptr: Handler to HAL
 * @msg_buf: contain new country code.
 *
 * Return: eHAL_STATUS_SUCCESS on success,
 * eHAL_STATUS_INVALID_PARAMETER on failure.
 */
eHalStatus sme_handle_cc_change_ind(tHalHandle hal_ptr, void *msg_buf)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal_ptr);
	v_REGDOMAIN_t domainId;
	struct sme_change_country_code_ind * change_cc_ind =
			 (struct sme_change_country_code_ind *)msg_buf;

	status =
		csrGetRegulatoryDomainForCountry(mac_ptr,
						 change_cc_ind->country_code,
						 &domainId, COUNTRY_IE);

	return (status);
}

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

  \brief sme_Start() - Put all SME modules at ready state.

  The function starts each module in SME, PMC, CCM, CSR, etc. . Upon
  successfully return, all modules are ready to run.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.

  \return eHAL_STATUS_SUCCESS - SME is ready.

          Other status means SME is failed to start
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_Start(tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   do
   {
      status = csrStart(pMac);
      if ( ! HAL_STATUS_SUCCESS( status ) ) {
         smsLog( pMac, LOGE, "csrStart failed during smeStart with status=%d",
                 status );
         break;
      }

      if(!pMac->psOffloadEnabled)
      {
          status = pmcStart(hHal);
          if ( ! HAL_STATUS_SUCCESS( status ) ) {
             smsLog( pMac, LOGE,
                     "pmcStart failed during smeStart with status=%d",
                     status );
             break;
          }
      }
      else
      {
          status = pmcOffloadStart(hHal);
          if ( ! HAL_STATUS_SUCCESS( status ) ) {
             smsLog( pMac, LOGE,
                     "pmcOffloadStart failed during smeStart with status=%d",
                     status );
             break;
          }
      }

      pMac->sme.state = SME_STATE_START;
   }while (0);

   sme_set_allowed_action_frames(hHal, ALLOWED_ACTION_FRAMES_BITMAP0_STA, true);

   return status;
}


#ifdef WLAN_FEATURE_PACKET_FILTERING
/******************************************************************************
*
* Name: sme_PCFilterMatchCountResponseHandler
*
* Description:
*    Invoke Packet Coalescing Filter Match Count callback routine
*
* Parameters:
*    hHal - HAL handle for device
*    pMsg - Pointer to tRcvFltPktMatchRsp structure
*
* Returns: eHalStatus
*
******************************************************************************/
eHalStatus sme_PCFilterMatchCountResponseHandler(tHalHandle hHal, void* pMsg)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp = (tpSirRcvFltPktMatchRsp)pMsg;

    if (NULL == pMsg)
    {
        smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
        status = eHAL_STATUS_FAILURE;
    }
    else
    {
        smsLog(pMac, LOG2, "SME: entering "
            "sme_FilterMatchCountResponseHandler");

        /* Call Packet Coalescing Filter Match Count callback routine. */
        if (pMac->pmc.FilterMatchCountCB != NULL)
           pMac->pmc.FilterMatchCountCB(pMac->pmc.FilterMatchCountCBContext,
                                          pRcvFltPktMatchRsp);

        smsLog(pMac, LOG1, "%s: status=0x%x", __func__,
               pRcvFltPktMatchRsp->status);

        pMac->pmc.FilterMatchCountCB = NULL;
        pMac->pmc.FilterMatchCountCBContext = NULL;
    }

    return(status);
}
#endif // WLAN_FEATURE_PACKET_FILTERING


#ifdef WLAN_FEATURE_11W
/*------------------------------------------------------------------
 *
 * Handle the unprotected management frame indication from LIM and
 * forward it to HDD.
 *
 *------------------------------------------------------------------*/

eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
                                      tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
{
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	eHalStatus  status = eHAL_STATUS_SUCCESS;
	tCsrRoamInfo *roam_info;
	tANI_U32 SessionId = pSmeMgmtFrm->sessionId;

	roam_info = vos_mem_malloc(sizeof(*roam_info));
	if (!roam_info)
		return eHAL_STATUS_FAILED_ALLOC;
	roam_info->nFrameLength = pSmeMgmtFrm->frameLen;
	roam_info->pbFrames = pSmeMgmtFrm->frameBuf;
	roam_info->frameType = pSmeMgmtFrm->frameType;

	/* forward the mgmt frame to HDD */
	csrRoamCallCallback(pMac, SessionId, roam_info, 0,
			    eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
	vos_mem_free(roam_info);

	return status;
}
#endif

/*------------------------------------------------------------------
 *
 * Handle the DFS Radar Event and indicate it to the SAP
 *
 *------------------------------------------------------------------*/
eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, void *pMsgBuf)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tCsrRoamInfo *roam_info;
    tSirSmeDfsEventInd *dfs_event;
    tSirSmeCSAIeTxCompleteRsp *csaIeTxCompleteRsp;
    tANI_U32 sessionId = 0;
    eRoamCmdStatus roamStatus;
    eCsrRoamResult roamResult;
    int i;

    roam_info = vos_mem_malloc(sizeof(*roam_info));
    if (!roam_info)
        return eHAL_STATUS_FAILED_ALLOC;

    switch (msgType)
    {
      case eWNI_SME_DFS_RADAR_FOUND:
      {
         /* Radar found !! */
         dfs_event = (tSirSmeDfsEventInd *)pMsgBuf;
         if (NULL == dfs_event)
         {
            smsLog(pMac, LOGE,
                   "%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message",
                   __func__);
            vos_mem_free(roam_info);
            return eHAL_STATUS_FAILURE;
         }
         sessionId = dfs_event->sessionId;
         roam_info->dfs_event.sessionId = sessionId;
         roam_info->dfs_event.chan_list.nchannels =
             dfs_event->chan_list.nchannels;
         for (i = 0; i < dfs_event->chan_list.nchannels; i++)
         {
             roam_info->dfs_event.chan_list.channels[i] =
                 dfs_event->chan_list.channels[i];
         }

         roam_info->dfs_event.dfs_radar_status = dfs_event->dfs_radar_status;
         roam_info->dfs_event.use_nol = dfs_event->use_nol;

         roamStatus = eCSR_ROAM_DFS_RADAR_IND;
         roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
                   "sapdfs: Radar indication event occurred");
         break;
      }
      case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
      {
         csaIeTxCompleteRsp = (tSirSmeCSAIeTxCompleteRsp *)pMsgBuf;
         if (NULL == csaIeTxCompleteRsp)
         {
            smsLog(pMac, LOGE,
                   "%s: pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND",
                   __func__);
            vos_mem_free(roam_info);
            return eHAL_STATUS_FAILURE;
         }
         sessionId = csaIeTxCompleteRsp->sessionId;
         roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY;
         roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS;
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
         "sapdfs: Received eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND for session id [%d]",
                   sessionId );
         break;
      }
      default:
      {
         smsLog(pMac, LOG1, "%s: Invalid DFS message = 0x%x", __func__,
                msgType);
         status = eHAL_STATUS_FAILURE;
         vos_mem_free(roam_info);
         return status;
      }
    }

    /* Indicate Radar Event to SAP */
    csrRoamCallCallback(pMac, sessionId, roam_info, 0,
                        roamStatus, roamResult);
    vos_mem_free(roam_info);

    return status;
}

/**
 * sme_extended_change_channel_ind()- function to indicate ECSA
 * action frame is received in lim to SAP
 * @mac_ctx:  pointer to global mac structure
 * @msg_buf: contain new channel and session id.
 *
 * This function is called to post ECSA action frame
 * receive event to SAP.
 *
 * Return: success if msg indicated to SAP else return failure
 */
static eHalStatus sme_extended_change_channel_ind(tpAniSirGlobal mac_ctx,
						void *msg_buf)
{
	struct sir_sme_ext_cng_chan_ind *ext_chan_ind;
	eHalStatus status = eHAL_STATUS_SUCCESS;
	uint32_t session_id = 0;
	tCsrRoamInfo *roam_info;
	eRoamCmdStatus roamStatus;
	eCsrRoamResult roamResult;


	ext_chan_ind = msg_buf;
	if (NULL == ext_chan_ind) {
		smsLog(mac_ctx, LOGE,
			FL("pMsg is NULL for eWNI_SME_EXT_CHANGE_CHANNEL_IND"));
		return eHAL_STATUS_FAILURE;
	}
	roam_info = vos_mem_malloc(sizeof(*roam_info));
	if (!roam_info)
		return eHAL_STATUS_FAILED_ALLOC;
	session_id = ext_chan_ind->session_id;
	roam_info->target_channel = ext_chan_ind->new_channel;
	roamStatus = eCSR_ROAM_EXT_CHG_CHNL_IND;
	roamResult = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND;
	smsLog(mac_ctx, LOG1,
		FL("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]"),
		session_id);

	/* Indicate Ext Channel Change event to SAP */
	csrRoamCallCallback(mac_ctx, session_id, roam_info, 0,
					roamStatus, roamResult);
	vos_mem_free(roam_info);

	return status;
}

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/*------------------------------------------------------------------
 *
 * Handle the tsm ie indication from  LIM and forward it to HDD.
 *
 *------------------------------------------------------------------*/
eHalStatus sme_TsmIeInd(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd)
{
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	eHalStatus     status = eHAL_STATUS_SUCCESS;
	tCsrRoamInfo   *roam_info;
	tANI_U32       SessionId = pSmeTsmIeInd->sessionId;

	roam_info = vos_mem_malloc(sizeof(*roam_info));
	if (!roam_info)
		return eHAL_STATUS_FAILED_ALLOC;
	roam_info->tsmIe.tsid= pSmeTsmIeInd->tsmIe.tsid;
	roam_info->tsmIe.state= pSmeTsmIeInd->tsmIe.state;
	roam_info->tsmIe.msmt_interval= pSmeTsmIeInd->tsmIe.msmt_interval;
	/* forward the tsm ie information to HDD */
	csrRoamCallCallback(pMac,
	                    SessionId,
	                    roam_info,
	                    0,
	                    eCSR_ROAM_TSM_IE_IND,
	                    0);
	vos_mem_free(roam_info);

	return status;
}
/* ---------------------------------------------------------------------------
    \fn sme_SetCCKMIe
    \brief  function to store the CCKM IE passed from supplicant and use
    it while packing reassociation request
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  pCckmIe - pointer to CCKM IE data
    \param  pCckmIeLen - length of the CCKM IE
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_SetCCKMIe(tHalHandle hHal, tANI_U8 sessionId,
                              tANI_U8 *pCckmIe, tANI_U8 cckmIeLen)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        csrSetCCKMIe(pMac, sessionId, pCckmIe, cckmIeLen);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_SetEseBeaconRequest
    \brief  function to set ESE beacon request parameters
    \param  hHal       - HAL handle for device
    \param  sessionId  - Session id
    \param  pEseBcnReq - pointer to ESE beacon request
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_SetEseBeaconRequest(tHalHandle hHal, const tANI_U8 sessionId,
                                   const tCsrEseBeaconReq* pEseBcnReq)
{
   eHalStatus               status           = eSIR_SUCCESS;
   tpAniSirGlobal           pMac             = PMAC_STRUCT( hHal );
   tpSirBeaconReportReqInd  pSmeBcnReportReq = NULL;
   tCsrEseBeaconReqParams  *pBeaconReq       = NULL;
   tANI_U8                  counter          = 0;
   tCsrRoamSession         *pSession         = CSR_GET_SESSION(pMac, sessionId);
   tpRrmSMEContext          pSmeRrmContext   = &pMac->rrm.rrmSmeContext;

   if (pSmeRrmContext->eseBcnReqInProgress == TRUE)
   {
      smsLog(pMac, LOGE, "A Beacon Report Req is already in progress");
      return eHAL_STATUS_RESOURCES;
   }

   /* Store the info in RRM context */
   vos_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq, sizeof(tCsrEseBeaconReq));

   //Prepare the request to send to SME.
   pSmeBcnReportReq = vos_mem_malloc(sizeof( tSirBeaconReportReqInd ));
   if(NULL == pSmeBcnReportReq)
   {
      smsLog(pMac, LOGP, "Memory Allocation Failure!!! ESE  BcnReq Ind to SME");
      return eSIR_FAILURE;
   }

   pSmeRrmContext->eseBcnReqInProgress = TRUE;

   smsLog(pMac, LOGE, "Sending Beacon Report Req to SME");
   vos_mem_zero( pSmeBcnReportReq, sizeof( tSirBeaconReportReqInd ));

   pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
   pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd );
   vos_mem_copy( pSmeBcnReportReq->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
   pSmeBcnReportReq->channelInfo.channelNum = 255;
   pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe;
   pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD;

   for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++)
   {
        pBeaconReq = (tCsrEseBeaconReqParams *)&pEseBcnReq->bcnReq[counter];
        pSmeBcnReportReq->fMeasurementtype[counter] = pBeaconReq->scanMode;
        pSmeBcnReportReq->measurementDuration[counter] = SYS_TU_TO_MS(pBeaconReq->measurementDuration);
        pSmeBcnReportReq->channelList.channelNumber[counter] = pBeaconReq->channel;
   }

   status = sme_RrmProcessBeaconReportReqInd(pMac, pSmeBcnReportReq);

   if(status != eHAL_STATUS_SUCCESS)
      pSmeRrmContext->eseBcnReqInProgress = FALSE;

   vos_mem_free(pSmeBcnReportReq);
   return status;
}

#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
eHalStatus sme_IbssPeerInfoResponseHandleer( tHalHandle hHal,
                                      tpSirIbssGetPeerInfoRspParams pIbssPeerInfoParams)
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (NULL == pMac)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
           "%s: pMac is null", __func__);
       return eHAL_STATUS_FAILURE;
   }
   if (pMac->sme.peerInfoParams.peerInfoCbk == NULL)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
           "%s: HDD callback is null", __func__);
       return eHAL_STATUS_FAILURE;
   }
   pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData,
                                        &pIbssPeerInfoParams->ibssPeerInfoRspParams);
   return eHAL_STATUS_SUCCESS;
}

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

  \brief sme_ProcessMsg() - The main message processor for SME.

  The function is called by a message dispatcher when to process a message
  targeted for SME.

  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param pMsg - A pointer to a caller allocated object of tSirMsgQ.

  \return eHAL_STATUS_SUCCESS - SME successfully process the message.

          Other status means SME failed to process the message to HAL.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (pMsg == NULL) {
      smsLog( pMac, LOGE, "Empty message for SME, nothing to process");
      return status;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( SME_IS_START(pMac) )
      {
          switch (pMsg->type) { // TODO: Will be modified to do a range check for msgs instead of having cases for each msgs
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
          case eWNI_SME_HO_FAIL_IND:
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "LFR3:%s: Rcvd eWNI_SME_HO_FAIL_IND", __func__);
               csrProcessHOFailInd(pMac, pMsg->bodyptr);
               vos_mem_free(pMsg->bodyptr);
               break;
	  case eWNI_SME_ROAM_OFFLOAD_SYNCH_IND:
	       csrProcessRoamOffloadSynchInd(pMac,
			       (tpSirRoamOffloadSynchInd)pMsg->bodyptr);
               vos_mem_free(pMsg->bodyptr);
	       break;
#endif
          case eWNI_PMC_ENTER_BMPS_RSP:
          case eWNI_PMC_EXIT_BMPS_RSP:
          case eWNI_PMC_EXIT_BMPS_IND:
          case eWNI_PMC_ENTER_IMPS_RSP:
          case eWNI_PMC_EXIT_IMPS_RSP:
          case eWNI_PMC_SMPS_STATE_IND:
          case eWNI_PMC_ENTER_UAPSD_RSP:
          case eWNI_PMC_EXIT_UAPSD_RSP:
          case eWNI_PMC_ENTER_WOWL_RSP:
          case eWNI_PMC_EXIT_WOWL_RSP:
             //PMC
             if (pMsg->bodyptr)
             {
                if(!pMac->psOffloadEnabled)
                {
                    pmcMessageProcessor(hHal, pMsg->bodyptr);
                }
                else
                {
                    pmcOffloadMessageProcessor(hHal, pMsg->bodyptr);
                }
                status = eHAL_STATUS_SUCCESS;
                vos_mem_free(pMsg->bodyptr);
             } else {
                smsLog( pMac, LOGE, "Empty rsp message for PMC, nothing to process");
             }
             break;

          case WNI_CFG_SET_CNF:
          case WNI_CFG_DNLD_CNF:
          case WNI_CFG_GET_RSP:
          case WNI_CFG_ADD_GRP_ADDR_CNF:
          case WNI_CFG_DEL_GRP_ADDR_CNF:
             //CCM
             if (pMsg->bodyptr)
             {
                ccmCfgCnfMsgHandler(hHal, pMsg->bodyptr);
                status = eHAL_STATUS_SUCCESS;
                vos_mem_free(pMsg->bodyptr);
             } else {
                smsLog( pMac, LOGE, "Empty rsp message for CCM, nothing to process");
             }
             break;

          case eWNI_SME_ADDTS_RSP:
          case eWNI_SME_DELTS_RSP:
          case eWNI_SME_DELTS_IND:
#ifdef WLAN_FEATURE_VOWIFI_11R
          case eWNI_SME_FT_AGGR_QOS_RSP:
#endif
             //QoS
             if (pMsg->bodyptr)
             {
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
                status = sme_QosMsgProcessor(pMac, pMsg->type, pMsg->bodyptr);
                vos_mem_free(pMsg->bodyptr);
#endif
             } else {
                smsLog( pMac, LOGE, "Empty rsp message for QoS, nothing to process");
             }
             break;
#if defined WLAN_FEATURE_VOWIFI
          case eWNI_SME_NEIGHBOR_REPORT_IND:
          case eWNI_SME_BEACON_REPORT_REQ_IND:
#if defined WLAN_VOWIFI_DEBUG
             smsLog( pMac, LOGE, "Received RRM message. Message Id = %d", pMsg->type );
#endif
             if ( pMsg->bodyptr )
             {
                status = sme_RrmMsgProcessor( pMac, pMsg->type, pMsg->bodyptr );
                vos_mem_free(pMsg->bodyptr);
             }
             else
             {
                smsLog( pMac, LOGE, "Empty message for RRM, nothing to process");
             }
             break;
#endif

#ifdef FEATURE_OEM_DATA_SUPPORT
          //Handle the eWNI_SME_OEM_DATA_RSP:
          case eWNI_SME_OEM_DATA_RSP:
                if(pMsg->bodyptr)
                {
                        status = sme_HandleOemDataRsp(pMac, pMsg->bodyptr);
                        vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                        smsLog( pMac, LOGE, "Empty rsp message for oemData_ (eWNI_SME_OEM_DATA_RSP), nothing to process");
                }
                smeProcessPendingQueue( pMac );
                break;
#endif

          case eWNI_SME_ADD_STA_SELF_RSP:
                if(pMsg->bodyptr)
                {
                   status = csrProcessAddStaSessionRsp(pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ADD_STA_SELF_RSP), nothing to process");
                }
                break;
          case eWNI_SME_DEL_STA_SELF_RSP:
                if(pMsg->bodyptr)
                {
                   status = csrProcessDelStaSessionRsp(pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_DEL_STA_SELF_RSP), nothing to process");
                }
                break;
          case eWNI_SME_REMAIN_ON_CHN_RSP:
                if(pMsg->bodyptr)
                {
                    status = sme_remainOnChnRsp(pMac, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                    smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RSP), nothing to process");
                }
                break;
          case eWNI_SME_REMAIN_ON_CHN_RDY_IND:
                if(pMsg->bodyptr)
                {
                    status = sme_remainOnChnReady(pMac, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                    smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RDY_IND), nothing to process");
                }
                break;

#ifdef FEATURE_WLAN_SCAN_PNO
          case eWNI_SME_PREF_NETWORK_FOUND_IND:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                              NO_SESSION, pMsg->type));
                if(pMsg->bodyptr)
                {
                   status = sme_PreferredNetworkFoundInd((void *)pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_PREF_NETWORK_FOUND_IND), nothing to process");
                }
                break;
#endif // FEATURE_WLAN_SCAN_PNO

          case eWNI_SME_TX_PER_HIT_IND:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                              NO_SESSION, pMsg->type));
                if (pMac->sme.pTxPerHitCallback)
                {
                   pMac->sme.pTxPerHitCallback(pMac->sme.pTxPerHitCbContext);
                }
                break;

          case eWNI_SME_CHANGE_COUNTRY_CODE:
              if(pMsg->bodyptr)
                {
                   status = sme_HandleChangeCountryCode((void *)pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                    smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_CHANGE_COUNTRY_CODE), nothing to process");
                }
                break;

          case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE:
              if (pMsg->bodyptr)
                {
                    status = sme_HandleGenericChangeCountryCode((void *)pMac, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE), nothing to process");
                }
                break;

#ifdef WLAN_FEATURE_PACKET_FILTERING
          case eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                              NO_SESSION, pMsg->type));
                if(pMsg->bodyptr)
                {
                   status = sme_PCFilterMatchCountResponseHandler((void *)pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog(pMac, LOGE, "Empty rsp message for meas "
                          "(PACKET_COALESCING_FILTER_MATCH_COUNT_RSP), nothing to process");
                }
                break;
#endif // WLAN_FEATURE_PACKET_FILTERING
          case eWNI_SME_PRE_SWITCH_CHL_IND:
                if(pMsg->bodyptr)
                {
                   status = sme_HandlePreChannelSwitchInd(pMac,pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog(pMac, LOGE, "Empty rsp message for meas "
                          "(eWNI_SME_PRE_SWITCH_CHL_IND), nothing to process");
                }
                break;
          case eWNI_SME_CC_CHANGE_IND:
                if(pMsg->bodyptr)
                {
                   status = sme_handle_cc_change_ind(pMac,pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog(pMac, LOGE, "Empty rsp message for meas "
                          "(eWNI_SME_CC_CHANGE_IND), nothing to process");
                }
                break;
          case eWNI_SME_POST_SWITCH_CHL_IND:
             {
                status = sme_HandlePostChannelSwitchInd(pMac);
                break;
             }

#ifdef WLAN_WAKEUP_EVENTS
          case eWNI_SME_WAKE_REASON_IND:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                              NO_SESSION, pMsg->type));
                if(pMsg->bodyptr)
                {
                   status = sme_WakeReasonIndCallback((void *)pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_WAKE_REASON_IND), nothing to process");
                }
                break;
#endif // WLAN_WAKEUP_EVENTS

#ifdef FEATURE_WLAN_TDLS
          /*
           * command received from PE, SME tdls msg processor shall be called
           * to process commands received from PE
           */
          case eWNI_SME_TDLS_SEND_MGMT_RSP:
          case eWNI_SME_TDLS_ADD_STA_RSP:
          case eWNI_SME_TDLS_DEL_STA_RSP:
          case eWNI_SME_TDLS_DEL_STA_IND:
          case eWNI_SME_TDLS_DEL_ALL_PEER_IND:
          case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND:
          case eWNI_SME_TDLS_LINK_ESTABLISH_RSP:
          case eWNI_SME_TDLS_SHOULD_DISCOVER:
          case eWNI_SME_TDLS_SHOULD_TEARDOWN:
          case eWNI_SME_TDLS_PEER_DISCONNECTED:
                {
                    if (pMsg->bodyptr)
                    {
                        status = tdlsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr);
                        vos_mem_free(pMsg->bodyptr);
                    }
                    else
                    {
                        smsLog( pMac, LOGE,
                                "Empty rsp message for TDLS, nothing to process");
                    }
                    break;
                }
#endif

#ifdef WLAN_FEATURE_11W
           case eWNI_SME_UNPROT_MGMT_FRM_IND:
                if (pMsg->bodyptr)
                {
                    sme_UnprotectedMgmtFrmInd(pMac, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                    smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_UNPROT_MGMT_FRM_IND), nothing to process");
                }
                break;
#endif
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
       case eWNI_SME_TSM_IE_IND:
       {
        if (pMsg->bodyptr)
        {
            sme_TsmIeInd(pMac, pMsg->bodyptr);
            vos_mem_free(pMsg->bodyptr);
        }
        else
        {
            smsLog(pMac, LOGE,
            "Empty rsp message for (eWNI_SME_TSM_IE_IND), nothing to process");
        }
        break;
       }
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
          case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP:
                status = csrRoamOffloadScanRspHdlr((void *)pMac, pMsg->bodyptr);
                vos_mem_free(pMsg->bodyptr);
                break;
#endif // WLAN_FEATURE_ROAM_SCAN_OFFLOAD

#ifdef WLAN_FEATURE_GTK_OFFLOAD
           case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                               NO_SESSION, pMsg->type));
                if (pMsg->bodyptr)
                {
                    sme_ProcessGetGtkInfoRsp(pMac, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                    smsLog(pMac, LOGE, "Empty rsp message for (eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP), nothing to process");
                }
                break ;
#endif

#ifdef FEATURE_WLAN_LPHB
          /* LPHB timeout indication arrived, send IND to client */
          case eWNI_SME_LPHB_IND:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                              NO_SESSION, pMsg->type));
                if (pMac->sme.pLphbIndCb)
                {
                   pMac->sme.pLphbIndCb(pMac->hHdd, pMsg->bodyptr);
                }
                vos_mem_free(pMsg->bodyptr);

                break;
#endif /* FEATURE_WLAN_LPHB */

          case eWNI_SME_IBSS_PEER_INFO_RSP:
              MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                            NO_SESSION, pMsg->type));
              if (pMsg->bodyptr)
              {
                  sme_IbssPeerInfoResponseHandleer(pMac, pMsg->bodyptr);
                  vos_mem_free(pMsg->bodyptr);
              }
              else
              {
                  smsLog(pMac, LOGE,
                         "Empty rsp message for (eWNI_SME_IBSS_PEER_INFO_RSP),"
                         " nothing to process");
              }
              break ;

           case eWNI_SME_READY_TO_SUSPEND_IND:
                if (pMsg->bodyptr)
                {
                    sme_ProcessReadyToSuspend(pMac, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                    smsLog(pMac, LOGE, "Empty rsp message for (eWNI_SME_READY_TO_SUSPEND_IND), nothing to process");
                }
                break ;

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
           case eWNI_SME_READY_TO_EXTWOW_IND:
                if (pMsg->bodyptr)
                {
                     sme_ProcessReadyToExtWoW(pMac, pMsg->bodyptr);
                     vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                     smsLog(pMac, LOGE, "Empty rsp message"
                     "for (eWNI_SME_READY_TO_EXTWOW_IND), nothing to process");
                }
                break ;
#endif

#ifdef FEATURE_WLAN_CH_AVOID
           /* channel avoid message arrived, send IND to client */
           case eWNI_SME_CH_AVOID_IND:
                MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                              NO_SESSION, pMsg->type));
                if (pMac->sme.pChAvoidNotificationCb)
                {
                   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                             "%s: CH avoid notification", __func__);
                   pMac->sme.pChAvoidNotificationCb(pMac->hHdd, pMsg->bodyptr);
                }
                vos_mem_free(pMsg->bodyptr);
                break;
#endif /* FEATURE_WLAN_CH_AVOID */

#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
           case eWNI_SME_AUTO_SHUTDOWN_IND:
                if (pMac->sme.pAutoShutdownNotificationCb)
                {
                   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                             "%s: Auto shutdown notification", __func__);
                   pMac->sme.pAutoShutdownNotificationCb();
                }
                vos_mem_free(pMsg->bodyptr);
                break;
#endif
           case eWNI_SME_DFS_RADAR_FOUND:
           case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
                {
                    status = dfsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr);
                    vos_mem_free( pMsg->bodyptr );
                }
                break;
           case eWNI_SME_EXT_CHANGE_CHANNEL_IND:
                status = sme_extended_change_channel_ind(pMac, pMsg->bodyptr);
                vos_mem_free(pMsg->bodyptr);
                break;
           case eWNI_SME_CHANNEL_CHANGE_RSP:
                if (pMsg->bodyptr)
                {
                    status = sme_ProcessChannelChangeResp(pMac,
                                           pMsg->type, pMsg->bodyptr);
                    vos_mem_free( pMsg->bodyptr );
                }
                else
                {
                    smsLog( pMac, LOGE,
                            "Empty rsp message for (eWNI_SME_CHANNEL_CHANGE_RSP),"
                            "nothing to process");
                }
                break ;

#ifdef WLAN_FEATURE_STATS_EXT
          case eWNI_SME_STATS_EXT_EVENT:
              if (pMsg->bodyptr)
              {
                  status = sme_StatsExtEvent(hHal, pMsg->bodyptr);
                  vos_mem_free(pMsg->bodyptr);
              }
              else
              {
                  smsLog( pMac, LOGE,
                          "Empty event message for eWNI_SME_STATS_EXT_EVENT, nothing to process");
              }
              break;
#endif
          case eWNI_SME_LINK_SPEED_IND:
               if (pMac->sme.pLinkSpeedIndCb)
               {
                   pMac->sme.pLinkSpeedIndCb(pMsg->bodyptr,
                                             pMac->sme.pLinkSpeedCbContext);
               }
               if (pMsg->bodyptr)
               {
                   vos_mem_free(pMsg->bodyptr);
               }
               break;
          case eWNI_SME_GET_PEER_INFO_IND:
               if (pMac->sme.pget_peer_info_ind_cb)
                   pMac->sme.pget_peer_info_ind_cb(pMsg->bodyptr,
                                        pMac->sme.pget_peer_info_cb_context);
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_GET_PEER_INFO_EXT_IND:
               if (pMac->sme.pget_peer_info_ext_ind_cb)
                   pMac->sme.pget_peer_info_ext_ind_cb(pMsg->bodyptr,
                       pMac->sme.pget_peer_info_ext_cb_context);
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_CSA_OFFLOAD_EVENT:
               if (pMsg->bodyptr)
               {
#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
                   /*Indicate to HostApd*/
                   if(pMac->sme.pCSASAPIndCb)
                   {
                        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                             "%s: CSA Notification to SAP", __func__);
                        pMac->sme.pCSASAPIndCb(pMac->hHdd, pMsg->bodyptr);
                   }
#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
                   csrScanFlushBssEntry(pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
               }
               break;
          case eWNI_SME_TSF_EVENT:
               if (pMac->sme.get_tsf_cb) {
                   pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt,
                                      (struct stsf *)pMsg->bodyptr);
               }
               if (pMsg->bodyptr) {
                   vos_mem_free(pMsg->bodyptr);
                   pMsg->bodyptr = NULL;
               }
               break;
#ifdef WLAN_FEATURE_MOTION_DETECTION
          case eWNI_SME_MOTION_DET_HOST_EVENT:
               if (pMsg->bodyptr) {
                   if (pMac->sme.mt_host_ev_cb) {
                       pMac->sme.mt_host_ev_cb(pMac->hHdd,
                                               (tSirMtEvent *)pMsg->bodyptr);
                   }

                   vos_mem_free(pMsg->bodyptr);
                   pMsg->bodyptr = NULL;
               }
               break;
#endif
#ifdef WLAN_FEATURE_NAN
          case eWNI_SME_NAN_EVENT:
              MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG,
                                            NO_SESSION, pMsg->type));
                if (pMsg->bodyptr)
                {
                    sme_NanEvent(hHal, pMsg->bodyptr);
                    vos_mem_free(pMsg->bodyptr);
                }
                break;
#endif /* WLAN_FEATURE_NAN */
          case eWNI_SME_LINK_STATUS_IND:
          {
                tAniGetLinkStatus *pLinkStatus =
                             (tAniGetLinkStatus *) pMsg->bodyptr;
                if (pLinkStatus) {
                    if (pMac->sme.linkStatusCallback) {
                        pMac->sme.linkStatusCallback(pLinkStatus->linkStatus,
                                               pMac->sme.linkStatusContext);
                    }

                    pMac->sme.linkStatusCallback = NULL;
                    pMac->sme.linkStatusContext = NULL;
                    vos_mem_free(pLinkStatus);
                }
                break;
          }
          case eWNI_SME_MSG_GET_TEMPERATURE_IND:
               if (pMac->sme.pGetTemperatureCb)
               {
                   pMac->sme.pGetTemperatureCb(pMsg->bodyval,
                           pMac->sme.pTemperatureCbContext);
               }
               break;
          case eWNI_SME_SNR_IND:
          {
                tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr;
                if (pSnrReq) {
                    if (pSnrReq->snrCallback) {
                        ((tCsrSnrCallback)(pSnrReq->snrCallback))(pSnrReq->snr,
                                                    pSnrReq->staId,
                                                    pSnrReq->pDevContext);
                    }

                    vos_mem_free(pSnrReq);
                }
                break;
          }
#ifdef FEATURE_WLAN_EXTSCAN
          case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND:
          {
                tCsrRoamInfo *roam_info;
                tpSirWifiFullScanResultEvent result =
                             (tpSirWifiFullScanResultEvent) pMsg->bodyptr;

                roam_info = vos_mem_malloc(sizeof(*roam_info));
                if (roam_info) {
                    vos_mem_zero(roam_info, sizeof(*roam_info));
		    roam_info->pBssDesc = (tSirBssDescription *)(
		    (uint8_t *)&result->bss_description+result->ap.ieLength);
                    csrRoamCallCallback(pMac, 0, roam_info, 0,
                        eCSR_ROAM_UPDATE_SCAN_RESULT, eCSR_ROAM_RESULT_NONE);
                    vos_mem_free(roam_info);
                } else
                  smsLog( pMac, LOGE, FL("vos_mem_malloc failed:"));

                if (pMac->sme.pExtScanIndCb) {
                    pMac->sme.pExtScanIndCb(pMac->hHdd,
                                            eSIR_EXTSCAN_FULL_SCAN_RESULT_IND,
                                            pMsg->bodyptr);
                } else {
                    smsLog(pMac, LOGE,
                           FL("callback not registered to process eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND"));
                }

                vos_mem_free(pMsg->bodyptr);
                break;
          }
          case eWNI_SME_EPNO_NETWORK_FOUND_IND:
          {
                if (pMac->sme.pExtScanIndCb) {
                    pMac->sme.pExtScanIndCb(pMac->hHdd,
                                            eSIR_EPNO_NETWORK_FOUND_IND,
                                            pMsg->bodyptr);
                } else {
                    smsLog(pMac, LOGE,
                           FL("callback not registered to process eWNI_SME_EPNO_NETWORK_FOUND_IND"));
                }
                vos_mem_free(pMsg->bodyptr);
                break;
          }
#endif
          case eWNI_SME_FW_STATUS_IND:
               if (pMac->sme.fw_state_callback)
                   pMac->sme.fw_state_callback(pMac->sme.fw_state_context);

               pMac->sme.fw_state_callback = NULL;
               pMac->sme.fw_state_context = NULL;
               break;
          case eWNI_SME_OCB_SET_CONFIG_RSP:
               if (pMac->sme.ocb_set_config_callback) {
                   pMac->sme.ocb_set_config_callback(
                       pMac->sme.ocb_set_config_context,
                       pMsg->bodyptr);
               } else {
                   smsLog(pMac, LOGE, FL(
                       "Error processing message. The callback is NULL."));
               }
               pMac->sme.ocb_set_config_callback = NULL;
               pMac->sme.ocb_set_config_context = NULL;
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_OCB_GET_TSF_TIMER_RSP:
               if (pMac->sme.ocb_get_tsf_timer_callback) {
                   pMac->sme.ocb_get_tsf_timer_callback(
                       pMac->sme.ocb_get_tsf_timer_context,
                       pMsg->bodyptr);
               } else {
                   smsLog(pMac, LOGE, FL(
                       "Error processing message. The callback is NULL."));
               }
               pMac->sme.ocb_get_tsf_timer_callback = NULL;
               pMac->sme.ocb_get_tsf_timer_context = NULL;
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_DCC_GET_STATS_RSP:
               if (pMac->sme.dcc_get_stats_callback) {
                   pMac->sme.dcc_get_stats_callback(
                       pMac->sme.dcc_get_stats_context,
                       pMsg->bodyptr);
               } else {
                   smsLog(pMac, LOGE, FL(
                       "Error processing message. The callback or context is NULL."));
               }
               pMac->sme.dcc_get_stats_callback = NULL;
               pMac->sme.dcc_get_stats_context = NULL;
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_DCC_UPDATE_NDL_RSP:
               if (pMac->sme.dcc_update_ndl_callback) {
                   pMac->sme.dcc_update_ndl_callback(
                       pMac->sme.dcc_update_ndl_context,
                       pMsg->bodyptr);
               } else {
                   smsLog(pMac, LOGE, FL(
                       "Error processing message. The callback or context is NULL."));
               }
               pMac->sme.dcc_update_ndl_callback = NULL;
               pMac->sme.dcc_update_ndl_context = NULL;
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_DCC_STATS_EVENT:
               if (pMac->sme.dcc_stats_event_callback) {
                   pMac->sme.dcc_stats_event_callback(
                       pMac->sme.dcc_stats_event_context,
                       pMsg->bodyptr);
               } else {
                   smsLog(pMac, LOGE, FL(
                       "Error processing message. The callback or context is NULL."));
               }
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_RADIO_CHAN_STATS_IND:
               if (pMac->sme.radio_chan_stats_callback) {
                   pMac->sme.radio_chan_stats_callback(
                       pMac->sme.radio_chan_stats_context, pMsg->bodyptr);
               } else {
                   smsLog(pMac, LOGE, FL(
                       "Error processing message. The callback is NULL."));
               }
               vos_mem_free(pMsg->bodyptr);
               break;

          case eWNI_SME_SET_THERMAL_LEVEL_IND:
               if (pMac->sme.set_thermal_level_cb)
               {
                   pMac->sme.set_thermal_level_cb(pMac->hHdd, pMsg->bodyval);
               }
               break;
#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN
          case eWNI_SME_THERMAL_TEMPERATURE_IND:
               if (pMac->sme.thermal_temp_ind_cb)
               {
                   pMac->sme.thermal_temp_ind_cb(pMac->hHdd, pMsg->bodyval);
               }
               break;
#endif

          case eWNI_SME_LOST_LINK_INFO_IND:
               if (pMac->sme.lost_link_info_cb) {
                   pMac->sme.lost_link_info_cb(pMac->hHdd,
                             (struct sir_lost_link_info *)pMsg->bodyptr);
               }
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_SMPS_FORCE_MODE_IND:
               if (pMac->sme.smps_force_mode_cb)
                   pMac->sme.smps_force_mode_cb(pMac->hHdd,
                       (struct sir_smps_force_mode_event *)
                       pMsg->bodyptr);
               vos_mem_free(pMsg->bodyptr);
               break;
          case eWNI_SME_NDP_CONFIRM_IND:
          case eWNI_SME_NDP_NEW_PEER_IND:
          case eWNI_SME_NDP_INITIATOR_RSP:
          case eWNI_SME_NDP_INDICATION:
          case eWNI_SME_NDP_RESPONDER_RSP:
          case eWNI_SME_NDP_END_RSP:
          case eWNI_SME_NDP_END_IND:
          case eWNI_SME_NDP_PEER_DEPARTED_IND:
               sme_ndp_msg_processor(pMac, pMsg);
               break;
          case eWMI_SME_LL_STATS_IND:
	       if (pMac->sme.link_layer_stats_ext_cb)
			pMac->sme.link_layer_stats_ext_cb(pMsg->bodyptr);
	       vos_mem_free(pMsg->bodyptr);
	       break;
          case eWNI_SME_RX_AGGR_HOLE_IND:
               if (pMac->sme.stats_ext2_cb)
                   pMac->sme.stats_ext2_cb(pMac->hHdd,
                       (struct stats_ext2_event *)pMsg->bodyptr);
               vos_mem_free(pMsg->bodyptr);
               break;
#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
          case eWNI_SME_AU_TXRX_STAT_IND:
               if (pMac->sme.pau_txrx_stat_ind_cb)
                   pMac->sme.pau_txrx_stat_ind_cb(pMsg->bodyptr,
                                        pMac->sme.pau_get_txrx_stat_cb_context);
               if (pMsg->bodyptr)
                   vos_mem_free(pMsg->bodyptr);
		break;
          case eWNI_SME_AU_TX_SCHED_IND:
               if (pMac->sme.pau_tx_sched_ind_cb)
                   pMac->sme.pau_tx_sched_ind_cb(pMsg->bodyptr,
                                        pMac->sme.pau_get_tx_sched_cb_context);
               if (pMsg->bodyptr)
                   vos_mem_free(pMsg->bodyptr);
		break;
#endif

          default:

             if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN )
                  &&  ( pMsg->type <= eWNI_SME_MSG_TYPES_END ) )
             {
                //CSR
                if (pMsg->bodyptr)
                {
                   status = csrMsgProcessor(hHal, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
                else
                {
                   smsLog( pMac, LOGE, "Empty rsp message for CSR, nothing to process");
                }
             }
             else
             {
                smsLog( pMac, LOGW, "Unknown message type %d, nothing to process",
                        pMsg->type);
                if (pMsg->bodyptr)
                {
                   vos_mem_free(pMsg->bodyptr);
                }
             }
          }//switch
      } //SME_IS_START
      else
      {
         smsLog( pMac, LOGW, "message type %d in stop state ignored", pMsg->type);
         if (pMsg->bodyptr)
         {
            vos_mem_free(pMsg->bodyptr);
         }
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   else
   {
      smsLog( pMac, LOGW, "Locking failed, bailing out");
      if (pMsg->bodyptr)
      {
          vos_mem_free(pMsg->bodyptr);
      }
   }

   return status;
}


//No need to hold the global lock here because this function can only be called
//after sme_Stop.
v_VOID_t sme_FreeMsg( tHalHandle hHal, vos_msg_t* pMsg )
{
   if( pMsg )
   {
      if (pMsg->bodyptr)
      {
         vos_mem_free(pMsg->bodyptr);
      }
   }

}


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

  \brief sme_Stop() - Stop all SME modules and put them at idle state

  The function stops each module in SME, PMC, CCM, CSR, etc. . Upon
  return, all modules are at idle state ready to start.

  This is a synchronous call
  \param hHal - The handle returned by macOpen
  \param tHalStopType - reason for stopping

  \return eHAL_STATUS_SUCCESS - SME is stopped.

          Other status means SME is failed to stop but caller should still
          consider SME is stopped.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_Stop(tHalHandle hHal, tHalStopType stopType)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   eHalStatus fail_status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   p2pStop(hHal);

   if(!pMac->psOffloadEnabled)
   {
       status = pmcStop(hHal);
       if ( ! HAL_STATUS_SUCCESS( status ) ) {
           smsLog( pMac, LOGE,
                   "pmcStop failed during smeStop with status=%d",
                   status );
           fail_status = status;
       }
   }
   else
   {
       status = pmcOffloadStop(hHal);
       if ( ! HAL_STATUS_SUCCESS( status ) ) {
           smsLog( pMac, LOGE,
                   "pmcOffloadStop failed during smeStop with status=%d",
                   status );
           fail_status = status;
       }
   }

   status = csrStop(pMac, stopType);
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "csrStop failed during smeStop with status=%d",
              status );
      fail_status = status;
   }

   ccmStop(hHal);

   purgeSmeCmdList(pMac);

   if (!HAL_STATUS_SUCCESS( fail_status )) {
      status = fail_status;
   }

   pMac->sme.state = SME_STATE_STOP;

   return status;
}

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

  \brief sme_Close() - Release all SME modules and their resources.

  The function release each module in SME, PMC, CCM, CSR, etc. . Upon
  return, all modules are at closed state.

  No SME APIs can be involved after smeClose except smeOpen.
  smeClose must be called before macClose.
  This is a synchronous call
  \param hHal - The handle returned by macOpen

  \return eHAL_STATUS_SUCCESS - SME is successfully close.

          Other status means SME is failed to be closed but caller still cannot
          call any other SME functions except smeOpen.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_Close(tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   eHalStatus fail_status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (!pMac)
       return eHAL_STATUS_FAILURE;

   /* Note: pSession will be invalid from here on, do not access */
   status = csrClose(pMac);
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "csrClose failed during sme close with status=%d",
              status );
      fail_status = status;
   }

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   status = sme_QosClose(pMac);
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "Qos close failed during sme close with status=%d",
              status );
      fail_status = status;
   }
#endif
#ifdef FEATURE_OEM_DATA_SUPPORT
   status = oemData_OemDataReqClose(hHal);
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
       smsLog( pMac, LOGE, "OEM DATA REQ close failed during sme close with status=%d",
              status );
      fail_status = status;
   }
#endif

   status = ccmClose(hHal);
         if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "ccmClose failed during sme close with status=%d",
                 status );
             fail_status = status;
         }

   if(!pMac->psOffloadEnabled)
   {
       status = pmcClose(hHal);
       if ( ! HAL_STATUS_SUCCESS( status ) ) {
          smsLog(pMac, LOGE, "pmcClose failed during sme close with status=%d",
              status);
          fail_status = status;
       }
   }
   else
   {
       status = pmcOffloadClose(hHal);
       if(!HAL_STATUS_SUCCESS(status)) {
          smsLog(pMac, LOGE, "pmcOffloadClose failed during smeClose status=%d",
              status);
          fail_status = status;
       }
   }
#if defined WLAN_FEATURE_VOWIFI
   status = rrmClose(hHal);
   if ( ! HAL_STATUS_SUCCESS( status ) ) {
      smsLog( pMac, LOGE, "RRM close failed during sme close with status=%d",
              status );
      fail_status = status;
   }
#endif

   sme_p2pClose(hHal);

   freeSmeCmdList(pMac);

   if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pMac->sme.lkSmeGlobalLock ) ) )
   {
       fail_status = eHAL_STATUS_FAILURE;
   }

   if (!HAL_STATUS_SUCCESS( fail_status )) {
      status = fail_status;
   }

   pMac->sme.state = SME_STATE_STOP;

   return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ScanRequest
    \brief a wrapper function to Request a 11d or full scan from CSR.
    This is an asynchronous call
    \param pScanRequestID - pointer to an object to get back the request ID
    \param callback - a callback function that scan calls upon finish, will not
                      be called if csrScanRequest returns error
    \param pContext - a pointer passed in for the callback
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanRequest(tHalHandle hHal, tANI_U8 sessionId, tCsrScanRequest *pscanReq,
                           tANI_U32 *pScanRequestID,
                           csrScanCompleteCallback callback, void *pContext)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, sessionId, pscanReq->scanType));
    smsLog(pMac, LOG2, FL("enter"));
    do
    {
        if(pMac->scan.fScanEnable)
        {
            status = sme_AcquireGlobalLock( &pMac->sme );
            if (HAL_STATUS_SUCCESS(status )) {
                status = csrScanRequest(hHal, sessionId, pscanReq,
                                        pScanRequestID, callback, pContext);
                if (!HAL_STATUS_SUCCESS(status)) {
                   smsLog(pMac, LOGE,
                          FL("csrScanRequest failed sessionId(%d)"), sessionId);
                }
                sme_ReleaseGlobalLock( &pMac->sme );
            } else {
                smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed"));
            }
        } //if(pMac->scan.fScanEnable)
        else
        {
            smsLog(pMac, LOGE, FL("fScanEnable FALSE"));
        }
    } while( 0 );

    return (status);


}

/* ---------------------------------------------------------------------------
    \fn sme_ScanGetResult
    \brief a wrapper function to request scan results from CSR.
    This is a synchronous call
    \param pFilter - If pFilter is NULL, all cached results are returned
    \param phResult - an object for the result.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanGetResult(tHalHandle hHal, tANI_U8 sessionId, tCsrScanResultFilter *pFilter,
                            tScanResultHandle *phResult)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId,0 ));
   smsLog(pMac, LOG2, FL("enter"));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = csrScanGetResult( hHal, pFilter, phResult );
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   smsLog(pMac, LOG2, FL("exit status %d"), status);

   return (status);
}

/**
 * sme_get_ap_channel_from_scan_cache() - a wrapper function to get AP's
 *                                        channel id from CSR by filtering the
 *                                        result which matches our roam profile.
 * @profile: SAP adapter
 * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the
 *              best ap from scan cache.
 *
 * This function is written to get AP's channel id from CSR by filtering
 * the result which matches our roam profile. This is a synchronous call.
 *
 * Return: VOS_STATUS.
 */
VOS_STATUS sme_get_ap_channel_from_scan_cache(tHalHandle hHal,
                                              tCsrRoamProfile *profile,
                                              tScanResultHandle *scan_cache,
                                              tANI_U8 *ap_chnl_id)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tCsrScanResultFilter *scan_filter = NULL;
   tScanResultHandle filtered_scan_result = NULL;
   tSirBssDescription first_ap_profile;
   VOS_STATUS ret_status = VOS_STATUS_SUCCESS;

   if (NULL == pMac) {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                 FL("pMac is NULL"));
       return VOS_STATUS_E_FAILURE;
   }
   scan_filter = vos_mem_malloc(sizeof(tCsrScanResultFilter));
   if (NULL == scan_filter) {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                 FL("scan_filter mem alloc failed"));
       return VOS_STATUS_E_FAILURE;
   } else {
      vos_mem_set(scan_filter, sizeof(tCsrScanResultFilter), 0);
      vos_mem_set(&first_ap_profile, sizeof(tSirBssDescription), 0);

      if (NULL == profile) {
          scan_filter->EncryptionType.numEntries = 1;
          scan_filter->EncryptionType.encryptionType[0]
                              = eCSR_ENCRYPT_TYPE_NONE;
      } else {
          /* Here is the profile we need to connect to */
          status = csrRoamPrepareFilterFromProfile(pMac, profile, scan_filter);
      }

      if (HAL_STATUS_SUCCESS(status)) {
          /* Save the WPS info */
          if(NULL != profile) {
             scan_filter->bWPSAssociation = profile->bWPSAssociation;
             scan_filter->bOSENAssociation = profile->bOSENAssociation;
          } else {
             scan_filter->bWPSAssociation = 0;
             scan_filter->bOSENAssociation = 0;
          }
      } else {
          VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                    FL("Preparing the profile filter failed"));
          vos_mem_free(scan_filter);
          return VOS_STATUS_E_FAILURE;
      }
   }
   status = sme_AcquireGlobalLock( &pMac->sme );
   if (eHAL_STATUS_SUCCESS == status) {
       status = csrScanGetResult(hHal, scan_filter, &filtered_scan_result);
       if (eHAL_STATUS_SUCCESS == status) {
           csr_get_bssdescr_from_scan_handle(filtered_scan_result,
                                             &first_ap_profile);
           *scan_cache = filtered_scan_result;
           if (0 != first_ap_profile.channelId) {
               *ap_chnl_id = first_ap_profile.channelId;
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Found best AP and it is on channel[%d]"),
                          first_ap_profile.channelId);
           } else {
               /*
                * This means scan result is empty
                * so set the channel to zero, caller should
                * take of zero channel id case.
                */
               *ap_chnl_id = 0;
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                         FL("Scan result is empty, setting channel to 0"));
               ret_status = VOS_STATUS_E_FAILURE;
           }
       } else {
          VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                    FL("Failed to get scan get result"));
          ret_status = VOS_STATUS_E_FAILURE;
       }
       sme_ReleaseGlobalLock( &pMac->sme );
   } else {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                    FL("Aquiring lock failed"));
       ret_status = VOS_STATUS_E_FAILURE;
   }

   if (NULL != profile)
       csrFreeScanFilter(pMac, scan_filter);

   vos_mem_free(scan_filter);

   return ret_status;
}

/**
 * sme_store_joinreq_param() - This function will pass station's join
 *                             request to store to csr.
 * @hal_handle: pointer to hal context.
 * @profile: pointer to station's roam profile.
 * @scan_cache: pointer to station's scan cache.
 * @roam_id: reference to roam_id variable being passed.
 * @session_id: station's session id.
 *
 * This function will pass station's join request further down to csr
 * to store it. this stored parameter will be used later.
 *
 * Return: true or false based on function's overall success.
 */
bool sme_store_joinreq_param(tHalHandle hal_handle,
                             tCsrRoamProfile *profile,
                             tScanResultHandle scan_cache,
                             uint32_t *roam_id,
                             uint32_t session_id)
{
   tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
   eHalStatus status = eHAL_STATUS_FAILURE;
   bool ret_status = true;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                    TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ,
                    session_id, 0));
   status = sme_AcquireGlobalLock( &mac_ctx->sme );
   if (HAL_STATUS_SUCCESS(status)) {
       if (false == csr_store_joinreq_param(mac_ctx, profile, scan_cache,
                                            roam_id, session_id)) {
           ret_status = false;
       }
       sme_ReleaseGlobalLock(&mac_ctx->sme);
   } else {
       ret_status = false;
   }

   return ret_status;
}

/**
 * sme_clear_joinreq_param() - This function will pass station's clear
 *                             the join request to csr.
 * @hal_handle: pointer to hal context.
 * @session_id: station's session id.
 *
 * This function will pass station's clear join request further down to csr
 * to cleanup.
 *
 * Return: true or false based on function's overall success.
 */
bool sme_clear_joinreq_param(tHalHandle hal_handle,
                             uint32_t session_id)
{
   tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
   eHalStatus status = eHAL_STATUS_FAILURE;
   bool ret_status = true;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                    TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ,
                    session_id, 0));
   status = sme_AcquireGlobalLock( &mac_ctx->sme );
   if (HAL_STATUS_SUCCESS(status)) {
       if (false == csr_clear_joinreq_param(mac_ctx,
                                            session_id)) {
           ret_status = false;
       }
       sme_ReleaseGlobalLock(&mac_ctx->sme);
   } else {
       ret_status = false;
   }

   return ret_status;
}

/**
 * sme_issue_stored_joinreq() - This function will issues station's stored
 *                              the join request to csr.
 * @hal_handle: pointer to hal context.
 * @roam_id: reference to roam_id variable being passed.
 * @session_id: station's session id.
 *
 * This function will issue station's stored join request further down to csr
 * to proceed forward.
 *
 * Return: VOS_STATUS_SUCCESS or VOS_STATUS_E_FAILURE.
 */
VOS_STATUS sme_issue_stored_joinreq(tHalHandle hal_handle,
                                    uint32_t *roam_id,
                                    uint32_t session_id)
{
   tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
   eHalStatus status = eHAL_STATUS_FAILURE;
   VOS_STATUS ret_status = VOS_STATUS_SUCCESS;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                    TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ,
                    session_id, 0));
   status = sme_AcquireGlobalLock( &mac_ctx->sme );
   if (HAL_STATUS_SUCCESS(status)) {
       if (!HAL_STATUS_SUCCESS(csr_issue_stored_joinreq(mac_ctx,
                                                        roam_id,
                                                        session_id))) {
           ret_status = VOS_STATUS_E_FAILURE;
       }
       sme_ReleaseGlobalLock(&mac_ctx->sme);
   } else {
       csr_clear_joinreq_param(mac_ctx, session_id);
       ret_status = VOS_STATUS_E_FAILURE;
   }
   return ret_status;
}
/* ---------------------------------------------------------------------------
    \fn sme_ScanFlushResult
    \brief a wrapper function to request CSR to clear scan results.
    This is a synchronous call
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanFlushResult(tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, sessionId,0 ));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = csrScanFlushResult(hHal, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_FilterScanResults
    \brief a wrapper function to request CSR to clear scan results.
    This is a synchronous call
    \param tHalHandle - HAL context handle
    \param sessionId - session id
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_FilterScanResults(tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, sessionId,0 ));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       csrScanFilterResults(pMac);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

eHalStatus sme_ScanFlushP2PResult(tHalHandle hHal, tANI_U8 sessionId)
{
        eHalStatus status = eHAL_STATUS_FAILURE;
        tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

        MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS, sessionId,0 ));
        status = sme_AcquireGlobalLock( &pMac->sme );
        if ( HAL_STATUS_SUCCESS( status ) )
        {
                status = csrScanFlushSelectiveResult( hHal, VOS_TRUE );
                sme_ReleaseGlobalLock( &pMac->sme );
        }

        return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_ScanResultGetFirst
    \brief a wrapper function to request CSR to returns the first element of
           scan result.
    This is a synchronous call
    \param hScanResult - returned from csrScanGetResult
    \return tCsrScanResultInfo * - NULL if no result
  ---------------------------------------------------------------------------*/
tCsrScanResultInfo *sme_ScanResultGetFirst(tHalHandle hHal,
                                          tScanResultHandle hScanResult)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tCsrScanResultInfo *pRet = NULL;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST, NO_SESSION,0 ));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       pRet = csrScanResultGetFirst( pMac, hScanResult );
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (pRet);
}


/* ---------------------------------------------------------------------------
    \fn sme_ScanResultGetNext
    \brief a wrapper function to request CSR to returns the next element of
           scan result. It can be called without calling csrScanResultGetFirst
           first
    This is a synchronous call
    \param hScanResult - returned from csrScanGetResult
    \return Null if no result or reach the end
  ---------------------------------------------------------------------------*/
tCsrScanResultInfo *sme_ScanResultGetNext(tHalHandle hHal,
                                          tScanResultHandle hScanResult)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tCsrScanResultInfo *pRet = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pRet = csrScanResultGetNext( pMac, hScanResult );
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (pRet);
}


/* ---------------------------------------------------------------------------
    \fn sme_ScanSetBGScanparams
    \brief a wrapper function to request CSR to set BG scan params in PE
    This is a synchronous call
    \param pScanReq - BG scan request structure
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanSetBGScanparams(tHalHandle hHal, tANI_U8 sessionId, tCsrBGScanRequest *pScanReq)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if( NULL != pScanReq )
    {
        status = sme_AcquireGlobalLock( &pMac->sme );
        if ( HAL_STATUS_SUCCESS( status ) )
        {
            status = csrScanSetBGScanparams( hHal, pScanReq );
            sme_ReleaseGlobalLock( &pMac->sme );
        }
    }

    return (status);
}


/* ---------------------------------------------------------------------------
    \fn sme_ScanResultPurge
    \brief a wrapper function to request CSR to remove all items(tCsrScanResult)
           in the list and free memory for each item
    This is a synchronous call
    \param hScanResult - returned from csrScanGetResult. hScanResult is
                         considered gone by
    calling this function and even before this function returns.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanResultPurge(tHalHandle hHal, tScanResultHandle hScanResult)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE, NO_SESSION,0 ));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = csrScanResultPurge( hHal, hScanResult );
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_ScanGetPMKIDCandidateList
    \brief a wrapper function to return the PMKID candidate list
    This is a synchronous call
    \param pPmkidList - caller allocated buffer point to an array of
                        tPmkidCandidateInfo
    \param pNumItems - pointer to a variable that has the number of
                       tPmkidCandidateInfo allocated when returning, this is
                       either the number needed or number of items put into
                       pPmkidList
    \return eHalStatus - when fail, it usually means the buffer allocated is not
                         big enough and pNumItems
    has the number of tPmkidCandidateInfo.
    \Note: pNumItems is a number of tPmkidCandidateInfo,
           not sizeof(tPmkidCandidateInfo) * something
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanGetPMKIDCandidateList(tHalHandle hHal, tANI_U8 sessionId,
                                        tPmkidCandidateInfo *pPmkidList,
                                        tANI_U32 *pNumItems )
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = csrScanGetPMKIDCandidateList( pMac, sessionId, pPmkidList, pNumItems );
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/*----------------------------------------------------------------------------
  \fn sme_RoamRegisterLinkQualityIndCallback

  \brief
  a wrapper function to allow HDD to register a callback handler with CSR for
  link quality indications.

  Only one callback may be registered at any time.
  In order to deregister the callback, a NULL cback may be provided.

  Registration happens in the task context of the caller.

  \param callback - Call back being registered
  \param pContext - user data

  DEPENDENCIES: After CSR open

  \return eHalStatus
-----------------------------------------------------------------------------*/
eHalStatus sme_RoamRegisterLinkQualityIndCallback(tHalHandle hHal, tANI_U8 sessionId,
                                                  csrRoamLinkQualityIndCallback   callback,
                                                  void                           *pContext)
{
   return(csrRoamRegisterLinkQualityIndCallback((tpAniSirGlobal)hHal, callback, pContext));
}

eCsrPhyMode sme_GetPhyMode(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->roam.configParam.phyMode;
}

/* ---------------------------------------------------------------------------
    \fn sme_GetChannelBondingMode5G
    \brief get the channel bonding mode for 5G band
    \param hHal - HAL handle
    \return channel bonding mode for 5G
  ---------------------------------------------------------------------------*/
tANI_U32 sme_GetChannelBondingMode5G(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tSmeConfigParams  smeConfig;

    sme_GetConfigParam(pMac, &smeConfig);

    return smeConfig.csrConfig.channelBondingMode5GHz;
}

/* ---------------------------------------------------------------------------
    \fn sme_GetChannelBondingMode24G
    \brief get the channel bonding mode for 2.4G band
    \param hHal - HAL handle
    \return channel bonding mode for 2.4G
  ---------------------------------------------------------------------------*/
tANI_U32 sme_GetChannelBondingMode24G(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tSmeConfigParams  smeConfig;

    sme_GetConfigParam(pMac, &smeConfig);

    return smeConfig.csrConfig.channelBondingMode24GHz;
}


/* ---------------------------------------------------------------------------
    \fn sme_RoamConnect
    \brief a wrapper function to request CSR to initiate an association
    This is an asynchronous call.
    \param sessionId - the sessionId returned by sme_OpenSession.
    \param pProfile - description of the network to which to connect
    \param hBssListIn - a list of BSS descriptor to roam to. It is returned
                        from csrScanGetResult
    \param pRoamId - to get back the request ID
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamConnect(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile,
                           tANI_U32 *pRoamId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (!pMac)
    {
        return eHAL_STATUS_FAILURE;
    }

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0));
    smsLog(pMac, LOG2, FL("enter"));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
            status = csrRoamConnect( pMac, sessionId, pProfile, NULL, pRoamId );
        }
        else
        {
            smsLog(pMac, LOGE, FL("invalid sessionID %d"), sessionId);
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    else
    {
        smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed"));
    }

    return (status);
}

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

    \fn sme_SetPhyMode

    \brief Changes the PhyMode.

    \param hHal - The handle returned by macOpen.

    \param phyMode new phyMode which is to set

    \return eHalStatus  SUCCESS.

  -------------------------------------------------------------------------------*/
eHalStatus sme_SetPhyMode(tHalHandle hHal, eCsrPhyMode phyMode)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (NULL == pMac)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: invalid context", __func__);
        return eHAL_STATUS_FAILURE;
    }

    pMac->roam.configParam.phyMode = phyMode;
    pMac->roam.configParam.uCfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(NULL,
                                                 pMac->roam.configParam.phyMode,
                                    pMac->roam.configParam.ProprietaryRatesEnabled);

    return eHAL_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamReassoc
    \brief a wrapper function to request CSR to initiate a re-association
    \param pProfile - can be NULL to join the currently connected AP. In that
    case modProfileFields should carry the modified field(s) which could trigger
    reassoc
    \param modProfileFields - fields which are part of tCsrRoamConnectedProfile
    that might need modification dynamically once STA is up & running and this
    could trigger a reassoc
    \param pRoamId - to get back the request ID
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamReassoc(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile,
                          tCsrRoamModifyProfileFields modProfileFields,
                          tANI_U32 *pRoamId, v_BOOL_t fForce)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                      TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0));
    smsLog(pMac, LOG2, FL("enter"));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
            if((NULL == pProfile) && (fForce == 1))
            {
                status = csrReassoc( pMac, sessionId, &modProfileFields, pRoamId , fForce);
            }
            else
            {
                status = csrRoamReassoc( pMac, sessionId, pProfile, modProfileFields, pRoamId );
            }
        }
        else
        {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamConnectToLastProfile
    \brief a wrapper function to request CSR to disconnect and reconnect with
           the same profile
    This is an asynchronous call.
    \return eHalStatus. It returns fail if currently connected
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamConnectToLastProfile(tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, sessionId, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamConnectToLastProfile( pMac, sessionId );
      }
      else
      {
          status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamDisconnect
    \brief a wrapper function to request CSR to disconnect from a network
    This is an asynchronous call.
    \param reason -- To indicate the reason for disconnecting. Currently, only
                     eCSR_DISCONNECT_REASON_MIC_ERROR is meaningful.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDisconnectReason reason)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (!pMac)
       return status;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                        TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, sessionId, reason));
   smsLog(pMac, LOG2, FL("enter"));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamDisconnect( pMac, sessionId, reason );
      }
      else
      {
          status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* sme_dhcp_done_ind() - send dhcp done ind
 * @hal: hal context
 * @session_id: session id
 *
 * Return: void.
 */
void sme_dhcp_done_ind(tHalHandle hal, uint8_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	tCsrRoamSession *session;

	if (!mac_ctx)
		return;

	session = CSR_GET_SESSION(mac_ctx, session_id);
	if (!session) {
		smsLog(mac_ctx, LOGE, FL("session %d not found"), session_id);
		return;
	}
	session->dhcp_done = true;
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamStopBss
    \brief To stop BSS for Soft AP. This is an asynchronous API.
    \param hHal - Global structure
    \param sessionId - sessionId of SoftAP
    \return eHalStatus  SUCCESS  Roam callback will be called to indicate actual results
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamStopBss(tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (!pMac)
       return status;

   smsLog(pMac, LOG2, FL("enter"));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamIssueStopBssCmd( pMac, sessionId, eANI_BOOLEAN_TRUE );
      }
      else
      {
          status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamDisconnectSta
    \brief To disassociate a station. This is an asynchronous API.
    \param hHal - Global structure
    \param sessionId - sessionId of SoftAP
    \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes)
    \return eHalStatus  SUCCESS  Roam callback will be called to indicate actual results
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamDisconnectSta(tHalHandle hHal, tANI_U8 sessionId,
                                struct tagCsrDelStaParams *pDelStaParams)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if ( NULL == pMac )
   {
     VOS_ASSERT(0);
     return status;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamIssueDisassociateStaCmd( pMac, sessionId, pDelStaParams);
      }
      else
      {
         status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamDeauthSta
    \brief To disassociate a station. This is an asynchronous API.
    \param hHal - Global structure
    \param sessionId - sessionId of SoftAP
    \param pDelStaParams -Pointer to parameters of the station to deauthenticate
    \return eHalStatus  SUCCESS  Roam callback will be called to indicate actual results
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamDeauthSta(tHalHandle hHal, tANI_U8 sessionId,
                             struct tagCsrDelStaParams *pDelStaParams)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if ( NULL == pMac )
   {
     VOS_ASSERT(0);
     return status;
   }

   MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA,
                         sessionId, pDelStaParams->reason_code));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamIssueDeauthStaCmd( pMac, sessionId, pDelStaParams);
      }
      else
      {
         status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamTKIPCounterMeasures
    \brief To start or stop TKIP counter measures. This is an asynchronous API.
    \param sessionId - sessionId of SoftAP
    \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes)
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamTKIPCounterMeasures(tHalHandle hHal, tANI_U8 sessionId,
                                        tANI_BOOLEAN bEnable)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if ( NULL == pMac )
   {
     VOS_ASSERT(0);
     return status;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
            status = csrRoamIssueTkipCounterMeasures( pMac, sessionId, bEnable);
        }
        else
        {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamGetAssociatedStas
    \brief To probe the list of associated stations from various modules of CORE stack.
    \This is an asynchronous API.
    \param sessionId    - sessionId of SoftAP
    \param modId        - Module from whom list of associated stations is to be probed.
                          If an invalid module is passed then by default VOS_MODULE_ID_PE will be probed
    \param pUsrContext  - Opaque HDD context
    \param pfnSapEventCallback  - Sap event callback in HDD
    \param pAssocBuf    - Caller allocated memory to be filled with
                          associated stations info
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamGetAssociatedStas(tHalHandle hHal, tANI_U8 sessionId,
                                        VOS_MODULE_ID modId, void *pUsrContext,
                                        void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if ( NULL == pMac )
   {
     VOS_ASSERT(0);
     return status;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
            status = csrRoamGetAssociatedStas( pMac, sessionId, modId, pUsrContext, pfnSapEventCallback, pAssocStasBuf );
        }
        else
        {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamGetWpsSessionOverlap
    \brief To get the WPS PBC session overlap information.
    \This is an asynchronous API.
    \param sessionId    - sessionId of SoftAP
    \param pUsrContext  - Opaque HDD context
    \param pfnSapEventCallback  - Sap event callback in HDD
    \pRemoveMac - pointer to Mac address which needs to be removed from session
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamGetWpsSessionOverlap(tHalHandle hHal, tANI_U8 sessionId,
                                        void *pUsrContext, void
                                        *pfnSapEventCallback, v_MACADDR_t pRemoveMac)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if ( NULL == pMac )
   {
     VOS_ASSERT(0);
     return status;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
            status = csrRoamGetWpsSessionOverlap( pMac, sessionId, pUsrContext, pfnSapEventCallback, pRemoveMac);
        }
        else
        {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}


/* ---------------------------------------------------------------------------
    \fn sme_RoamGetConnectState
    \brief a wrapper function to request CSR to return the current connect state
           of Roaming
    This is a synchronous call.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamGetConnectState(tHalHandle hHal, tANI_U8 sessionId, eCsrConnectState *pState)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
       if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
       {
          status = csrRoamGetConnectState( pMac, sessionId, pState );
       }
       else
       {
           status = eHAL_STATUS_INVALID_PARAMETER;
       }
       sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamGetConnectProfile
    \brief a wrapper function to request CSR to return the current connect
           profile. Caller must call csrRoamFreeConnectProfile after it is done
           and before reuse for another csrRoamGetConnectProfile call.
    This is a synchronous call.
    \param pProfile - pointer to a caller allocated structure
                      tCsrRoamConnectedProfile
    \return eHalStatus. Failure if not connected
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamGetConnectProfile(tHalHandle hHal, tANI_U8 sessionId,
                                     tCsrRoamConnectedProfile *pProfile)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, sessionId, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamGetConnectProfile( pMac, sessionId, pProfile );
      }
      else
      {
          status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamFreeConnectProfile
    \brief a wrapper function to request CSR to free and reinitialize the
           profile returned previously by csrRoamGetConnectProfile.
    This is a synchronous call.
    \param pProfile - pointer to a caller allocated structure
                      tCsrRoamConnectedProfile
    \return eHalStatus.
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamFreeConnectProfile(tHalHandle hHal,
                                      tCsrRoamConnectedProfile *pProfile)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
            TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE, NO_SESSION, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = csrRoamFreeConnectProfile( pMac, pProfile );
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamSetPMKIDCache
    \brief a wrapper function to request CSR to return the PMKID candidate list
    This is a synchronous call.
    \param pPMKIDCache - caller allocated buffer point to an array of
                         tPmkidCacheInfo
    \param numItems - a variable that has the number of tPmkidCacheInfo
                      allocated when returning, this is either the number needed
                      or number of items put into pPMKIDCache
    \param update_entire_cache - this bool value specifies if the entire pmkid
                               cache should be overwritten or should it be
                               updated entry by entry.
    \return eHalStatus - when fail, it usually means the buffer allocated is not
                         big enough and pNumItems has the number of
                         tPmkidCacheInfo.
    \Note: pNumItems is a number of tPmkidCacheInfo,
           not sizeof(tPmkidCacheInfo) * something
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamSetPMKIDCache( tHalHandle hHal, tANI_U8 sessionId,
                                  tPmkidCacheInfo *pPMKIDCache,
                                  tANI_U32 numItems,
                                  tANI_BOOLEAN update_entire_cache )
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId, numItems));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamSetPMKIDCache( pMac, sessionId, pPMKIDCache,
                                        numItems, update_entire_cache);
      }
      else
      {
          status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId,
                                      tPmkidCacheInfo *pmksa,
                                      tANI_BOOLEAN flush_cache )
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE, sessionId, flush_cache));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
      {
         status = csrRoamDelPMKIDfromCache( pMac, sessionId,
                                            pmksa, flush_cache );
      }
      else
      {
          status = eHAL_STATUS_INVALID_PARAMETER;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/* ---------------------------------------------------------------------------
 *\fn sme_RoamSetPSK_PMK
 *\brief a wrapper function to request CSR to save PSK/PMK
 * This is a synchronous call.
 *\param hHal - Global structure
 *\param sessionId - SME sessionId
 *\param pPSK_PMK - pointer to an array of Psk[]/Pmk
 *\param pmk_len - Length could be only 16 bytes in case if LEAP
                   connections. Need to pass this information to
                   firmware.
 *\return eHalStatus -status whether PSK/PMK is set or not
 *---------------------------------------------------------------------------*/
eHalStatus sme_RoamSetPSK_PMK (tHalHandle hHal, tANI_U8 sessionId,
                               tANI_U8 *pPSK_PMK, size_t pmk_len)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    status = sme_AcquireGlobalLock(&pMac->sme);
    if (HAL_STATUS_SUCCESS(status)) {
        if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
            status = csrRoamSetPSK_PMK(pMac, sessionId, pPSK_PMK, pmk_len);
        }
        else {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return (status);
}
#endif
/* ---------------------------------------------------------------------------
    \fn sme_RoamGetSecurityReqIE
    \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR
           passes to PE to JOIN request or START_BSS request
    This is a synchronous call.
    \param pLen - caller allocated memory that has the length of pBuf as input.
                  Upon returned, *pLen has the needed or IE length in pBuf.
    \param pBuf - Caller allocated memory that contain the IE field, if any,
                  upon return
    \param secType - Specifies whether looking for WPA/WPA2/WAPI IE
    \return eHalStatus - when fail, it usually means the buffer allocated is not
                         big enough
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamGetSecurityReqIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen,
                                  tANI_U8 *pBuf, eCsrSecurityType secType)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
           status = csrRoamGetWpaRsnReqIE( hHal, sessionId, pLen, pBuf );
        }
        else
        {
           status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamGetSecurityRspIE
    \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE from
           the beacon or probe rsp if connected
    This is a synchronous call.
    \param pLen - caller allocated memory that has the length of pBuf as input.
                  Upon returned, *pLen has the needed or IE length in pBuf.
    \param pBuf - Caller allocated memory that contain the IE field, if any,
                  upon return
    \param secType - Specifies whether looking for WPA/WPA2/WAPI IE
    \return eHalStatus - when fail, it usually means the buffer allocated is not
                         big enough
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamGetSecurityRspIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen,
                                  tANI_U8 *pBuf, eCsrSecurityType secType)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
           status = csrRoamGetWpaRsnRspIE( pMac, sessionId, pLen, pBuf );
        }
        else
        {
           status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);

}


/* ---------------------------------------------------------------------------
    \fn sme_RoamGetNumPMKIDCache
    \brief a wrapper function to request CSR to return number of PMKID cache
           entries
    This is a synchronous call.
    \return tANI_U32 - the number of PMKID cache entries
  ---------------------------------------------------------------------------*/
tANI_U32 sme_RoamGetNumPMKIDCache(tHalHandle hHal, tANI_U8 sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_U32 numPmkidCache = 0;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
        {
           numPmkidCache = csrRoamGetNumPMKIDCache( pMac, sessionId );
           status = eHAL_STATUS_SUCCESS;
        }
        else
        {
           status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (numPmkidCache);
}

/* ---------------------------------------------------------------------------
    \fn sme_RoamGetPMKIDCache
    \brief a wrapper function to request CSR to return PMKID cache from CSR
    This is a synchronous call.
    \param pNum - caller allocated memory that has the space of the number of
                  pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the
                  needed or actually number in tPmkidCacheInfo.
    \param pPmkidCache - Caller allocated memory that contains PMKID cache, if
                         any, upon return
    \return eHalStatus - when fail, it usually means the buffer allocated is not
                         big enough
  ---------------------------------------------------------------------------*/
eHalStatus sme_RoamGetPMKIDCache(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pNum,
                                 tPmkidCacheInfo *pPmkidCache)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, sessionId, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
       {
          status = csrRoamGetPMKIDCache( pMac, sessionId, pNum, pPmkidCache );
       }
       else
       {
          status = eHAL_STATUS_INVALID_PARAMETER;
       }
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}


/* ---------------------------------------------------------------------------
    \fn sme_GetConfigParam
    \brief a wrapper function that HDD calls to get the global settings
           currently maintained by CSR.
    This is a synchronous call.
    \param pParam - caller allocated memory
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
            TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrGetConfigParam(pMac, &pParam->csrConfig);
      if (status != eHAL_STATUS_SUCCESS)
      {
         smsLog( pMac, LOGE, "%s csrGetConfigParam failed", __func__);
         sme_ReleaseGlobalLock( &pMac->sme );
         return status;
      }
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
      pParam->sap_channel_avoidance = pMac->sap.sap_channel_avoidance;
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
      pParam->fScanOffload = pMac->fScanOffload;
      pParam->fP2pListenOffload = pMac->fP2pListenOffload;
      pParam->pnoOffload = pMac->pnoOffload;
      pParam->max_intf_count = pMac->sme.max_intf_count;
      pParam->enableSelfRecovery = pMac->sme.enableSelfRecovery;
      pParam->f_prefer_non_dfs_on_radar = pMac->f_prefer_non_dfs_on_radar;
      pParam->fine_time_meas_cap = pMac->fine_time_meas_cap;
      pParam->csrConfig.mcc_rts_cts_prot_enable =
              pMac->roam.configParam.mcc_rts_cts_prot_enable;
      pParam->csrConfig.mcc_bcast_prob_resp_enable =
              pMac->roam.configParam.mcc_bcast_prob_resp_enable;
      pParam->csrConfig.sta_roam_policy_params.dfs_mode =
              pMac->roam.configParam.sta_roam_policy.dfs_mode;
      pParam->csrConfig.sta_roam_policy_params.skip_unsafe_channels =
              pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels;
      pParam->sub20_config_info = pMac->sub20_config_info;
      pParam->sub20_channelwidth = pMac->sub20_channelwidth;
      pParam->sub20_dynamic_channelwidth = pMac->sub20_dynamic_channelwidth;
      pParam->sta_change_cc_via_beacon = pMac->sta_change_cc_via_beacon;
      pParam->csrConfig.gStaLocalEDCAEnable =
              pMac->roam.configParam.gStaLocalEDCAEnable;
#if defined WLAN_FEATURE_VOWIFI
      vos_mem_copy(&pParam->rrmConfig, &pMac->rrm.rrmSmeContext.rrmConfig,
                   sizeof(struct rrm_config_param));
#endif
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_CfgSetInt
    \brief a wrapper function that HDD calls to set parameters in CFG.
    This is a synchronous call.
    \param cfgId - Configuration Parameter ID (type) for STA.
    \param ccmValue - The information related to Configuration Parameter ID
                      which needs to be saved in CFG
    \param callback - To be registered by CSR with CCM. Once the CFG done with
                      saving the information in the database, it notifies CCM &
                      then the callback will be invoked to notify.
    \param toBeSaved - To save the request for future reference
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_CfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue,
                         tCcmCfgSetCallback callback, eAniBoolean toBeSaved)
{
   return(ccmCfgSetInt(hHal, cfgId, ccmValue, callback, toBeSaved));
}

/* ---------------------------------------------------------------------------
    \fn sme_CfgSetStr
    \brief a wrapper function that HDD calls to set parameters in CFG.
    This is a synchronous call.
    \param cfgId - Configuration Parameter ID (type) for STA.
    \param pStr - Pointer to the byte array which carries the information needs
                  to be saved in CFG
    \param length - Length of the data to be saved
    \param callback - To be registered by CSR with CCM. Once the CFG done with
                      saving the information in the database, it notifies CCM &
                      then the callback will be invoked to notify.
    \param toBeSaved - To save the request for future reference
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_CfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr,
                         tANI_U32 length, tCcmCfgSetCallback callback,
                         eAniBoolean toBeSaved)
{
   return(ccmCfgSetStr(hHal, cfgId, pStr, length, callback, toBeSaved));
}

/* ---------------------------------------------------------------------------
    \fn sme_GetModifyProfileFields
    \brief HDD or SME - QOS calls this function to get the current values of
    connected profile fields, changing which can cause reassoc.
    This function must be called after CFG is downloaded and STA is in connected
    state. Also, make sure to call this function to get the current profile
    fields before calling the reassoc. So that pModifyProfileFields will have
    all the latest values plus the one(s) has been updated as part of reassoc
    request.
    \param pModifyProfileFields - pointer to the connected profile fields
    changing which can cause reassoc

    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_GetModifyProfileFields(tHalHandle hHal, tANI_U8 sessionId,
                                     tCsrRoamModifyProfileFields * pModifyProfileFields)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, sessionId, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
       {
          status = csrGetModifyProfileFields(pMac, sessionId, pModifyProfileFields);
       }
       else
       {
          status = eHAL_STATUS_INVALID_PARAMETER;
       }
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/*--------------------------------------------------------------------------
    \fn sme_SetConfigPowerSave
    \brief  Wrapper fn to change power save configuration in SME (PMC) module.
            For BMPS related configuration, this function also updates the CFG
            and sends a message to FW to pick up the new values. Note: Calling
            this function only updates the configuration and does not enable
            the specified power save mode.
    \param  hHal - The handle returned by macOpen.
    \param  psMode - Power Saving mode being modified
    \param  pConfigParams - a pointer to a caller allocated object of type
            tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams
    \return eHalStatus
  --------------------------------------------------------------------------*/
eHalStatus sme_SetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode,
                                  void *pConfigParams)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                 TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE, NO_SESSION, 0));
   if (NULL == pConfigParams ) {
      smsLog( pMac, LOGE, "Empty config param structure for PMC, "
              "nothing to update");
      return eHAL_STATUS_FAILURE;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcSetConfigPowerSave(hHal, psMode, pConfigParams);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/*--------------------------------------------------------------------------
    \fn sme_GetConfigPowerSave
    \brief  Wrapper fn to retrieve power save configuration in SME (PMC) module
    \param  hHal - The handle returned by macOpen.
    \param  psMode - Power Saving mode
    \param  pConfigParams - a pointer to a caller allocated object of type
            tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams
    \return eHalStatus
  --------------------------------------------------------------------------*/
eHalStatus sme_GetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode,
                                  void *pConfigParams)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
            TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE, NO_SESSION, 0));
   if (NULL == pConfigParams ) {
      smsLog( pMac, LOGE, "Empty config param structure for PMC, "
              "nothing to update");
      return eHAL_STATUS_FAILURE;
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcGetConfigPowerSave(hHal, psMode, pConfigParams);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_EnablePowerSave
    \brief  Enables one of the power saving modes.
    \param  hHal - The handle returned by macOpen.
    \param  psMode - The power saving mode to enable. If BMPS mode is enabled
                     while the chip is operating in Full Power, PMC will start
                     a timer that will try to put the chip in BMPS mode after
                     expiry.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_EnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE, NO_SESSION, psMode));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status =  pmcEnablePowerSave(hHal, psMode);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_DisablePowerSave
    \brief   Disables one of the power saving modes.
    \param  hHal - The handle returned by macOpen.
    \param  psMode - The power saving mode to disable. Disabling does not imply
                     that device will be brought out of the current PS mode. This
                     is purely a configuration API.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_DisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE, NO_SESSION, psMode));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcDisablePowerSave(hHal, psMode);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
 }

/* ---------------------------------------------------------------------------
+    \fn sme_SetHostPowerSave
+    \brief   Enables BMPS logic to be controlled by User level apps
+    \param  hHal - The handle returned by macOpen.
+    \param  psMode - The power saving mode to disable. Disabling does not imply
+                     that device will be brought out of the current PS mode. This
+                     is purely a configuration API.
+    \return eHalStatus
+  ---------------------------------------------------------------------------*/
eHalStatus sme_SetHostPowerSave (tHalHandle hHal, v_BOOL_t psMode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   pMac->pmc.isHostPsEn = psMode;

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_StartAutoBmpsTimer
    \brief  Starts a timer that periodically polls all the registered
            module for entry into Bmps mode. This timer is started only if BMPS is
            enabled and whenever the device is in full power.
    \param  hHal - The handle returned by macOpen.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_StartAutoBmpsTimer ( tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER, NO_SESSION, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcStartAutoBmpsTimer(hHal);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}
/* ---------------------------------------------------------------------------
    \fn sme_StopAutoBmpsTimer
    \brief  Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer
            Stopping the timer does not cause a device state change. Only the timer
            is stopped. If "Full Power" is desired, use the sme_RequestFullPower API
    \param  hHal - The handle returned by macOpen.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_StopAutoBmpsTimer ( tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER, NO_SESSION, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcStopAutoBmpsTimer(hHal);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}
/**
 * sme_process_set_max_tx_power() - Set the Maximum Transmit Power
 *
 * @pMac: mac pointer.
 * @command: cmd param containing bssid, self mac
 *           and power in db
 *
 * Set the maximum transmit power dynamically.
 *
 * Return: eHalStatus
 *
 */
eHalStatus sme_process_set_max_tx_power(tpAniSirGlobal pMac,
						tSmeCmd *command)
{
	vos_msg_t msg;
	tMaxTxPowerParams *max_tx_params = NULL;

	max_tx_params = vos_mem_malloc(sizeof(*max_tx_params));
	if (NULL == max_tx_params)
	{
		smsLog(pMac, LOGE, FL("fail to allocate memory for max_tx_params"));
		return eHAL_STATUS_FAILURE;
	}

	vos_mem_copy(max_tx_params->bssId,
		command->u.set_tx_max_pwr.bssid, SIR_MAC_ADDR_LENGTH);
	vos_mem_copy(max_tx_params->selfStaMacAddr,
		command->u.set_tx_max_pwr.self_sta_mac_addr,
				SIR_MAC_ADDR_LENGTH);
	max_tx_params->power =
			command->u.set_tx_max_pwr.power;

	msg.type = WDA_SET_MAX_TX_POWER_REQ;
	msg.reserved = 0;
	msg.bodyptr = max_tx_params;

	if(VOS_STATUS_SUCCESS !=
		vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
	{
		smsLog(pMac, LOGE,
			FL("Not able to post WDA_SET_MAX_TX_POWER_REQ message to WDA"));
		vos_mem_free(max_tx_params);
		return eHAL_STATUS_FAILURE;
	}
	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_process_set_max_tx_power_per_band() - Set the Maximum Transmit Power
 * specific to band dynamically
 * @mac_ctx: mac context
 * @command: cmd param containing band, and power in db
 *
 * Set the maximum transmit power dynamically per band
 *
 * Return: eHalStatus
 */
eHalStatus sme_process_set_max_tx_power_per_band(tpAniSirGlobal mac_ctx,
                  tSmeCmd *command)
{
	vos_msg_t msg;
	tMaxTxPowerPerBandParams *max_tx_params_per_band;

	max_tx_params_per_band =
		vos_mem_malloc(sizeof(*max_tx_params_per_band));
	if (max_tx_params_per_band == NULL) {
		smsLog(mac_ctx, LOGE,
			   FL("fail to allocate memory"));
		return eHAL_STATUS_FAILURE;
	}

	max_tx_params_per_band->bandInfo =
		command->u.set_tx_max_pwr_per_band.band;
	max_tx_params_per_band->power =
			command->u.set_tx_max_pwr_per_band.power;

	msg.type = WDA_SET_MAX_TX_POWER_PER_BAND_REQ;
	msg.reserved = 0;
	msg.bodyptr = max_tx_params_per_band;

	if (VOS_STATUS_SUCCESS !=
			vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
		smsLog(mac_ctx, LOGE,
			   FL("Unable to post message to WDA"));
		vos_mem_free(max_tx_params_per_band);
		return eHAL_STATUS_FAILURE;
	}
	return eHAL_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------
    \fn sme_QueryPowerState
    \brief  Returns the current power state of the device.
    \param  hHal - The handle returned by macOpen.
    \param pPowerState - pointer to location to return power state (LOW or HIGH)
    \param pSwWlanSwitchState - ptr to location to return SW WLAN Switch state
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_QueryPowerState (
   tHalHandle hHal,
   tPmcPowerState *pPowerState,
   tPmcSwitchState *pSwWlanSwitchState)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcQueryPowerState (hHal, pPowerState, NULL, pSwWlanSwitchState);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_IsPowerSaveEnabled
    \brief  Checks if the device is able to enter a particular power save mode
            This does not imply that the device is in a particular PS mode
    \param  hHal - The handle returned by macOpen.
    \param  sessionId - sme session id
    \param psMode - the power saving mode
    \return eHalStatus
  ---------------------------------------------------------------------------*/
tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal,
                                     tANI_U32 sessionId,
                                     tPmcPowerSavingMode psMode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tANI_BOOLEAN result = false;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED, NO_SESSION, psMode));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       if(!pMac->psOffloadEnabled)
          result = pmcIsPowerSaveEnabled(hHal, psMode);
       else
          result = pmcOffloadIsPowerSaveEnabled(hHal, sessionId, psMode);
       sme_ReleaseGlobalLock( &pMac->sme );
       return result;
   }

   return false;
}

/* ---------------------------------------------------------------------------
    \fn sme_RequestFullPower
    \brief  Request that the device be brought to full power state. When the
            device enters Full Power PMC will start a BMPS timer if BMPS PS mode
            is enabled. On timer expiry PMC will attempt to put the device in
            BMPS mode if following holds true:
            - BMPS mode is enabled
            - Polling of all modules through the Power Save Check routine passes
            - STA is associated to an access point
    \param  hHal - The handle returned by macOpen.
    \param  - callbackRoutine Callback routine invoked in case of success/failure
    \return eHalStatus - status
     eHAL_STATUS_SUCCESS - device brought to full power state
     eHAL_STATUS_FAILURE - device cannot be brought to full power state
     eHAL_STATUS_PMC_PENDING - device is being brought to full power state,
  ---------------------------------------------------------------------------*/
eHalStatus sme_RequestFullPower (
   tHalHandle hHal,
   void (*callbackRoutine) (void *callbackContext, eHalStatus status),
   void *callbackContext,
   tRequestFullPowerReason fullPowerReason)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
         TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER, NO_SESSION, fullPowerReason));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcRequestFullPower(hHal, callbackRoutine, callbackContext, fullPowerReason);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RequestBmps
    \brief  Request that the device be put in BMPS state. Request will be
            accepted only if BMPS mode is enabled and power save check routine
            passes.
    \param  hHal - The handle returned by macOpen.
    \param  - callbackRoutine Callback routine invoked in case of success/failure
    \return eHalStatus
      eHAL_STATUS_SUCCESS - device is in BMPS state
      eHAL_STATUS_FAILURE - device cannot be brought to BMPS state
      eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state
  ---------------------------------------------------------------------------*/
eHalStatus sme_RequestBmps (
   tHalHandle hHal,
   void (*callbackRoutine) (void *callbackContext, eHalStatus status),
   void *callbackContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_REQUEST_BMPS, NO_SESSION, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcRequestBmps(hHal, callbackRoutine, callbackContext);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}


/* ---------------------------------------------------------------------------
    \fn  sme_SetDHCPTillPowerActiveFlag
    \brief  Sets/Clears DHCP related flag in PMC to disable/enable auto BMPS
            entry by PMC
    \param  hHal - The handle returned by macOpen.
  ---------------------------------------------------------------------------*/
void  sme_SetDHCPTillPowerActiveFlag(tHalHandle hHal, tANI_U8 flag)
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION, flag));
   /* Set/Clear the DHCP flag which will disable/enable
      auto BMPS enter by PMC */
   pMac->pmc.remainInPowerActiveTillDHCP = flag;
}


/* ---------------------------------------------------------------------------
    \fn sme_StartUapsd
    \brief  Request that the device be put in UAPSD state. If the device is in
            Full Power it will be put in BMPS mode first and then into UAPSD
            mode.
    \param  hHal - The handle returned by macOpen.
    \param  - callbackRoutine Callback routine invoked in case of success/failure
      eHAL_STATUS_SUCCESS - device is in UAPSD state
      eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state
      eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state
      eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_StartUapsd (
   tHalHandle hHal,
   void (*callbackRoutine) (void *callbackContext, eHalStatus status),
   void *callbackContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcStartUapsd(hHal, callbackRoutine, callbackContext);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
 }

/* ---------------------------------------------------------------------------
    \fn sme_StopUapsd
    \brief  Request that the device be put out of UAPSD state. Device will be
            put in in BMPS state after stop UAPSD completes.
    \param  hHal - The handle returned by macOpen.
    \return eHalStatus
      eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state
      eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state
  ---------------------------------------------------------------------------*/
eHalStatus sme_StopUapsd (tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcStopUapsd(hHal);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RequestStandby
    \brief  Request that the device be put in standby. It is HDD's responsibility
            to bring the chip to full power and do a disassoc before calling
            this API.
    \param  hHal - The handle returned by macOpen.
    \param  - callbackRoutine Callback routine invoked in case of success/failure
    \return eHalStatus
      eHAL_STATUS_SUCCESS - device is in Standby mode
      eHAL_STATUS_FAILURE - device cannot be put in standby mode
      eHAL_STATUS_PMC_PENDING - device is being put in standby mode
  ---------------------------------------------------------------------------*/
eHalStatus sme_RequestStandby (
   tHalHandle hHal,
   void (*callbackRoutine) (void *callbackContext, eHalStatus status),
   void *callbackContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY, NO_SESSION, 0));
   smsLog( pMac, LOG1, FL(" called") );
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcRequestStandby(hHal, callbackRoutine, callbackContext);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RegisterPowerSaveCheck
    \brief  Register a power save check routine that is called whenever
            the device is about to enter one of the power save modes.
    \param  hHal - The handle returned by macOpen.
    \param  checkRoutine -  Power save check routine to be registered
    \return eHalStatus
            eHAL_STATUS_SUCCESS - successfully registered
            eHAL_STATUS_FAILURE - not successfully registered
  ---------------------------------------------------------------------------*/
eHalStatus sme_RegisterPowerSaveCheck (
   tHalHandle hHal,
   tANI_BOOLEAN (*checkRoutine) (void *checkContext), void *checkContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcRegisterPowerSaveCheck (hHal, checkRoutine, checkContext);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_Register11dScanDoneCallback
    \brief  Register a routine of type csrScanCompleteCallback which is
            called whenever an 11d scan is done
    \param  hHal - The handle returned by macOpen.
    \param  callback -  11d scan complete routine to be registered
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_Register11dScanDoneCallback (
   tHalHandle hHal,
   csrScanCompleteCallback callback)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   pMac->scan.callback11dScanDone = callback;

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_DeregisterPowerSaveCheck
    \brief  Deregister a power save check routine
    \param  hHal - The handle returned by macOpen.
    \param  checkRoutine -  Power save check routine to be deregistered
    \return eHalStatus
            eHAL_STATUS_SUCCESS - successfully deregistered
            eHAL_STATUS_FAILURE - not successfully deregistered
  ---------------------------------------------------------------------------*/
eHalStatus sme_DeregisterPowerSaveCheck (
   tHalHandle hHal,
   tANI_BOOLEAN (*checkRoutine) (void *checkContext))
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcDeregisterPowerSaveCheck (hHal, checkRoutine);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_RegisterDeviceStateUpdateInd
    \brief  Register a callback routine that is called whenever
            the device enters a new device state (Full Power, BMPS, UAPSD)
    \param  hHal - The handle returned by macOpen.
    \param  callbackRoutine -  Callback routine to be registered
    \param  callbackContext -  Cookie to be passed back during callback
    \return eHalStatus
            eHAL_STATUS_SUCCESS - successfully registered
            eHAL_STATUS_FAILURE - not successfully registered
  ---------------------------------------------------------------------------*/
eHalStatus sme_RegisterDeviceStateUpdateInd (
   tHalHandle hHal,
   void (*callbackRoutine) (void *callbackContext, tPmcState pmcState),
   void *callbackContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcRegisterDeviceStateUpdateInd (hHal, callbackRoutine, callbackContext);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_DeregisterDeviceStateUpdateInd
    \brief  Deregister a routine that was registered for device state changes
    \param  hHal - The handle returned by macOpen.
    \param  callbackRoutine -  Callback routine to be deregistered
    \return eHalStatus
            eHAL_STATUS_SUCCESS - successfully deregistered
            eHAL_STATUS_FAILURE - not successfully deregistered
  ---------------------------------------------------------------------------*/
eHalStatus sme_DeregisterDeviceStateUpdateInd (
   tHalHandle hHal,
   void (*callbackRoutine) (void *callbackContext, tPmcState pmcState))
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcDeregisterDeviceStateUpdateInd (hHal, callbackRoutine);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_WowlAddBcastPattern
    \brief  Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will
            do a pattern match on these patterns when Wowl is enabled during BMPS
            mode. Note that Firmware performs the pattern matching only on
            broadcast frames and while Libra is in BMPS mode.
    \param  hHal - The handle returned by macOpen.
    \param  pattern -  Pattern to be added
    \return eHalStatus
            eHAL_STATUS_FAILURE  Cannot add pattern
            eHAL_STATUS_SUCCESS  Request accepted.
  ---------------------------------------------------------------------------*/
eHalStatus sme_WowlAddBcastPattern (
   tHalHandle hHal,
   tpSirWowlAddBcastPtrn pattern,
   tANI_U8    sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, sessionId, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
       status = pmcWowlAddBcastPattern (hHal, pattern, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_WowlDelBcastPattern
    \brief  Delete a pattern that was added for Pattern Byte Matching.
    \param  hHal - The handle returned by macOpen.
    \param  pattern -  Pattern to be deleted
    \return eHalStatus
            eHAL_STATUS_FAILURE  Cannot delete pattern
            eHAL_STATUS_SUCCESS  Request accepted.
  ---------------------------------------------------------------------------*/
eHalStatus sme_WowlDelBcastPattern (
   tHalHandle hHal,
   tpSirWowlDelBcastPtrn pattern,
   tANI_U8  sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, sessionId, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
       status = pmcWowlDelBcastPattern (hHal, pattern, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_EnterWowl
    \brief  This is the SME API exposed to HDD to request enabling of WOWL mode.
            WoWLAN works on top of BMPS mode. If the device is not in BMPS mode,
            SME will will cache the information that WOWL has been enabled and
            attempt to put the device in BMPS. On entry into BMPS, SME will
            enable the WOWL mode.
            Note 1: If we exit BMPS mode (someone requests full power), we
            will NOT resume WOWL when we go back to BMPS again. Request for full
            power (while in WOWL mode) means disable WOWL and go to full power.
            Note 2: Both UAPSD and WOWL work on top of BMPS. On entry into BMPS, SME
            will give priority to UAPSD and enable only UAPSD if both UAPSD and WOWL
            are required. Currently there is no requirement or use case to support
            UAPSD and WOWL at the same time.

    \param  hHal - The handle returned by macOpen.
    \param  enterWowlCallbackRoutine -  Callback routine provided by HDD.
                               Used for success/failure notification by SME
    \param  enterWowlCallbackContext - A cookie passed by HDD, that is passed back to HDD
                              at the time of callback.
    \param  wakeReasonIndCB -  Callback routine provided by HDD.
                               Used for Wake Reason Indication by SME
    \param  wakeReasonIndCBContext - A cookie passed by HDD, that is passed back to HDD
                              at the time of callback.
    \return eHalStatus
            eHAL_STATUS_SUCCESS  Device is already in WoWLAN mode
            eHAL_STATUS_FAILURE  Device cannot enter WoWLAN mode.
            eHAL_STATUS_PMC_PENDING  Request accepted. SME will enable WOWL after
                                      BMPS mode is entered.
  ---------------------------------------------------------------------------*/
eHalStatus sme_EnterWowl (
    tHalHandle hHal,
    void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status),
    void *enterWowlCallbackContext,
#ifdef WLAN_WAKEUP_EVENTS
    void (*wakeIndicationCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd),
    void *wakeIndicationCBContext,
#endif // WLAN_WAKEUP_EVENTS
    tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_ENTER_WOWL, sessionId, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
       status = pmcEnterWowl (hHal, enterWowlCallbackRoutine, enterWowlCallbackContext,
#ifdef WLAN_WAKEUP_EVENTS
                              wakeIndicationCB, wakeIndicationCBContext,
#endif // WLAN_WAKEUP_EVENTS
                              wowlEnterParams, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}
/* ---------------------------------------------------------------------------
    \fn sme_ExitWowl
    \brief  This is the SME API exposed to HDD to request exit from WoWLAN mode.
            SME will initiate exit from WoWLAN mode and device will be put in BMPS
            mode.
    \param  hHal - The handle returned by macOpen.
    \param  wowlExitParams - Carries info on which smesession
                             wowl exit is requested.
    \return eHalStatus
            eHAL_STATUS_FAILURE  Device cannot exit WoWLAN mode.
            eHAL_STATUS_SUCCESS  Request accepted to exit WoWLAN mode.
  ---------------------------------------------------------------------------*/
eHalStatus sme_ExitWowl (tHalHandle hHal, tpSirSmeWowlExitParams wowlExitParams)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
           TRACE_CODE_SME_RX_HDD_EXIT_WOWL, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
       status = pmcExitWowl (hHal, wowlExitParams);
       sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

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

    \fn sme_RoamSetKey

    \brief To set encryption key. This function should be called only when connected
    This is an asynchronous API.

    \param pSetKeyInfo - pointer to a caller allocated object of tCsrSetContextInfo

    \param pRoamId  Upon success return, this is the id caller can use to identify the request in roamcallback

    \return eHalStatus  SUCCESS  Roam callback will be called indicate actually results

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamSetKey(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 *pRoamId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tANI_U32 roamId;
   tANI_U32 i;
   tCsrRoamSession *pSession = NULL;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_SET_KEY, sessionId, 0));
   if (pSetKey->keyLength > CSR_MAX_KEY_LEN)
   {
      smsLog(pMac, LOGE, FL("Invalid key length %d"), pSetKey->keyLength);
      return eHAL_STATUS_FAILURE;
   }
   /*Once Setkey is done, we can go in BMPS */
   if(pSetKey->keyLength) {
     pMac->pmc.full_power_till_set_key = false;
     smsLog(pMac, LOG1, FL("Reset full_power_till_set_key"
                           " to allow BMPS"));
   }

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      roamId = GET_NEXT_ROAM_ID(&pMac->roam);
      if(pRoamId)
      {
         *pRoamId = roamId;
      }

      smsLog(pMac, LOG2, FL("keyLength %d"), pSetKey->keyLength);

      for(i=0; i<pSetKey->keyLength; i++)
          smsLog(pMac, LOG2, FL("%02x"), pSetKey->Key[i]);

      smsLog(pMac, LOG2, "\n sessionId=%d roamId=%d", sessionId, roamId);

      pSession = CSR_GET_SESSION(pMac, sessionId);

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

      if(CSR_IS_INFRA_AP(&pSession->connectedProfile))
      {
         if(pSetKey->keyDirection == eSIR_TX_DEFAULT)
         {
            if ( ( eCSR_ENCRYPT_TYPE_WEP40 == pSetKey->encType ) ||
                 ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pSetKey->encType ))
            {
               pSession->pCurRoamProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
            }
            if ( ( eCSR_ENCRYPT_TYPE_WEP104 == pSetKey->encType ) ||
                 ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pSetKey->encType ))
            {
               pSession->pCurRoamProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
            }
         }
      }

      status = csrRoamSetKey ( pMac, sessionId, pSetKey, roamId );
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/*
 * sme_roam_set_default_key_index - function to set default wep key idx
 * @hHal: pointer to hal handler
 * @session_id: session id
 * @default_idx: default wep key index
 *
 * function prepares a message and post to WMA to set wep default
 * key index
 *
 * return: Success:eHAL_STATUS_SUCCESS Failure: Error value
 */
eHalStatus sme_roam_set_default_key_index(tHalHandle hHal, uint8_t session_id,
				 uint8_t default_idx)
{
	vos_msg_t msg;
	struct wep_update_default_key_idx *update_key;

	update_key = vos_mem_malloc(sizeof(struct wep_update_default_key_idx));
	if (!update_key) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "Failed to allocate memory for update key");
		return eHAL_STATUS_FAILED_ALLOC;
	}

	update_key->session_id = session_id;
	update_key->default_idx = default_idx;

	msg.type = WDA_UPDATE_WEP_DEFAULT_KEY;
	msg.reserved = 0;
	msg.bodyptr = (void *)update_key;

	if (VOS_STATUS_SUCCESS !=
			vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
			  "%s: Failed to post msg to WDA", __func__);
		vos_mem_free(update_key);
		return eHAL_STATUS_FAILURE;
	}

	return eHAL_STATUS_SUCCESS;
}


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

    \fn sme_RoamRemoveKey

    \brief To set encryption key. This is an asynchronous API.

    \param pRemoveKey - pointer to a caller allocated object of tCsrRoamRemoveKey

    \param pRoamId  Upon success return, this is the id caller can use to identify the request in roamcallback

    \return eHalStatus  SUCCESS  Roam callback will be called indicate actually results

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamRemoveKey(tHalHandle hHal, tANI_U8 sessionId,
                             tCsrRoamRemoveKey *pRemoveKey, tANI_U32 *pRoamId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tANI_U32 roamId;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
          TRACE_CODE_SME_RX_HDD_REMOVE_KEY, sessionId, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      roamId = GET_NEXT_ROAM_ID(&pMac->roam);
      if(pRoamId)
      {
         *pRoamId = roamId;
      }
      status = csrRoamIssueRemoveKeyCommand( pMac, sessionId, pRemoveKey, roamId );
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_GetRssi
    \brief a wrapper function that client calls to register a callback to get
           RSSI

    \param hHal - HAL handle for device
    \param callback - SME sends back the requested stats using the callback
    \param staId -    The station ID for which the stats is requested for
    \param bssid - The bssid of the connected session
    \param lastRSSI - RSSI value at time of request. In case fw cannot provide
                      RSSI, do not hold up but return this value.
    \param pContext - user context to be passed back along with the callback
    \param pVosContext - vos context
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_GetRssi(tHalHandle hHal,
                             tCsrRssiCallback callback,
                             tANI_U8 staId, tCsrBssid bssId, tANI_S8 lastRSSI,
                             void *pContext, void* pVosContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                TRACE_CODE_SME_RX_HDD_GET_RSSI, NO_SESSION,  0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrGetRssi( pMac, callback,
                           staId, bssId, lastRSSI,
                           pContext, pVosContext);
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_GetSnr
    \brief a wrapper function that client calls to register a callback to
           get SNR

    \param callback - SME sends back the requested stats using the callback
    \param staId - The station ID for which the stats is requested for
    \param pContext - user context to be passed back along with the callback
    \param pVosContext - vos context
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_GetSnr(tHalHandle hHal,
                      tCsrSnrCallback callback,
                      tANI_U8 staId, tCsrBssid bssId,
                      void *pContext)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrGetSnr(pMac, callback,
                          staId, bssId, pContext);
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return status;
}

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/* ---------------------------------------------------------------------------
    \fn sme_GetTsmStats
    \brief a wrapper function that client calls to register a callback to
     get TSM Stats
    \param callback - SME sends back the requested stats using the callback
    \param staId - The station ID for which the stats is requested for
    \param pContext - user context to be passed back along with the callback
    \param pVosContext - vos context
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_GetTsmStats(tHalHandle hHal,
                             tCsrTsmStatsCallback callback,
                             tANI_U8 staId, tCsrBssid bssId,
                             void *pContext, void* pVosContext, tANI_U8 tid)
{
   eHalStatus     status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrGetTsmStats( pMac, callback,
                                 staId, bssId, pContext, pVosContext, tid);
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}
#endif

/* ---------------------------------------------------------------------------
    \fn sme_GetStatistics
    \brief a wrapper function that client calls to register a callback to get
    different PHY level statistics from CSR.

    \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc
    \param statsMask - The different category/categories of stats requester is looking for
    \param callback - SME sends back the requested stats using the callback
    \param periodicity - If requester needs periodic update in millisec, 0 means
                         it's an one time request
    \param cache - If requester is happy with cached stats
    \param staId - The station ID for which the stats is requested for
    \param pContext - user context to be passed back along with the callback
    \param sessionId - sme session interface
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId,
                             tANI_U32 statsMask,
                             tCsrStatsCallback callback,
                             tANI_U32 periodicity, tANI_BOOLEAN cache,
                             tANI_U8 staId, void *pContext,
                             tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION,  periodicity));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrGetStatistics( pMac, requesterId , statsMask, callback,
                                 periodicity, cache, staId, pContext,
                                 sessionId );
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);

}

eHalStatus sme_getLinkStatus(tHalHandle hHal,
                             tCsrLinkStatusCallback callback,
                             void *pContext,
                             tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tAniGetLinkStatus *pMsg;
   vos_msg_t vosMessage;

   status = sme_AcquireGlobalLock(&pMac->sme);
   if (HAL_STATUS_SUCCESS(status)) {
        pMsg = vos_mem_malloc(sizeof(tAniGetLinkStatus));
        if (NULL == pMsg) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                   "%s: Not able to allocate memory for link status", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        pMsg->msgType = WDA_LINK_STATUS_GET_REQ;
        pMsg->msgLen = (tANI_U16)sizeof(tAniGetLinkStatus);
        pMsg->sessionId = sessionId;
        pMac->sme.linkStatusContext = pContext;
        pMac->sme.linkStatusCallback = callback;

        vosMessage.type = WDA_LINK_STATUS_GET_REQ;
        vosMessage.bodyptr = pMsg;
        vosMessage.reserved = 0;

        if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
                                   &vosMessage))) {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                         "%s: Post LINK STATUS MSG fail", __func__);
           vos_mem_free(pMsg);
           pMac->sme.linkStatusContext = NULL;
           pMac->sme.linkStatusCallback = NULL;
           status = eHAL_STATUS_FAILURE;
        }

        sme_ReleaseGlobalLock(&pMac->sme);
   }

   return (status);
}

/**
 * sme_get_fw_state() - post message to wma to get firmware state
 * @callback: HDD callback to be called on receiving firmware state
 * @pcontext: callback context
 *
 * Return: eHAL_STATUS_SUCCESS on success or failure status
 */
eHalStatus sme_get_fw_state(tHalHandle hHal,
				tcsr_fw_state_callback callback,
				void *context)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hHal);
	vos_msg_t vos_message;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		vos_message.type = WDA_GET_FW_STATUS_REQ;
		vos_message.bodyptr = NULL;
		vos_message.reserved = 0;
		mac->sme.fw_state_context = context;
		mac->sme.fw_state_callback = callback;

		if (!VOS_IS_STATUS_SUCCESS(
			vos_mq_post_message(VOS_MODULE_ID_WDA, &vos_message))) {
			smsLog(mac, LOGE, FL("Post firmware STATUS MSG fail"));
			mac->sme.fw_state_context = NULL;
			mac->sme.fw_state_callback = NULL;
			status = eHAL_STATUS_FAILURE;
		}

		sme_ReleaseGlobalLock(&mac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn smeGetTLSTAState
    \helper function to get the TL STA State whenever the function is called.

    \param staId - The staID to be passed to the TL
            to get the relevant TL STA State
    \return the state as tANI_U16
  ---------------------------------------------------------------------------*/
tANI_U16 smeGetTLSTAState(tHalHandle hHal, tANI_U8 staId)
{
   tANI_U16 tlSTAState = TL_INIT_STATE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   eHalStatus status = eHAL_STATUS_FAILURE;

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      tlSTAState = csrGetTLSTAState( pMac, staId);
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return tlSTAState;
}

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

    \fn sme_GetCountryCode

    \brief To return the current country code. If no country code is applied,
           default country code is used to fill the buffer.
    If 11d supported is turned off, an error is return and the last
    applied/default country code is used.
    This is a synchronous API.

    \param pBuf - pointer to a caller allocated buffer for returned country code

    \param pbLen  For input, this parameter indicates how big is the buffer.
                  Upon return, this parameter has the number of bytes for
                  country. If pBuf doesn't have enough space,
                  this function returns fail status and this parameter contains
                  the number that is needed.

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.

  ----------------------------------------------------------------------------*/
eHalStatus sme_GetCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U8 *pbLen)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                 TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0));

    return ( csrGetCountryCode( pMac, pBuf, pbLen ) );
}


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

    \fn sme_SetCountryCode

    \brief To change the current/default country code.
    If 11d supported is turned off, an error is return.
    This is a synchronous API.

    \param pCountry - pointer to a caller allocated buffer for the country code.

    \param pfRestartNeeded  A pointer to caller allocated memory, upon successful return, it indicates
    whether a reset is required.

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_SetCountryCode(tHalHandle hHal, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE, NO_SESSION, 0));
    return ( csrSetCountryCode( pMac, pCountry, pfRestartNeeded ) );
}


/* ---------------------------------------------------------------------------
    \fn sme_ResetCountryCodeInformation
    \brief this function is to reset the country code current being used back to EEPROM default
    this includes channel list and power setting. This is a synchronous API.
    \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether
    a restart is needed to apply the change
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_ResetCountryCodeInformation(tHalHandle hHal, tANI_BOOLEAN *pfRestartNeeded)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return ( csrResetCountryCodeInformation( pMac, pfRestartNeeded ) );
}


/* ---------------------------------------------------------------------------
    \fn sme_GetSupportedCountryCode
    \brief this function is to get a list of the country code current being supported
    \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return,
    this has the country code list. 3 bytes for each country code. This may be NULL if
    caller wants to know the needed byte count.
    \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return,
    this contains the length of the data in pBuf. If pbuf is NULL, as input, *pbLen should be 0.
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_GetSupportedCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U32 *pbLen)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return ( csrGetSupportedCountryCode( pMac, pBuf, pbLen ) );
}


/* ---------------------------------------------------------------------------
    \fn sme_GetCurrentRegulatoryDomain
    \brief this function is to get the current regulatory domain. This is a synchronous API.
    This function must be called after CFG is downloaded and all the band/mode setting already passed into
    SME. The function fails if 11d support is turned off.
    \param pDomain - Caller allocated buffer to return the current domain.
    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.
  -------------------------------------------------------------------------------*/
eHalStatus sme_GetCurrentRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t *pDomain)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;

    if( pDomain )
    {
        if( csrIs11dSupported( pMac ) )
        {
            *pDomain = csrGetCurrentRegulatoryDomain( pMac );
            status = eHAL_STATUS_SUCCESS;
        }
        else
        {
            status = eHAL_STATUS_FAILURE;
        }
    }

    return ( status );
}


/* ---------------------------------------------------------------------------
    \fn sme_SetRegulatoryDomain
    \brief this function is to set the current regulatory domain.
    This function must be called after CFG is downloaded and all the band/mode setting already passed into
    SME. This is a synchronous API.
    \param domainId - indicate the domain (defined in the driver) needs to set to.
    See v_REGDOMAIN_t for definition
    \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether
    a restart is needed to apply the change
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_SetRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return ( csrSetRegulatoryDomain( pMac, domainId, pfRestartNeeded ) );
}


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

    \fn sme_GetRegulatoryDomainForCountry

    \brief To return a regulatory domain base on a country code. This is a synchronous API.

    \param pCountry - pointer to a caller allocated buffer for input country code.

    \param pDomainId  Upon successful return, it is the domain that country belongs to.
    If it is NULL, returning success means that the country code is known.

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_GetRegulatoryDomainForCountry(tHalHandle hHal, tANI_U8 *pCountry, v_REGDOMAIN_t *pDomainId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return csrGetRegulatoryDomainForCountry(pMac, pCountry, pDomainId,
                                            COUNTRY_QUERY);
}




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

    \fn sme_GetSupportedRegulatoryDomains

    \brief To return a list of supported regulatory domains. This is a synchronous API.

    \param pDomains - pointer to a caller allocated buffer for returned regulatory domains.

    \param pNumDomains  For input, this parameter indicates how many
                        domains pDomains can hold. Upon return, this parameter
                        has the number for supported domains. If pDomains
                        doesn't have enough space for all the supported domains,
                        this function returns fail status and this parameter
                        contains the number that is needed.

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_GetSupportedRegulatoryDomains(tHalHandle hHal, v_REGDOMAIN_t *pDomains, tANI_U32 *pNumDomains)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;

    //We support all domains for now
    if( pNumDomains )
    {
        if( NUM_REG_DOMAINS <= *pNumDomains )
        {
            status = eHAL_STATUS_SUCCESS;
        }
        *pNumDomains = NUM_REG_DOMAINS;
    }
    if( HAL_STATUS_SUCCESS( status ) )
    {
        if( pDomains )
        {
            pDomains[0] = REGDOMAIN_FCC;
            pDomains[1] = REGDOMAIN_ETSI;
            pDomains[2] = REGDOMAIN_JAPAN;
            pDomains[3] = REGDOMAIN_WORLD;
            pDomains[4] = REGDOMAIN_N_AMER_EXC_FCC;
            pDomains[5] = REGDOMAIN_APAC;
            pDomains[6] = REGDOMAIN_KOREA;
            pDomains[7] = REGDOMAIN_HI_5GHZ;
            pDomains[8] = REGDOMAIN_NO_5GHZ;
        }
        else
        {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
    }

    return ( status );
}


//some support functions
tANI_BOOLEAN sme_Is11dSupported(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return ( csrIs11dSupported( pMac ) );
}


tANI_BOOLEAN sme_Is11hSupported(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return ( csrIs11hSupported( pMac ) );
}


tANI_BOOLEAN sme_IsWmmSupported(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    return ( csrIsWmmSupported( pMac ) );
}

//Upper layer to get the list of the base channels to scan for passively 11d info from csr
eHalStatus sme_ScanGetBaseChannels( tHalHandle hHal, tCsrChannelInfo * pChannelInfo )
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   return(csrScanGetBaseChannels(pMac,pChannelInfo) );
}

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

    \fn sme_ChangeCountryCode

    \brief Change Country code from upper layer during WLAN driver operation.
           This is a synchronous API.

    \param hHal - The handle returned by macOpen.

    \param pCountry New Country Code String

    \param sendRegHint If we want to send reg hint to nl80211

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_ChangeCountryCode( tHalHandle hHal,
                                          tSmeChangeCountryCallback callback,
                                          tANI_U8 *pCountry,
                                          void *pContext,
                                          void* pVosContext,
                                          tAniBool countryFromUserSpace,
                                          tAniBool sendRegHint )
{
   eHalStatus                status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal            pMac = PMAC_STRUCT( hHal );
   vos_msg_t                 msg;
   tAniChangeCountryCodeReq *pMsg;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
            TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, NO_SESSION, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      smsLog(pMac, LOG1, FL(" called"));

      if ((pMac->roam.configParam.Is11dSupportEnabledOriginal == true) &&
          (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority))
      {

          smsLog(pMac, LOGW, "Set Country Code Fail since the STA is associated and userspace does not have priority ");

	  sme_ReleaseGlobalLock( &pMac->sme );
          status = eHAL_STATUS_FAILURE;
          return status;
      }

      pMsg = vos_mem_malloc(sizeof(tAniChangeCountryCodeReq));
      if ( NULL == pMsg )
      {
         smsLog(pMac, LOGE, " csrChangeCountryCode: failed to allocate mem for req");
         sme_ReleaseGlobalLock( &pMac->sme );
         return eHAL_STATUS_FAILURE;
      }

      pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANGE_COUNTRY_CODE);
      pMsg->msgLen = (tANI_U16)sizeof(tAniChangeCountryCodeReq);
      vos_mem_copy(pMsg->countryCode, pCountry, 3);
      pMsg->countryFromUserSpace = countryFromUserSpace;
      pMsg->sendRegHint = sendRegHint;
      pMsg->changeCCCallback = callback;
      pMsg->pDevContext = pContext;
      pMsg->pVosContext = pVosContext;

      msg.type = eWNI_SME_CHANGE_COUNTRY_CODE;
      msg.bodyptr = pMsg;
      msg.reserved = 0;

      if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg))
      {
          smsLog(pMac, LOGE, " sme_ChangeCountryCode failed to post msg to self ");
          vos_mem_free((void *)pMsg);
          status = eHAL_STATUS_FAILURE;
      }
      smsLog(pMac, LOG1, FL(" returned"));
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

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

    \fn sme_GenericChangeCountryCode

    \brief Change Country code from upper layer during WLAN driver operation.
           This is a synchronous API.

    \param hHal - The handle returned by macOpen.

    \param pCountry New Country Code String

    \param reg_domain regulatory domain

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.

-----------------------------------------------------------------------------*/
eHalStatus sme_GenericChangeCountryCode( tHalHandle hHal,
                                         tANI_U8 *pCountry,
                                         v_REGDOMAIN_t reg_domain)
{
    eHalStatus                status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal            pMac = PMAC_STRUCT( hHal );
    vos_msg_t                 msg;
    tAniGenericChangeCountryCodeReq *pMsg;

    if (NULL == pMac)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
            "%s: pMac is null", __func__);
        return status;
    }

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        smsLog(pMac, LOG1, FL(" called"));
        pMsg = vos_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq));

        if (NULL == pMsg)
        {
            smsLog(pMac, LOGE, " sme_GenericChangeCountryCode: failed to allocate mem for req");
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE);
        pMsg->msgLen = (tANI_U16)sizeof(tAniGenericChangeCountryCodeReq);
        vos_mem_copy(pMsg->countryCode, pCountry, 2);
        pMsg->countryCode[2] = ' '; /* For ASCII space */
        pMsg->domain_index = reg_domain;

        msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
        msg.bodyptr = pMsg;
        msg.reserved = 0;

        if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg))
        {
            smsLog(pMac, LOGE, "sme_GenericChangeCountryCode failed to post msg to self");
            vos_mem_free(pMsg);
            status = eHAL_STATUS_FAILURE;
        }
        smsLog(pMac, LOG1, FL(" returned"));
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}
/* ---------------------------------------------------------------------------

    \fn sme_DHCPStartInd

    \brief API to signal the FW about the DHCP Start event.

    \param hHal - HAL handle for device.

    \param device_mode - mode(AP,SAP etc) of the device.

    \param macAddr - MAC address of the adapter.

    \param sessionId - session ID.

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.
  --------------------------------------------------------------------------*/
eHalStatus sme_DHCPStartInd( tHalHandle hHal,
                                   tANI_U8 device_mode,
                                   tANI_U8 *macAddr,
                                   tANI_U8 sessionId )
{
    eHalStatus          status;
    VOS_STATUS          vosStatus;
    tpAniSirGlobal      pMac = PMAC_STRUCT( hHal );
    vos_msg_t           vosMessage;
    tAniDHCPInd         *pMsg;
    tCsrRoamSession     *pSession;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if ( eHAL_STATUS_SUCCESS == status)
    {
        pSession = CSR_GET_SESSION( pMac, sessionId );

        if (!pSession)
        {
            smsLog(pMac, LOGE, FL("session %d not found "), sessionId);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }
        pSession->dhcp_done = false;

        pMsg = (tAniDHCPInd*)vos_mem_malloc(sizeof(tAniDHCPInd));
        if (NULL == pMsg)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                   "%s: Not able to allocate memory for dhcp start", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }
        pMsg->msgType = WDA_DHCP_START_IND;
        pMsg->msgLen = (tANI_U16)sizeof(tAniDHCPInd);
        pMsg->device_mode = device_mode;
        vos_mem_copy( pMsg->adapterMacAddr, macAddr, sizeof(tSirMacAddr));
        vos_mem_copy( pMsg->peerMacAddr, pSession->connectedProfile.bssid,
                      sizeof(tSirMacAddr) );

        vosMessage.type = WDA_DHCP_START_IND;
        vosMessage.bodyptr = pMsg;
        vosMessage.reserved = 0;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                  sessionId, vosMessage.type));
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                         "%s: Post DHCP Start MSG fail", __func__);
           vos_mem_free(pMsg);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}
/* ---------------------------------------------------------------------------
    \fn sme_DHCPStopInd

    \brief API to signal the FW about the DHCP complete event.

    \param hHal - HAL handle for device.

    \param device_mode - mode(AP, SAP etc) of the device.

    \param macAddr - MAC address of the adapter.

    \param sessionId - session ID.

    \return eHalStatus  SUCCESS.
                         FAILURE or RESOURCES  The API finished and failed.
  --------------------------------------------------------------------------*/
eHalStatus sme_DHCPStopInd( tHalHandle hHal,
                              tANI_U8 device_mode,
                              tANI_U8 *macAddr,
                              tANI_U8 sessionId )
{
    eHalStatus          status;
    VOS_STATUS          vosStatus;
    tpAniSirGlobal      pMac = PMAC_STRUCT( hHal );
    vos_msg_t           vosMessage;
    tAniDHCPInd         *pMsg;
    tCsrRoamSession     *pSession;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if ( eHAL_STATUS_SUCCESS == status)
    {
        pSession = CSR_GET_SESSION( pMac, sessionId );

        if (!pSession)
        {
            smsLog(pMac, LOGE, FL("session %d not found "), sessionId);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }
        pSession->dhcp_done = false;

        pMsg = (tAniDHCPInd*)vos_mem_malloc(sizeof(tAniDHCPInd));
        if (NULL == pMsg)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Not able to allocate memory for dhcp stop", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
       }

       pMsg->msgType = WDA_DHCP_STOP_IND;
       pMsg->msgLen = (tANI_U16)sizeof(tAniDHCPInd);
       pMsg->device_mode = device_mode;
       vos_mem_copy( pMsg->adapterMacAddr, macAddr, sizeof(tSirMacAddr));
       vos_mem_copy( pMsg->peerMacAddr, pSession->connectedProfile.bssid,
                     sizeof(tSirMacAddr) );

       vosMessage.type = WDA_DHCP_STOP_IND;
       vosMessage.bodyptr = pMsg;
       vosMessage.reserved = 0;
       MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 sessionId, vosMessage.type));
       vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
       if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
       {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s: Post DHCP Stop MSG fail", __func__);
           vos_mem_free(pMsg);
           status = eHAL_STATUS_FAILURE;
       }

       sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

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

    \fn sme_TXFailMonitorStopInd

    \brief API to signal the FW to start monitoring TX failures

    \return eHalStatus  SUCCESS.

                         FAILURE or RESOURCES  The API finished and failed.
 --------------------------------------------------------------------------*/
eHalStatus sme_TXFailMonitorStartStopInd(tHalHandle hHal, tANI_U8 tx_fail_count,
                                         void * txFailIndCallback)
{
    eHalStatus            status;
    VOS_STATUS            vosStatus;
    tpAniSirGlobal        pMac = PMAC_STRUCT(hHal);
    vos_msg_t             vosMessage;
    tAniTXFailMonitorInd  *pMsg;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if ( eHAL_STATUS_SUCCESS == status)
    {
        pMsg = (tAniTXFailMonitorInd*)
                   vos_mem_malloc(sizeof(tAniTXFailMonitorInd));
        if (NULL == pMsg)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                   "%s: Failed to allocate memory", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        pMsg->msgType = WDA_TX_FAIL_MONITOR_IND;
        pMsg->msgLen = (tANI_U16)sizeof(tAniTXFailMonitorInd);

        //tx_fail_count = 0 should disable the Monitoring in FW
        pMsg->tx_fail_count = tx_fail_count;
        pMsg->txFailIndCallback = txFailIndCallback;

        vosMessage.type = WDA_TX_FAIL_MONITOR_IND;
        vosMessage.bodyptr = pMsg;
        vosMessage.reserved = 0;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                         "%s: Post TX Fail monitor Start MSG fail", __func__);
           vos_mem_free(pMsg);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_SetCfgPrivacy
    \brief  API to set configure privacy parameters
    \param  hHal - The handle returned by macOpen.
    \param  pProfile - Pointer CSR Roam profile.
    \param  fPrivacy - This parameter indicates status of privacy

    \return void
  ---------------------------------------------------------------------------*/
void sme_SetCfgPrivacy( tHalHandle hHal,
                        tCsrRoamProfile *pProfile,
                        tANI_BOOLEAN fPrivacy
                        )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, NO_SESSION, 0));
    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        csrSetCfgPrivacy(pMac, pProfile, fPrivacy);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
}

#if defined WLAN_FEATURE_VOWIFI
/* ---------------------------------------------------------------------------
    \fn sme_NeighborReportRequest
    \brief  API to request neighbor report.
    \param  hHal - The handle returned by macOpen.
    \param  pRrmNeighborReq - Pointer to a caller allocated object of type
                            tRrmNeighborReq. Caller owns the memory and is responsible
                            for freeing it.
    \return VOS_STATUS
            VOS_STATUS_E_FAILURE - failure
            VOS_STATUS_SUCCESS  success
  ---------------------------------------------------------------------------*/
VOS_STATUS sme_NeighborReportRequest (tHalHandle hHal, tANI_U8 sessionId,
                                    tpRrmNeighborReq pRrmNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo)
{
    VOS_STATUS status = VOS_STATUS_E_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                 TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION, 0));

    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        status = sme_RrmNeighborReportRequest (hHal, sessionId, pRrmNeighborReq, callbackInfo);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}
#endif

void pmcLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...)
{
    VOS_TRACE_LEVEL  vosDebugLevel;
    char    logBuffer[LOG_SIZE];
    va_list marker;

    /* getting proper Debug level */
    vosDebugLevel = getVosDebugLevel(loglevel);

    /* extracting arguments from pstring */
    va_start( marker, pString );
    vsnprintf(logBuffer, LOG_SIZE, pString, marker);

    VOS_TRACE(VOS_MODULE_ID_PMC, vosDebugLevel, "%s", logBuffer);
    va_end( marker );
}


void smsLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...)
{
#ifdef WLAN_DEBUG
    // Verify against current log level
    if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_SMS_MODULE_ID )] )
        return;
    else
    {
        va_list marker;

        va_start( marker, pString );     /* Initialize variable arguments. */

        logDebug(pMac, SIR_SMS_MODULE_ID, loglevel, pString, marker);

        va_end( marker );              /* Reset variable arguments.      */
    }
#endif
}

/* ---------------------------------------------------------------------------
    \fn sme_GetWcnssWlanCompiledVersion
    \brief  This API returns the version of the WCNSS WLAN API with
            which the HOST driver was built
    \param  hHal - The handle returned by macOpen.
    \param  pVersion - Points to the Version structure to be filled
    \return VOS_STATUS
            VOS_STATUS_E_INVAL - failure
            VOS_STATUS_SUCCESS  success
  ---------------------------------------------------------------------------*/
VOS_STATUS sme_GetWcnssWlanCompiledVersion(tHalHandle hHal,
                                           tSirVersionType *pVersion)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);

    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        if( pVersion != NULL )
        {
            status = WDA_GetWcnssWlanCompiledVersion(vosContext, pVersion);
        }
        else
        {
            status = VOS_STATUS_E_INVAL;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}


/* ---------------------------------------------------------------------------
    \fn sme_GetWcnssWlanReportedVersion
    \brief  This API returns the version of the WCNSS WLAN API with
            which the WCNSS driver reports it was built
    \param  hHal - The handle returned by macOpen.
    \param  pVersion - Points to the Version structure to be filled
    \return VOS_STATUS
            VOS_STATUS_E_INVAL - failure
            VOS_STATUS_SUCCESS  success
  ---------------------------------------------------------------------------*/
VOS_STATUS sme_GetWcnssWlanReportedVersion(tHalHandle hHal,
                                           tSirVersionType *pVersion)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);

    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        if( pVersion != NULL )
        {
            status = WDA_GetWcnssWlanReportedVersion(vosContext, pVersion);
        }
        else
        {
            status = VOS_STATUS_E_INVAL;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}


/* ---------------------------------------------------------------------------
    \fn sme_GetWcnssSoftwareVersion
    \brief  This API returns the version string of the WCNSS driver
    \param  hHal - The handle returned by macOpen.
    \param  pVersion - Points to the Version string buffer to be filled
    \param  versionBufferSize - THe size of the Version string buffer
    \return VOS_STATUS
            VOS_STATUS_E_INVAL - failure
            VOS_STATUS_SUCCESS  success
  ---------------------------------------------------------------------------*/
VOS_STATUS sme_GetWcnssSoftwareVersion(tHalHandle hHal,
                                       tANI_U8 *pVersion,
                                       tANI_U32 versionBufferSize)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);

    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        if( pVersion != NULL )
        {
            status = WDA_GetWcnssSoftwareVersion(vosContext, pVersion,
                                                 versionBufferSize);
        }
        else
        {
            status = VOS_STATUS_E_INVAL;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}


/* ---------------------------------------------------------------------------
    \fn sme_GetWcnssHardwareVersion
    \brief  This API returns the version string of the WCNSS hardware
    \param  hHal - The handle returned by macOpen.
    \param  pVersion - Points to the Version string buffer to be filled
    \param  versionBufferSize - THe size of the Version string buffer
    \return VOS_STATUS
            VOS_STATUS_E_INVAL - failure
            VOS_STATUS_SUCCESS  success
  ---------------------------------------------------------------------------*/
VOS_STATUS sme_GetWcnssHardwareVersion(tHalHandle hHal,
                                       tANI_U8 *pVersion,
                                       tANI_U32 versionBufferSize)
{
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);

    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        if( pVersion != NULL )
        {
            status = WDA_GetWcnssHardwareVersion(vosContext, pVersion,
                                                 versionBufferSize);
        }
        else
        {
            status = VOS_STATUS_E_INVAL;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}


#ifdef FEATURE_WLAN_WAPI

/* ---------------------------------------------------------------------------
    \fn sme_ScanGetBKIDCandidateList
    \brief a wrapper function to return the BKID candidate list
    \param pBkidList - caller allocated buffer point to an array of
                        tBkidCandidateInfo
    \param pNumItems - pointer to a variable that has the number of
                       tBkidCandidateInfo allocated when returning, this is
                       either the number needed or number of items put into
                       pPmkidList
    \return eHalStatus - when fail, it usually means the buffer allocated is not
                         big enough and pNumItems
    has the number of tBkidCandidateInfo.
    \Note: pNumItems is a number of tBkidCandidateInfo,
           not sizeof(tBkidCandidateInfo) * something
  ---------------------------------------------------------------------------*/
eHalStatus sme_ScanGetBKIDCandidateList(tHalHandle hHal, tANI_U32 sessionId,
                                        tBkidCandidateInfo *pBkidList,
                                        tANI_U32 *pNumItems )
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrScanGetBKIDCandidateList( pMac, sessionId, pBkidList, pNumItems );
        sme_ReleaseGlobalLock( &pMac->sme );
    }

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

#ifdef FEATURE_OEM_DATA_SUPPORT

/*****************************************************************************
 OEM DATA related modifications and function additions
 *****************************************************************************/

/* ---------------------------------------------------------------------------
    \fn sme_OemDataReq
    \brief a wrapper function for OEM DATA REQ
    \param sessionId - session id to be used.
    \param pOemDataReqId - pointer to an object to get back the request ID
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_OemDataReq(tHalHandle hHal,
        tANI_U8 sessionId,
        tOemDataReqConfig *pOemDataReqConfig,
        tANI_U32 *pOemDataReqID)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    do
    {
        //acquire the lock for the sme object
        status = sme_AcquireGlobalLock(&pMac->sme);
        if(HAL_STATUS_SUCCESS(status))
        {
            tANI_U32 lOemDataReqId = pMac->oemData.oemDataReqID++; //let it wrap around

            if(pOemDataReqID)
            {
               *pOemDataReqID = lOemDataReqId;
            }
            else
            {
                sme_ReleaseGlobalLock( &pMac->sme );
                return eHAL_STATUS_FAILURE;
            }

            status = oemData_OemDataReq(hHal, sessionId, pOemDataReqConfig, pOemDataReqID);

            //release the lock for the sme object
            sme_ReleaseGlobalLock( &pMac->sme );
        }
    } while(0);

    smsLog(pMac, LOGW, "exiting function %s", __func__);

    return(status);
}

#endif /*FEATURE_OEM_DATA_SUPPORT*/

/**
 * sme_create_mon_session() - post message to create PE session for monitormode
 * operation
 * @hal_handle: Handle to the HAL
 * @bssid: pointer to bssid
 *
 * Return: eHAL_STATUS_SUCCESS on success, non-zero error code on failure.
 */
eHalStatus sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	struct sir_create_session *msg;
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal_handle);
	uint16_t msg_len;

	msg_len = (tANI_U16)(sizeof(struct sir_create_session));
	msg = vos_mem_malloc(msg_len);
	if ( NULL != msg )
	{
		vos_mem_set(msg, msg_len, 0);
		msg->type =
			pal_cpu_to_be16((tANI_U16)eWNI_SME_MON_INIT_SESSION);
		msg->msg_len = pal_cpu_to_be16(msg_len);
		vos_mem_copy(msg->bss_id, bss_id, sizeof(tSirMacAddr));
		status = palSendMBMessage(mac_ptr->hHdd, msg);
	}
	return status;
}

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

  \brief sme_OpenSession() - Open a session for scan/roam operation.

  This is a synchronous API.


  \param hHal - The handle returned by macOpen.
  \param callback - A pointer to the function caller specifies for roam/connect status indication
  \param pContext - The context passed with callback
  \param pSelfMacAddr - Caller allocated memory filled with self MAC address (6 bytes)
  \param pbSessionId - pointer to a caller allocated buffer for returned session ID

  \return eHAL_STATUS_SUCCESS - session is opened. sessionId returned.

          Other status means SME is failed to open the session.
          eHAL_STATUS_RESOURCES - no more session available.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_OpenSession(tHalHandle hHal, csrRoamCompleteCallback callback,
                           void *pContext,
                           tANI_U8 *pSelfMacAddr, tANI_U8 *pbSessionId,
                           tANI_U32 type, tANI_U32 subType)
{
   eHalStatus status;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: type=%d, subType=%d", __func__, type, subType);

   if( NULL == pbSessionId )
   {
      status = eHAL_STATUS_INVALID_PARAMETER;
   }
   else
   {
      status = sme_AcquireGlobalLock( &pMac->sme );
      if ( HAL_STATUS_SUCCESS( status ) )
      {
         status = csrRoamOpenSession( pMac, callback, pContext, pSelfMacAddr,
                                      pbSessionId, type, subType );

         sme_ReleaseGlobalLock( &pMac->sme );
      }
   }
   if( NULL != pbSessionId )
   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                 TRACE_CODE_SME_RX_HDD_OPEN_SESSION,*pbSessionId, 0));

   return ( status );
}


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

  \brief sme_CloseSession() - Open a session for scan/roam operation.

  This is a synchronous API.


  \param hHal - The handle returned by macOpen.

  \param sessionId - A previous opened session's ID.

  \return eHAL_STATUS_SUCCESS - session is closed.

          Other status means SME is failed to open the session.
          eHAL_STATUS_INVALID_PARAMETER - session is not opened.
  \sa

  --------------------------------------------------------------------------*/
eHalStatus sme_CloseSession(tHalHandle hHal, tANI_U8 sessionId,
                          csrRoamSessionCloseCallback callback, void *pContext)
{
   eHalStatus status;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (!pMac)
       return eHAL_STATUS_FAILURE;

   MTRACE(vos_trace(VOS_MODULE_ID_SME,
                 TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, sessionId, 0));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrRoamCloseSession( pMac, sessionId, FALSE,
                                    callback, pContext );

      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return ( status );
}

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

    \fn sme_RoamUpdateAPWPSIE

    \brief To update AP's WPS IE. This function should be called after SME AP session is created
    This is an asynchronous API.

    \param pAPWPSIES - pointer to a caller allocated object of tSirAPWPSIEs

    \return eHalStatus  SUCCESS 

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamUpdateAPWPSIE(tHalHandle hHal, tANI_U8 sessionId, tSirAPWPSIEs *pAPWPSIES)
{

   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

      status = csrRoamUpdateAPWPSIE( pMac, sessionId, pAPWPSIES );

      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}
/* ---------------------------------------------------------------------------

    \fn sme_RoamUpdateAPWPARSNIEs

    \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created
    This is an asynchronous API.

    \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs

    \return eHalStatus  SUCCESS 

                         FAILURE or RESOURCES  The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_RoamUpdateAPWPARSNIEs(tHalHandle hHal, tANI_U8 sessionId, tSirRSNie * pAPSirRSNie)
{

   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

      status = csrRoamUpdateWPARSNIEs( pMac, sessionId, pAPSirRSNie);

      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}
/* ---------------------------------------------------------------------------

    \fn sme_ChangeMCCBeaconInterval

    \brief To update P2P-GO beaconInterval. This function should be called after
    disassociating all the station is done
    This is an asynchronous API.

    \param

    \return eHalStatus  SUCCESS
                        FAILURE or RESOURCES
                        The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   smsLog(pMac, LOG1, FL("Update Beacon PARAMS "));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrSendChngMCCBeaconInterval( pMac, sessionId);
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}


/* ---------------------------------------------------------------------------
    \fn     smeIssueFastRoamNeighborAPEvent
    \brief  API to trigger fast BSS roam independent of RSSI triggers
    \param  hHal - The handle returned by macOpen.
    \param  bssid -  Pointer to the BSSID to roam to.
    \param  fastRoamTrig - Trigger to Scan or roam
    \param  sessionId - Session Identifier
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus smeIssueFastRoamNeighborAPEvent(tHalHandle hHal,
                                           tANI_U8 *bssid,
                                           tSmeFastRoamTrigger fastRoamTrig,
                                           tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tpCsrNeighborRoamControlInfo  pNeighborRoamInfo =
                                &pMac->roam.neighborRoamInfo[sessionId];
    VOS_STATUS  vosStatus = VOS_STATUS_SUCCESS;
    eHalStatus  status    = eHAL_STATUS_SUCCESS;
    tFTRoamCallbackUsrCtx  *pUsrCtx;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                  "%s: invoked", __func__);

        if (eSME_ROAM_TRIGGER_SCAN == fastRoamTrig)
        {
            smsLog(pMac, LOG1, FL("CFG Channel list scan... "));
            pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_SCAN;
            vos_mem_copy((void *)(&pNeighborRoamInfo->cfgRoambssId),
                       (void *)bssid, sizeof(tSirMacAddr));
            smsLog(pMac, LOG1, "Calling Roam Look Up down Event BSSID "
                   MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pNeighborRoamInfo->cfgRoambssId));

            vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac, sessionId);
            if (VOS_STATUS_SUCCESS != vosStatus)
            {
                smsLog(pMac, LOGE,
                       FL("CFG Channel list scan state failed with status %d "),
                       vosStatus);
            }
        }
        else if (eSME_ROAM_TRIGGER_FAST_ROAM == fastRoamTrig)
        {
             vos_mem_copy((void *)(&pNeighborRoamInfo->cfgRoambssId),
                       (void *)bssid, sizeof(tSirMacAddr));
             pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_FAST_ROAM;
             smsLog(pMac, LOG1, "Roam to BSSID "MAC_ADDRESS_STR,
                    MAC_ADDR_ARRAY(pNeighborRoamInfo->cfgRoambssId));

             pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx));
             if (NULL == pUsrCtx) {
                 smsLog(pMac, LOGE, FL("Memory allocation failed"));
                 sme_ReleaseGlobalLock( &pMac->sme );
                 return eHAL_STATUS_FAILED_ALLOC;
             }

             /* Populate user context */
             pUsrCtx->pMac = pMac;
             pUsrCtx->sessionId = sessionId;

             vosStatus = csrNeighborRoamReassocIndCallback(
                                                         pMac->roam.gVosContext,
                                                         0, pUsrCtx, 0);

             if (!VOS_IS_STATUS_SUCCESS(vosStatus))
             {
                 smsLog(pMac,
                        LOGE,
                        FL(" Call to csrNeighborRoamReassocIndCallback failed, status = %d"),
                        vosStatus);
             }
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return vosStatus;
}
/* ---------------------------------------------------------------------------
    \fn sme_SetHostOffload
    \brief  API to set the host offload feature.
    \param  hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \param  pRequest -  Pointer to the offload request.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetHostOffload (tHalHandle hHal, tANI_U8 sessionId,
                                    tpSirHostOffloadReq pRequest)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status = eHAL_STATUS_FAILURE;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
#ifdef WLAN_NS_OFFLOAD
        if(SIR_IPV6_NS_OFFLOAD == pRequest->offloadType)
        {
            status = pmcSetNSOffload( hHal, pRequest, sessionId);
        }
        else
#endif //WLAN_NS_OFFLOAD
        {
            status = pmcSetHostOffload (hHal, pRequest, sessionId);
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

#ifdef WLAN_FEATURE_GTK_OFFLOAD
/* ---------------------------------------------------------------------------
    \fn sme_SetGTKOffload
    \brief  API to set GTK offload information.
    \param  hHal - The handle returned by macOpen.
    \param  pRequest -  Pointer to the GTK offload request.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pRequest,
                                    tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                    TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD, sessionId, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        status = pmcSetGTKOffload( hHal, pRequest, sessionId );
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_GetGTKOffload
    \brief  API to get GTK offload information.
    \param  hHal - The handle returned by macOpen.
    \param  pRequest -  Pointer to the GTK offload response.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_GetGTKOffload (tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine,
                                    void *callbackContext, tANI_U8 sessionId )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD, sessionId, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        pmcGetGTKOffload(hHal, callbackRoutine, callbackContext, sessionId);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}
#endif // WLAN_FEATURE_GTK_OFFLOAD

/* ---------------------------------------------------------------------------
    \fn sme_SetKeepAlive
    \brief  API to set the Keep Alive feature.
    \param  hHal - The handle returned by macOpen.
    \param  pRequest -  Pointer to the Keep Alive request.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetKeepAlive (tHalHandle hHal, tANI_U8 sessionId,
                                 tpSirKeepAliveReq pRequest)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status;
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        status = pmcSetKeepAlive (hHal, pRequest, sessionId);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

#ifdef FEATURE_WLAN_SCAN_PNO
/* ---------------------------------------------------------------------------
    \fn sme_SetPreferredNetworkList
    \brief  API to set the Preferred Network List Offload feature.
    \param  hHal - The handle returned by macOpen.
    \param  pRequest -  Pointer to the offload request.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetPreferredNetworkList (tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, void (*callbackRoutine) (void *callbackContext, tSirPrefNetworkFoundInd *pPrefNetworkFoundInd), void *callbackContext )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status;

    MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_PREF_NET_LIST,
                         sessionId, pRequest->ucNetworksCount));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        pmcSetPreferredNetworkList(hHal, pRequest, sessionId, callbackRoutine, callbackContext);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}
#endif // FEATURE_WLAN_SCAN_PNO

eHalStatus sme_SetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                       TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS, NO_SESSION, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        pmcSetPowerParams(hHal, pwParams, forced);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_AbortMacScan
    \brief  API to cancel MAC scan.
    \param  hHal - The handle returned by macOpen.
    \param  sessionId - sessionId on which we need to abort scan.
    \param  reason - Reason to abort the scan.
    \return VOS_STATUS
            VOS_STATUS_E_FAILURE - failure
            VOS_STATUS_SUCCESS  success
  ---------------------------------------------------------------------------*/
eHalStatus sme_AbortMacScan(tHalHandle hHal, tANI_U8 sessionId,
                            eCsrAbortReason reason)
{
    eHalStatus status;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (!pMac)
        return eHAL_STATUS_FAILURE;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
       status = csrScanAbortMacScan(pMac, sessionId, reason);

       sme_ReleaseGlobalLock( &pMac->sme );
    }

    return ( status );
}

/* ----------------------------------------------------------------------------
        \fn sme_GetOperationChannel
        \brief API to get current channel on which STA is parked
        this function gives channel information only of infra station or IBSS station
        \param hHal, pointer to memory location and sessionId
        \returns eHAL_STATUS_SUCCESS
                eHAL_STATUS_FAILURE
-------------------------------------------------------------------------------*/
eHalStatus sme_GetOperationChannel(tHalHandle hHal, tANI_U32 *pChannel, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tCsrRoamSession *pSession;

    if (CSR_IS_SESSION_VALID( pMac, sessionId ))
    {
       pSession = CSR_GET_SESSION( pMac, sessionId );

       if(( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE ) ||
          ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_IBSS ) ||
          ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_INFRA_AP ) ||
          ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_START_IBSS ))
       {
           *pChannel =pSession->connectedProfile.operationChannel;
           return eHAL_STATUS_SUCCESS;
       }
    }
    return eHAL_STATUS_FAILURE;
}// sme_GetOperationChannel ends here


/**
 * sme_register_p2p_ack_ind_callback() - p2p ack indication callback
 * @hal: hal pointer
 * @callback: callback pointer to be registered
 *
 * This function is used to register a callback to PE for p2p ack
 * indication
 *
 * Return: Success if msg is posted to PE else Failure.
 */
eHalStatus sme_register_p2p_ack_ind_callback(tHalHandle hal,
				sir_p2p_ack_ind_callback callback)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_sme_p2p_ack_ind_cb_req *msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;

	smsLog(mac_ctx, LOG1, FL(": ENTER"));

	if (eHAL_STATUS_SUCCESS ==
			sme_AcquireGlobalLock(&mac_ctx->sme)) {
		msg = vos_mem_malloc(sizeof(*msg));
		if (NULL == msg) {
			smsLog(mac_ctx, LOGE,
				FL("Failed to allocate memory"));
			sme_ReleaseGlobalLock(&mac_ctx->sme);
			return eHAL_STATUS_FAILURE;
		}
		vos_mem_set(msg, sizeof(*msg), 0);
		msg->message_type = eWNI_SME_REGISTER_P2P_ACK_CB;
		msg->length = sizeof(*msg);

		msg->callback = callback;
		status = palSendMBMessage(mac_ctx->hHdd, msg);
		sme_ReleaseGlobalLock(&mac_ctx->sme);
		return status;
	}
	return eHAL_STATUS_FAILURE;
}

/**
 * sme_register_mgmt_frame_ind_callback() - Register a callback for
 * management frame indication to PE.
 *
 * @hal: hal pointer
 * @callback: callback pointer to be registered
 *
 * This function is used to register a callback for management
 * frame indication to PE.
 *
 * Return: Success if msg is posted to PE else Failure.
 */
eHalStatus sme_register_mgmt_frame_ind_callback(tHalHandle hal,
				sir_mgmt_frame_ind_callback callback)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_sme_mgmt_frame_cb_req *msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;

	smsLog(mac_ctx, LOG1, FL(": ENTER"));

	if (eHAL_STATUS_SUCCESS ==
			sme_AcquireGlobalLock(&mac_ctx->sme)) {
		msg = vos_mem_malloc(sizeof(*msg));
		if (NULL == msg) {
			smsLog(mac_ctx, LOGE,
				FL("Not able to allocate memory for eWNI_SME_REGISTER_MGMT_FRAME_CB"));
			sme_ReleaseGlobalLock(&mac_ctx->sme);
			return eHAL_STATUS_FAILURE;
		}
		vos_mem_set(msg, sizeof(*msg), 0);
		msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB;
		msg->length          = sizeof(*msg);

		msg->callback = callback;
		status = palSendMBMessage(mac_ctx->hHdd, msg);
		sme_ReleaseGlobalLock(&mac_ctx->sme);
		return status;
	}
	return eHAL_STATUS_FAILURE;
}

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

    \fn sme_RegisterMgtFrame

    \brief To register management frame of specified type and subtype.
    \param frameType - type of the frame that needs to be passed to HDD.
    \param matchData - data which needs to be matched before passing frame
                       to HDD.
    \param matchDataLen - Length of matched data.
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_RegisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId,
                     tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                          TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, sessionId, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        tSirRegisterMgmtFrame *pMsg;
        tANI_U16 len;
        tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

        if(!CSR_IS_SESSION_ANY(sessionId) && !pSession)
        {
            smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        if( !CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive )
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s Invalid Sessionid", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        len = sizeof(tSirRegisterMgmtFrame) + matchLen;

        pMsg = vos_mem_malloc(len);
        if ( NULL == pMsg )
           status = eHAL_STATUS_FAILURE;
        else
        {
            vos_mem_set(pMsg, len, 0);
            pMsg->messageType     = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
            pMsg->length          = len;
            pMsg->sessionId       = sessionId;
            pMsg->registerFrame   = VOS_TRUE;
            pMsg->frameType       = frameType;
            pMsg->matchLen        = matchLen;
            vos_mem_copy(pMsg->matchData, matchData, matchLen);
            status = palSendMBMessage(pMac->hHdd, pMsg);
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status;
}

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

    \fn sme_DeregisterMgtFrame

    \brief To De-register management frame of specified type and subtype.
    \param frameType - type of the frame that needs to be passed to HDD.
    \param matchData - data which needs to be matched before passing frame
                       to HDD.
    \param matchDataLen - Length of matched data.
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus sme_DeregisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId,
                     tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    if (!pMac)
        return eHAL_STATUS_FAILURE;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        tSirRegisterMgmtFrame *pMsg;
        tANI_U16 len;
        tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

        if(!CSR_IS_SESSION_ANY(sessionId) && !pSession)
        {
            smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        if( !CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive )
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s Invalid Sessionid", __func__);
            sme_ReleaseGlobalLock( &pMac->sme );
            return eHAL_STATUS_FAILURE;
        }

        len = sizeof(tSirRegisterMgmtFrame) + matchLen;

        pMsg = vos_mem_malloc(len);
        if ( NULL == pMsg )
           status = eHAL_STATUS_FAILURE;
        else
        {
            vos_mem_set(pMsg, len, 0);
            pMsg->messageType     = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
            pMsg->length          = len;
            pMsg->registerFrame   = VOS_FALSE;
            pMsg->frameType       = frameType;
            pMsg->matchLen        = matchLen;
            vos_mem_copy(pMsg->matchData, matchData, matchLen);
            status = palSendMBMessage(pMac->hHdd, pMsg);
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_RemainOnChannel
    \brief  API to request remain on channel for 'x' duration. used in p2p in listen state
    \param  hHal - The handle returned by macOpen.
    \param  pRequest -  channel
    \param  duration - duration in ms
    \param callback - HDD registered callback to process reaminOnChannelRsp
    \param context - HDD Callback param
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_RemainOnChannel(tHalHandle hHal, tANI_U8 sessionId,
                               tANI_U8 channel, tANI_U32 duration,
                               remainOnChanCallback callback,
                               void *pContext,
                               tANI_U8 isP2PProbeReqAllowed)
{
  eHalStatus status = eHAL_STATUS_SUCCESS;
  tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

  MTRACE(vos_trace(VOS_MODULE_ID_SME,
            TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, sessionId, 0));
  if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
  {
    status = p2pRemainOnChannel (hHal, sessionId, channel, duration, callback, pContext,
                                 isP2PProbeReqAllowed
                                );
    sme_ReleaseGlobalLock( &pMac->sme );
  }
  return(status);
}

/* ---------------------------------------------------------------------------
    \fn sme_ReportProbeReq
    \brief  API to enable/disable forwarding of probeReq to apps in p2p.
    \param  hHal - The handle returned by macOpen.
    \param  flag: to set the Probe request forwarding to wpa_supplicant in
                  listen state in p2p
    \return eHalStatus
  ---------------------------------------------------------------------------*/

#ifndef WLAN_FEATURE_CONCURRENT_P2P
eHalStatus sme_ReportProbeReq(tHalHandle hHal, tANI_U8 flag)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    do
    {
        //acquire the lock for the sme object
        status = sme_AcquireGlobalLock(&pMac->sme);
        if(HAL_STATUS_SUCCESS(status))
        {
            /* call set in context */
            pMac->p2pContext.probeReqForwarding = flag;
            //release the lock for the sme object
            sme_ReleaseGlobalLock( &pMac->sme );
        }
    } while(0);

    smsLog(pMac, LOGW, "exiting function %s", __func__);

    return(status);
}

/* ---------------------------------------------------------------------------
    \fn sme_updateP2pIe
    \brief  API to set the P2p Ie in p2p context
    \param  hHal - The handle returned by macOpen.
    \param  p2pIe -  Ptr to p2pIe from HDD.
    \param p2pIeLength: length of p2pIe
    \return eHalStatus
  ---------------------------------------------------------------------------*/

eHalStatus sme_updateP2pIe(tHalHandle hHal, void *p2pIe, tANI_U32 p2pIeLength)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE, NO_SESSION, 0));
    //acquire the lock for the sme object
    status = sme_AcquireGlobalLock(&pMac->sme);
    if(HAL_STATUS_SUCCESS(status))
    {
        if(NULL != pMac->p2pContext.probeRspIe){
            vos_mem_free(pMac->p2pContext.probeRspIe);
            pMac->p2pContext.probeRspIeLength = 0;
        }

        pMac->p2pContext.probeRspIe = vos_mem_malloc(p2pIeLength);
        if (NULL == pMac->p2pContext.probeRspIe)
        {
            smsLog(pMac, LOGE, "%s: Unable to allocate P2P IE", __func__);
            pMac->p2pContext.probeRspIeLength = 0;
            status = eHAL_STATUS_FAILURE;
        }
        else
        {
            pMac->p2pContext.probeRspIeLength = p2pIeLength;

            vos_mem_copy((tANI_U8 *)pMac->p2pContext.probeRspIe, p2pIe,
                         p2pIeLength);
            sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG2,
                        pMac->p2pContext.probeRspIe,
                        pMac->p2pContext.probeRspIeLength );
        }

        //release the lock for the sme object
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    smsLog(pMac, LOG2, "exiting function %s", __func__);

    return(status);
}
#endif

/* ---------------------------------------------------------------------------
    \fn sme_sendAction
    \brief  API to send action frame from supplicant.
    \param  hHal - The handle returned by macOpen.
    \return eHalStatus
  ---------------------------------------------------------------------------*/

eHalStatus sme_sendAction(tHalHandle hHal, tANI_U8 sessionId,
                          const tANI_U8 *pBuf, tANI_U32 len,
                          tANI_U16 wait, tANI_BOOLEAN noack)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_SEND_ACTION, sessionId, 0));
    //acquire the lock for the sme object
    status = sme_AcquireGlobalLock(&pMac->sme);
    if(HAL_STATUS_SUCCESS(status))
    {
        p2pSendAction(hHal, sessionId, pBuf, len, wait, noack);
        //release the lock for the sme object
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    smsLog(pMac, LOGW, "exiting function %s", __func__);

    return(status);
}

eHalStatus sme_CancelRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId )
{
  eHalStatus status = eHAL_STATUS_SUCCESS;
  tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

  MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, sessionId, 0));
  if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
  {
    status = p2pCancelRemainOnChannel (hHal, sessionId);
    sme_ReleaseGlobalLock( &pMac->sme );
  }
  return(status);
}

//Power Save Related
eHalStatus sme_p2pSetPs(tHalHandle hHal, tP2pPsConfig * data)
{
  eHalStatus status = eHAL_STATUS_SUCCESS;
  tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

  if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
  {
    status = p2pSetPs (hHal, data);
    sme_ReleaseGlobalLock( &pMac->sme );
  }
  return(status);
}


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

  \fn    sme_ConfigureRxpFilter

  \brief
    SME will pass this request to lower mac to set/reset the filter on RXP for
    multicast & broadcast traffic.

  \param

    hHal - The handle returned by macOpen.

    filterMask- Currently the API takes a 1 or 0 (set or reset) as filter.
    Basically to enable/disable the filter (to filter "all" mcbc traffic) based
    on this param. In future we can use this as a mask to set various types of
    filters as suggested below:
    FILTER_ALL_MULTICAST:
    FILTER_ALL_BROADCAST:
    FILTER_ALL_MULTICAST_BROADCAST:


  \return eHalStatus


--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureRxpFilter( tHalHandle hHal,
                            tpSirWlanSetRxpFilters  wlanRxpFilterParam)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t       vosMessage;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                    TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, NO_SESSION, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        /* serialize the req through MC thread */
        vosMessage.bodyptr = wlanRxpFilterParam;
        vosMessage.type         = WDA_CFG_RXP_FILTER_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return(status);
}

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

  \fn    sme_ConfigureSuspendInd

  \brief
    SME will pass this request to lower mac to Indicate that the wlan needs to
    be suspended

  \param

    hHal - The handle returned by macOpen.

    wlanSuspendParam- Depicts the wlan suspend params

    csrReadyToSuspendCallback - Callback to be called when ready to suspend
                                event is received.
    callbackContext  - Context associated with csrReadyToSuspendCallback.

  \return eHalStatus


--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureSuspendInd( tHalHandle hHal,
                          tpSirWlanSuspendParam  wlanSuspendParam,
                          csrReadyToSuspendCallback callback,
                          void *callbackContext)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t       vosMessage;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                  TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, NO_SESSION, 0));

    pMac->readyToSuspendCallback = callback;
    pMac->readyToSuspendContext = callbackContext;

    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        /* serialize the req through MC thread */
        vosMessage.bodyptr = wlanSuspendParam;
        vosMessage.type    = WDA_WLAN_SUSPEND_IND;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) {
           pMac->readyToSuspendCallback = NULL;
           pMac->readyToSuspendContext = NULL;
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return(status);
}

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

  \fn    sme_ConfigureResumeReq

  \brief
    SME will pass this request to lower mac to Indicate that the wlan needs to
    be Resumed

  \param

    hHal - The handle returned by macOpen.

    wlanResumeParam- Depicts the wlan resume params


  \return eHalStatus


--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureResumeReq( tHalHandle hHal,
                             tpSirWlanResumeParam  wlanResumeParam)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t       vosMessage;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, NO_SESSION, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        /* serialize the req through MC thread */
        vosMessage.bodyptr = wlanResumeParam;
        vosMessage.type    = WDA_WLAN_RESUME_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return(status);
}

/**
 * sme_prepare_mgmt_tx() - Prepares mgmt frame
 * @hal: The handle returned by mac_open
 * @session_id: session id
 * @buf: pointer to frame
 * @len: frame length
 *
 * Return: eHalStatus
 */
static eHalStatus sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id,
					const uint8_t *buf, uint32_t len)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	vos_msg_t vos_message;
	struct sir_mgmt_msg *msg;
	uint16_t msg_len;

	VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
		  ("prepares auth frame"));

	msg_len = sizeof(*msg) + len;
	msg = vos_mem_malloc(msg_len);
	if (msg == NULL) {
		status = eHAL_STATUS_FAILED_ALLOC;
	} else {
		msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
		msg->msg_len = msg_len;
		msg->session_id = session_id;
		msg->data = (uint8_t *)msg + sizeof(*msg);
		vos_mem_copy(msg->data, buf, len);
		vos_message.bodyptr = msg;
		vos_message.type =  eWNI_SME_SEND_MGMT_FRAME_TX;
		vos_status = vos_mq_post_message(VOS_MQ_ID_PE,
						 &vos_message);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			vos_mem_free(msg);
			status = eHAL_STATUS_FAILURE;
		}
	}

	return status;
}

eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
				const uint8_t *buf, uint32_t len)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	MTRACE(vos_trace(VOS_MODULE_ID_SME,
		TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX, session_id, 0));

	status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		status = sme_prepare_mgmt_tx(hal, session_id, buf, len);
		sme_ReleaseGlobalLock(&mac->sme);
	}

	return status;
}

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
/* ---------------------------------------------------------------------------

  \fn    sme_ConfigureExtWoW

  \brief
    SME will pass this request to lower mac to configure Extr WoW

  \param

    hHal - The handle returned by macOpen.

    wlanExtParams- Depicts the wlan Ext params

  \return eHalStatus


--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureExtWoW( tHalHandle hHal,
                          tpSirExtWoWParams  wlanExtParams,
                          csrReadyToExtWoWCallback callback,
                             void *callbackContext)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;
    tpSirExtWoWParams MsgPtr = vos_mem_malloc(sizeof(*MsgPtr));

    if (!MsgPtr)
        return eHAL_STATUS_FAILURE;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                  TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0));

    pMac->readyToExtWoWCallback = callback;
    pMac->readyToExtWoWContext = callbackContext;

    if ( eHAL_STATUS_SUCCESS ==
              ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) {

        /* serialize the req through MC thread */
        vos_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr));
        vosMessage.bodyptr = MsgPtr;
        vosMessage.type =  WDA_WLAN_EXT_WOW;
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) {
            pMac->readyToExtWoWCallback = NULL;
            pMac->readyToExtWoWContext = NULL;
            vos_mem_free(MsgPtr);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    } else {
        pMac->readyToExtWoWCallback = NULL;
        pMac->readyToExtWoWContext = NULL;
        vos_mem_free(MsgPtr);
    }

    return(status);
}

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

  \fn    sme_ConfigureAppType1Params

  \brief
   SME will pass this request to lower mac to configure Indoor WoW parameters.

  \param

    hHal - The handle returned by macOpen.

    wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params

  \return eHalStatus


--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureAppType1Params( tHalHandle hHal,
                          tpSirAppType1Params  wlanAppType1Params)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t       vosMessage;
    tpSirAppType1Params MsgPtr = vos_mem_malloc(sizeof(*MsgPtr));

    if (!MsgPtr)
        return eHAL_STATUS_FAILURE;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                  TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION, 0));

    if ( eHAL_STATUS_SUCCESS ==
              ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) {

        /* serialize the req through MC thread */
        vos_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr));
        vosMessage.bodyptr = MsgPtr;
        vosMessage.type    =  WDA_WLAN_SET_APP_TYPE1_PARAMS;
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) {
           vos_mem_free(MsgPtr);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    } else {
        vos_mem_free(MsgPtr);
    }

    return(status);
}

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

  \fn    sme_ConfigureAppType2Params

  \brief
   SME will pass this request to lower mac to configure Indoor WoW parameters.

  \param

    hHal - The handle returned by macOpen.

    wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params

  \return eHalStatus


--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureAppType2Params( tHalHandle hHal,
                          tpSirAppType2Params  wlanAppType2Params)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t       vosMessage;
    tpSirAppType2Params MsgPtr = vos_mem_malloc(sizeof(*MsgPtr));

    if (!MsgPtr)
        return eHAL_STATUS_FAILURE;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                  TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION, 0));

    if ( eHAL_STATUS_SUCCESS ==
            ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) {

        /* serialize the req through MC thread */
        vos_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr));
        vosMessage.bodyptr = MsgPtr;
        vosMessage.type =  WDA_WLAN_SET_APP_TYPE2_PARAMS;
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) {
           vos_mem_free(MsgPtr);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    } else {
        vos_mem_free(MsgPtr);
    }

    return(status);
}
#endif

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

    \fn sme_GetInfraSessionId

    \brief To get the session ID for infra session, if connected
    This is a synchronous API.

    \param hHal - The handle returned by macOpen.

    \return sessionid, -1 if infra session is not connected

  -------------------------------------------------------------------------------*/
tANI_S8 sme_GetInfraSessionId(tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tANI_S8 sessionid = -1;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

      sessionid = csrGetInfraSessionId( pMac);

      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (sessionid);
}

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

    \fn sme_GetInfraOperationChannel

    \brief To get the operating channel for infra session, if connected
    This is a synchronous API.

    \param hHal - The handle returned by macOpen.
    \param sessionId - the sessionId returned by sme_OpenSession.

    \return operating channel, 0 if infra session is not connected

  -------------------------------------------------------------------------------*/
tANI_U8 sme_GetInfraOperationChannel( tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tANI_U8 channel = 0;
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

      channel = csrGetInfraOperationChannel( pMac, sessionId);

      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (channel);
}

/*
 * This routine will return operating channel on which other BSS is operating to
 * be used for concurrency mode.
 * If other BSS is not up or not connected it will return 0.
 */
tANI_U8 sme_GetConcurrentOperationChannel( tHalHandle hHal )
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tANI_U8 channel = 0;
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

      channel = csrGetConcurrentOperationChannel( pMac );
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: "
           " Other Concurrent Channel = %d", __func__,channel);
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (channel);
}
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
v_U16_t sme_CheckConcurrentChannelOverlap( tHalHandle hHal, v_U16_t sap_ch,
                                 eCsrPhyMode sapPhyMode, v_U8_t cc_switch_mode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   v_U16_t channel = 0;

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      channel = csrCheckConcurrentChannelOverlap( pMac, sap_ch, sapPhyMode,
                                                  cc_switch_mode);
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (channel);
}
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/**
 * sme_find_sta_session_info() - get sta active session info
 * @hHal: tHalHandle ptr
 * @session_info: information returned.
 *
 * Return: TRUE if sta session info returned
 */
tANI_BOOLEAN sme_find_sta_session_info(
	tHalHandle hHal,
	session_info_t *session_info)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE;

	status = sme_AcquireGlobalLock( &pMac->sme );
	if ( HAL_STATUS_SUCCESS( status ) ) {
		ret = csr_find_sta_session_info(hHal,
				session_info);
		sme_ReleaseGlobalLock( &pMac->sme );
	}
	return ret;
}
/**
 * sme_find_all_session_info() - get all active session info
 * @hHal: tHalHandle ptr
 * @session_info: information returned.
 * @session_count: number of session
 *
 * Return: TRUE if any session info returned
 */
tANI_BOOLEAN sme_find_all_session_info(
	tHalHandle hHal,
	session_info_t *session_info,
	v_U8_t * session_count)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE;

	status = sme_AcquireGlobalLock( &pMac->sme );
	if ( HAL_STATUS_SUCCESS( status ) ) {
		ret = csr_find_all_session_info(hHal,
				session_info, session_count);
		sme_ReleaseGlobalLock( &pMac->sme );
	}
	return ret;
}
/**
 * sme_create_sap_session_info() - create session info based on
 *  the input chan and phymode
 * @hHal: tHalHandle ptr
 * @sap_phymode: requesting phymode.
 * @sap_ch: requesting channel number
 * @session_info: information returned.
 *
 * Return: TRUE if any session info returned
 */
tANI_BOOLEAN sme_create_sap_session_info(
	tHalHandle hHal,
	eCsrPhyMode sap_phymode,
	v_U16_t sap_ch,
	session_info_t *session_info)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE;

	status = sme_AcquireGlobalLock( &pMac->sme );
	if ( HAL_STATUS_SUCCESS( status ) ) {
		ret = csr_create_sap_session_info(hHal,
			sap_phymode,
			sap_ch,
			session_info);
		sme_ReleaseGlobalLock( &pMac->sme );
	}
	return ret;
}
#endif
#endif

#ifdef FEATURE_WLAN_SCAN_PNO
/******************************************************************************
*
* Name: sme_PreferredNetworkFoundInd
*
* Description:
*    Invoke Preferred Network Found Indication
*
* Parameters:
*    hHal - HAL handle for device
*    pMsg - found network description
*
* Returns: eHalStatus
*
******************************************************************************/
eHalStatus sme_PreferredNetworkFoundInd (tHalHandle hHal, void* pMsg)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tSirPrefNetworkFoundInd *pPrefNetworkFoundInd = (tSirPrefNetworkFoundInd *)pMsg;
   v_U8_t dumpSsId[SIR_MAC_MAX_SSID_LENGTH + 1];
   tANI_U8 ssIdLength = 0;

   if (NULL == pMsg)
   {
      smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
      return eHAL_STATUS_FAILURE;
   }

   if (pMac->pnoOffload)
   {
      /* Call Preferred Network Found Indication callback routine. */
      if (pMac->pmc.prefNetwFoundCB != NULL)
      {
         pMac->pmc.prefNetwFoundCB(
             pMac->pmc.preferredNetworkFoundIndCallbackContext,
             pPrefNetworkFoundInd);
      }
      return status;
   }

   if (pPrefNetworkFoundInd->ssId.length > 0)
   {
       ssIdLength = CSR_MIN(SIR_MAC_MAX_SSID_LENGTH,
                          pPrefNetworkFoundInd->ssId.length);
       vos_mem_copy(dumpSsId, pPrefNetworkFoundInd->ssId.ssId, ssIdLength);
       dumpSsId[ssIdLength] = 0;
       smsLog(pMac, LOG2, "%s:SSID=%s frame length %d",
           __func__, dumpSsId, pPrefNetworkFoundInd->frameLength);

         /* Flush scan results, So as to avoid indication/updation of
          * stale entries, which may not have aged out during APPS collapse
          */
         sme_ScanFlushResult(hHal,0);

       //Save the frame to scan result
       if (pPrefNetworkFoundInd->mesgLen > sizeof(tSirPrefNetworkFoundInd))
       {
          //we may have a frame
          status = csrScanSavePreferredNetworkFound(pMac,
                                    pPrefNetworkFoundInd);
          if (!HAL_STATUS_SUCCESS(status))
          {
             smsLog(pMac, LOGE, FL(" fail to save preferred network"));
          }
       }
       else
       {
          smsLog(pMac, LOGE, FL(" not enough data length %d needed %zu"),
             pPrefNetworkFoundInd->mesgLen, sizeof(tSirPrefNetworkFoundInd));
       }

       /* Call Preferred Network Found Indication callback routine. */
       if (HAL_STATUS_SUCCESS(status) && (pMac->pmc.prefNetwFoundCB != NULL))
       {
          pMac->pmc.prefNetwFoundCB(
              pMac->pmc.preferredNetworkFoundIndCallbackContext,
              pPrefNetworkFoundInd);
       }
   }
   else
   {
       smsLog(pMac, LOGE, "%s: callback failed - SSID is NULL", __func__);
       status = eHAL_STATUS_FAILURE;
   }

   return(status);
}

#endif // FEATURE_WLAN_SCAN_PNO


eHalStatus sme_GetCfgValidChannels(tHalHandle hHal, tANI_U8 *aValidChannels, tANI_U32 *len)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrGetCfgValidChannels(pMac, aValidChannels, len);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return (status);
}


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

    \fn sme_SetTxPerTracking

    \brief Set Tx PER tracking configuration parameters

    \param hHal - The handle returned by macOpen.
    \param pTxPerTrackingConf - Tx PER configuration parameters

    \return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_SetTxPerTracking(tHalHandle hHal,
                                void (*pCallbackfn) (void *pCallbackContext),
                                void *pCallbackContext,
                                tpSirTxPerTrackingParam pTxPerTrackingParam)
{
    vos_msg_t msg;
    tpSirTxPerTrackingParam pTxPerTrackingParamReq = NULL;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
    {
        pMac->sme.pTxPerHitCallback = pCallbackfn;
        pMac->sme.pTxPerHitCbContext = pCallbackContext;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    // free this memory in failure case or WDA request callback function
    pTxPerTrackingParamReq = vos_mem_malloc(sizeof(tSirTxPerTrackingParam));
    if (NULL == pTxPerTrackingParamReq)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for tSirTxPerTrackingParam", __func__);
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_copy(pTxPerTrackingParamReq, (void*)pTxPerTrackingParam,
                 sizeof(tSirTxPerTrackingParam));
    msg.type = WDA_SET_TX_PER_TRACKING_REQ;
    msg.reserved = 0;
    msg.bodyptr = pTxPerTrackingParamReq;
    MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                    NO_SESSION, msg.type));
    if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_TX_PER_TRACKING_REQ message to WDA", __func__);
        vos_mem_free(pTxPerTrackingParamReq);
        return eHAL_STATUS_FAILURE;
    }

    return eHAL_STATUS_SUCCESS;
}

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

    \fn sme_HandleChangeCountryCode

    \brief Change Country code, Reg Domain and channel list

    \details Country Code Priority
    0 = 11D > Configured Country > NV
    1 = Configured Country > 11D > NV
    If Supplicant country code is priority than 11d is disabled.
    If 11D is enabled, we update the country code after every scan.
    Hence when Supplicant country code is priority, we don't need 11D info.
    Country code from Supplicant is set as current country code.
    User can send reset command XX (instead of country code) to reset the
    country code to default values which is read from NV.
    In case of reset, 11D is enabled and default NV code is Set as current country code
    If 11D is priority,
    Than Supplicant country code code is set to default code. But 11D code is set as current country code

    \param pMac - The handle returned by macOpen.
    \param pMsgBuf - MSG Buffer

    \return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac,  void *pMsgBuf)
{
   eHalStatus  status = eHAL_STATUS_SUCCESS;
   tAniChangeCountryCodeReq *pMsg;
   v_REGDOMAIN_t domainIdIoctl;
   VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
   static uNvTables nvTables;
   pMsg = (tAniChangeCountryCodeReq *)pMsgBuf;


   /* if the reset Supplicant country code command is triggered, enable 11D, reset the NV country code and return */
   if( VOS_TRUE == vos_mem_compare(pMsg->countryCode, SME_INVALID_COUNTRY_CODE, 2) )
   {
       pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal;

       vosStatus = vos_nv_readDefaultCountryTable( &nvTables );

       /* read the country code from NV and use it */
       if ( VOS_IS_STATUS_SUCCESS(vosStatus) )
       {
           vos_mem_copy(pMsg->countryCode,
                        nvTables.defaultCountryTable.countryCode,
                        WNI_CFG_COUNTRY_CODE_LEN);
       }
       else
       {
           status = eHAL_STATUS_FAILURE;
           return status;
       }
       /*
        * Update the 11d country to default country from NV bin so that when
        * callback is received for this default country, driver will not
        * disable the 11d taking it as valid country by user.
        */
        smsLog(pMac, LOG1,
         FL
         ("Set default country code (%c%c) from NV as invalid country received"),
         pMsg->countryCode[0],pMsg->countryCode[1]);
        vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode,
                      WNI_CFG_COUNTRY_CODE_LEN);

   }
   else
   {
       /* if Supplicant country code has priority, disable 11d */
       if(pMac->roam.configParam.fSupplicantCountryCodeHasPriority &&
         pMsg->countryFromUserSpace)
       {
           pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE;
       }
   }

   /* WEXT set country code means
    * 11D should be supported?
    * 11D Channel should be enforced?
    * 11D Country code should be matched?
    * 11D Reg Domain should be matched?
    * Country string changed */
   if(pMac->roam.configParam.Is11dSupportEnabled &&
      pMac->roam.configParam.fEnforce11dChannels &&
      pMac->roam.configParam.fEnforceCountryCodeMatch &&
      pMac->roam.configParam.fEnforceDefaultDomain &&
      !csrSave11dCountryString(pMac, pMsg->countryCode, eANI_BOOLEAN_TRUE))
   {
      /* All 11D related options are already enabled
       * Country string is not changed
       * Do not need do anything for country code change request */
      return eHAL_STATUS_SUCCESS;
   }

   /* Set Current Country code and Current Regulatory domain */
   status = csrSetCountryCode(pMac, pMsg->countryCode, NULL);
   if(eHAL_STATUS_SUCCESS != status)
   {
       /* Supplicant country code failed. So give 11D priority */
       pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal;
       smsLog(pMac, LOGE, "Set Country Code Fail %d", status);
       return status;
   }

   /* Overwrite the default country code */
   vos_mem_copy(pMac->scan.countryCodeDefault,
                pMac->scan.countryCodeCurrent,
                WNI_CFG_COUNTRY_CODE_LEN);

   /* Get Domain ID from country code */
   status = csrGetRegulatoryDomainForCountry(pMac,
                   pMac->scan.countryCodeCurrent,
                   (v_REGDOMAIN_t *) &domainIdIoctl,
                   COUNTRY_QUERY);
   if ( status != eHAL_STATUS_SUCCESS )
   {
       smsLog( pMac, LOGE, FL("  fail to get regId %d"), domainIdIoctl );
       return status;
   }
   else if (REGDOMAIN_WORLD == domainIdIoctl)
   {
       /* Supplicant country code is invalid, so we are on world mode now. So
          give 11D chance to update */
       pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal;
       smsLog(pMac, LOG1, FL("Country Code unrecognized by driver"));
   }


   status = WDA_SetRegDomain(pMac, domainIdIoctl, pMsg->sendRegHint);

   if ( status != eHAL_STATUS_SUCCESS )
   {
       smsLog( pMac, LOGE, FL("  fail to set regId %d"), domainIdIoctl );
       return status;
   }
   else
   {
       //if 11d has priority, clear currentCountryBssid & countryCode11d to get
       //set again if we find AP with 11d info during scan
       if (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)
       {
           smsLog( pMac, LOGW, FL("Clearing currentCountryBssid, countryCode11d"));
           vos_mem_zero(&pMac->scan.currentCountryBssid, sizeof(tCsrBssid));
           vos_mem_zero( pMac->scan.countryCode11d, sizeof( pMac->scan.countryCode11d ) );
       }
   }

   if( pMsg->changeCCCallback )
   {
      ((tSmeChangeCountryCallback)(pMsg->changeCCCallback))((void *)pMsg->pDevContext);
   }

   return eHAL_STATUS_SUCCESS;
}

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

    \fn sme_HandleChangeCountryCodeByUser

    \brief Change Country code, Reg Domain and channel list

    If Supplicant country code is priority than 11d is disabled.
    If 11D is enabled, we update the country code after every scan.
    Hence when Supplicant country code is priority, we don't need 11D info.
    Country code from Supplicant is set as current country code.

    \param pMac - The handle returned by macOpen.
    \param pMsg - Carrying new CC & domain set in kernel by user

    \return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_HandleChangeCountryCodeByUser(tpAniSirGlobal pMac,
                                             tAniGenericChangeCountryCodeReq *pMsg)
{
    eHalStatus  status = eHAL_STATUS_SUCCESS;
    v_REGDOMAIN_t reg_domain_id;
    v_BOOL_t is11dCountry = VOS_FALSE;

    smsLog(pMac, LOG1, FL(" called"));
    reg_domain_id =  (v_REGDOMAIN_t)pMsg->domain_index;

    if (memcmp(pMsg->countryCode, pMac->scan.countryCode11d,
               VOS_COUNTRY_CODE_LEN) == 0)
    {
        is11dCountry = VOS_TRUE;
    }

    /* Set the country code given by user space when 11dOriginal is FALSE
     * when 11doriginal is True,is11dCountry =0 and
     * fSupplicantCountryCodeHasPriority = 0, then revert the country code,
     * and return failure
     */
    if(pMac->roam.configParam.Is11dSupportEnabledOriginal == true)
    {
        if ((!is11dCountry) && (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority))
        {

            smsLog( pMac, LOGW, FL(" incorrect country being set, nullify this request"));

            /* we have got a request for a country that should not have been added since the
             * STA is associated; nullify this request.
             * If both countryCode11d[0] and countryCode11d[1] are zero, revert it to World
             * domain to avoid from causing cfg80211 call trace.
             */
            if ((pMac->scan.countryCode11d[0] == 0) && (pMac->scan.countryCode11d[1] == 0))
               status = csrGetRegulatoryDomainForCountry(pMac,
                                                  "00",
                                                  (v_REGDOMAIN_t *) &reg_domain_id,
                                                  COUNTRY_IE);
            else
               status = csrGetRegulatoryDomainForCountry(pMac,
                                                  pMac->scan.countryCode11d,
                                                  (v_REGDOMAIN_t *) &reg_domain_id,
                                                  COUNTRY_IE);

            return eHAL_STATUS_FAILURE;
        }
    }
    /* if Supplicant country code has priority, disable 11d */
    if (!is11dCountry && pMac->roam.configParam.fSupplicantCountryCodeHasPriority)
    {
        pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE;
    }

    vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode,
                  WNI_CFG_COUNTRY_CODE_LEN);

    status = WDA_SetRegDomain(pMac, reg_domain_id, eSIR_TRUE);

    if (VOS_FALSE == is11dCountry )
    {
        /* Overwrite the default country code */
        vos_mem_copy(pMac->scan.countryCodeDefault,
                      pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
        /* set to default domain ID */
        pMac->scan.domainIdDefault = pMac->scan.domainIdCurrent;
    }

    if ( status != eHAL_STATUS_SUCCESS )
    {
        smsLog( pMac, LOGE, FL("  fail to set regId %d"), reg_domain_id );
        return status;
    }
    else
    {
        //if 11d has priority, clear currentCountryBssid & countryCode11d to get
        //set again if we find AP with 11d info during scan
        if((!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) &&
           (VOS_FALSE == is11dCountry ))
        {
            smsLog( pMac, LOGW, FL("Clearing currentCountryBssid, countryCode11d"));
            vos_mem_zero(&pMac->scan.currentCountryBssid, sizeof(tCsrBssid));
            vos_mem_zero( pMac->scan.countryCode11d, sizeof( pMac->scan.countryCode11d ) );
        }
    }

    /* get the channels based on new cc */
    status = csrInitGetChannels(pMac);

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

    /* reset info based on new cc, and we are done */
    csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
    if (VOS_TRUE == is11dCountry)
    {
        pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE;
        pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE;
    }
    /* Country code  Changed, Purge Only scan result
     * which does not have channel number belong to 11d
     * channel list
     */
    csrScanFilterResults(pMac);
    // Do active scans after the country is set by User hints or Country IE
    pMac->scan.curScanType = eSIR_ACTIVE_SCAN;

    sme_DisconnectConnectedSessions(pMac);

    smsLog(pMac, LOG1, FL(" returned"));
    return eHAL_STATUS_SUCCESS;
}

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

    \fn sme_HandleChangeCountryCodeByCore

    \brief Update Country code in the driver if set by kernel as world

    If 11D is enabled, we update the country code after every scan & notify kernel.
    This is to make sure kernel & driver are in sync in case of CC found in
    driver but not in kernel database

    \param pMac - The handle returned by macOpen.
    \param pMsg - Carrying new CC set in kernel

    \return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_HandleChangeCountryCodeByCore(tpAniSirGlobal pMac, tAniGenericChangeCountryCodeReq *pMsg)
{
    eHalStatus  status;

    smsLog(pMac, LOG1, FL(" called"));

    //this is to make sure kernel & driver are in sync in case of CC found in
    //driver but not in kernel database
    if (('0' == pMsg->countryCode[0]) && ('0' == pMsg->countryCode[1]))
    {
        smsLog( pMac, LOGW, FL("Setting countryCode11d & countryCodeCurrent to world CC"));
        vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode,
                      WNI_CFG_COUNTRY_CODE_LEN);
        vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode,
                      WNI_CFG_COUNTRY_CODE_LEN);
    }

    status = WDA_SetRegDomain(pMac, REGDOMAIN_WORLD, eSIR_TRUE);

    if ( status != eHAL_STATUS_SUCCESS )
    {
        smsLog( pMac, LOGE, FL("  fail to set regId") );
        return status;
    }
    else
    {
        status = csrInitGetChannels(pMac);
        if ( status != eHAL_STATUS_SUCCESS )
        {
            smsLog( pMac, LOGE, FL("  fail to get Channels "));
        }
        else
        {
            csrInitChannelList(pMac);
        }
    }
    /* Country code  Changed, Purge Only scan result
     * which does not have channel number belong to 11d
     * channel list
     */
    csrScanFilterResults(pMac);
    smsLog(pMac, LOG1, FL(" returned"));
    return eHAL_STATUS_SUCCESS;
}

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

    \fn sme_DisconnectConnectedSessions

    \brief Disconnect STA and P2P client session if channel is not supported

    If new country code does not support the channel on which STA/P2P client
    is connected, it sends the disconnect to the AP/P2P GO

    \param pMac - The handle returned by macOpen

    \return void

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

void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac)
{
    v_U8_t i,sessionId, isChanFound = false;
    tANI_U8 currChannel;

    for (sessionId=0; sessionId< CSR_ROAM_SESSION_MAX; sessionId++)
    {
        if (csrIsSessionClientAndConnected(pMac, sessionId))
        {
            isChanFound = false;
            //Session is connected.Check the channel
            currChannel = csrGetInfraOperationChannel(pMac, sessionId);
            smsLog(pMac, LOGW, "Current Operating channel : %d, session :%d",
            currChannel, sessionId);
            for (i=0; i < pMac->scan.base20MHzChannels.numChannels; i++)
            {
                if (pMac->scan.base20MHzChannels.channelList[i] == currChannel)
                {
                    isChanFound = true;
                    break;
                }
            }

            if (!isChanFound)
            {
                for (i=0; i < pMac->scan.base40MHzChannels.numChannels; i++)
                {
                    if(pMac->scan.base40MHzChannels.channelList[i] == currChannel)
                    {
                        isChanFound = true;
                        break;
                    }
                }
            }

            if (!isChanFound)
            {
                smsLog(pMac, LOGW, "%s : Disconnect Session :%d", __func__, sessionId);
                csrRoamDisconnect(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
            }
        }
    }
}


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

    \fn sme_HandleGenericChangeCountryCode

    \brief Change Country code, Reg Domain and channel list

    If Supplicant country code is priority than 11d is disabled.
    If 11D is enabled, we update the country code after every scan.
    Hence when Supplicant country code is priority, we don't need 11D info.
    Country code from kernel is set as current country code.

    \param pMac - The handle returned by macOpen.
    \param pMsgBuf - message buffer

    \return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac,  void *pMsgBuf)
{
    tAniGenericChangeCountryCodeReq *pMsg;
    v_REGDOMAIN_t reg_domain_id;

    smsLog(pMac, LOG1, FL(" called"));
    pMsg = (tAniGenericChangeCountryCodeReq *)pMsgBuf;
    reg_domain_id =  (v_REGDOMAIN_t)pMsg->domain_index;

    if (REGDOMAIN_COUNT == reg_domain_id)
    {
        sme_HandleChangeCountryCodeByCore(pMac, pMsg);
    }
    else
    {
        sme_HandleChangeCountryCodeByUser(pMac, pMsg);
    }
    smsLog(pMac, LOG1, FL(" returned"));
    return eHAL_STATUS_SUCCESS;
}

#ifdef WLAN_FEATURE_PACKET_FILTERING
eHalStatus sme_8023MulticastList (tHalHandle hHal, tANI_U8 sessionId, tpSirRcvFltMcAddrList pMulticastAddrs)
{
    tpSirRcvFltMcAddrList   pRequestBuf;
    vos_msg_t               msg;
    tpAniSirGlobal          pMac = PMAC_STRUCT(hHal);
    tCsrRoamSession         *pSession = NULL;

    VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: "
               "ulMulticastAddrCnt=%d, multicastAddr[0]=%pK", __func__,
               pMulticastAddrs->ulMulticastAddrCnt,
               pMulticastAddrs->multicastAddr[0]);

    /*
     *Find the connected Infra / P2P_client connected session
    */
    if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
           (csrIsConnStateInfra(pMac, sessionId) ||
           csr_is_ndi_started(pMac, sessionId))) {
        pSession = CSR_GET_SESSION( pMac, sessionId );
    }

    if (pSession == NULL) {
        smsLog(pMac, LOGW, FL("Unable to find the session Id: %d"), sessionId);
        return eHAL_STATUS_FAILURE;
    }

    pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList));
    if (NULL == pRequestBuf) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to "
            "allocate memory for 8023 Multicast List request", __func__);
        return eHAL_STATUS_FAILED_ALLOC;
    }

    if (!csrIsConnStateConnectedInfra(pMac, sessionId) &&
            !csr_is_ndi_started(pMac, sessionId)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            "%s: Request ignored, session %d is not connected or started",
            __func__, sessionId);
        vos_mem_free(pRequestBuf);
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_copy(pRequestBuf, pMulticastAddrs, sizeof(tSirRcvFltMcAddrList));

    vos_mem_copy(pRequestBuf->selfMacAddr, pSession->selfMacAddr,
                 sizeof(tSirMacAddr));
    vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid,
                 sizeof(tSirMacAddr));

    msg.type = WDA_8023_MULTICAST_LIST_REQ;
    msg.reserved = 0;
    msg.bodyptr = pRequestBuf;
    MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG, sessionId,
                                                          msg.type));
    if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to "
            "post WDA_8023_MULTICAST_LIST message to WDA", __func__);
        vos_mem_free(pRequestBuf);
        return eHAL_STATUS_FAILURE;
    }

    return eHAL_STATUS_SUCCESS;
}

eHalStatus sme_ReceiveFilterSetFilter(tHalHandle hHal, tpSirRcvPktFilterCfgType pRcvPktFilterCfg,
                                           tANI_U8 sessionId)
{
    tpSirRcvPktFilterCfgType    pRequestBuf;
    v_SINT_t                allocSize;
    vos_msg_t               msg;
    tpAniSirGlobal          pMac = PMAC_STRUCT(hHal);
    tCsrRoamSession         *pSession = CSR_GET_SESSION( pMac, sessionId );
    v_U8_t   idx=0;

    VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterType=%d, "
               "filterId = %d", __func__,
               pRcvPktFilterCfg->filterType, pRcvPktFilterCfg->filterId);

    allocSize = sizeof(tSirRcvPktFilterCfgType);

    pRequestBuf = vos_mem_malloc(allocSize);

    if (NULL == pRequestBuf)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to "
            "allocate memory for Receive Filter Set Filter request", __func__);
        return eHAL_STATUS_FAILED_ALLOC;
    }

    if( NULL == pSession )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Session Not found ", __func__);
        vos_mem_free(pRequestBuf);
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_copy(pRcvPktFilterCfg->selfMacAddr, pSession->selfMacAddr,
                 sizeof(tSirMacAddr));
    vos_mem_copy(pRcvPktFilterCfg->bssId, pSession->connectedProfile.bssid,
                 sizeof(tSirMacAddr));
    vos_mem_copy(pRequestBuf, pRcvPktFilterCfg, allocSize);

    msg.type = WDA_RECEIVE_FILTER_SET_FILTER_REQ;
    msg.reserved = 0;
    msg.bodyptr = pRequestBuf;
    MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG, sessionId,
                                                           msg.type));
    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Pkt Flt Req : "
           "FT %d FID %d ",
           pRequestBuf->filterType, pRequestBuf->filterId);

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Pkt Flt Req : "
           "params %d CT %d",
           pRequestBuf->numFieldParams, pRequestBuf->coalesceTime);

    for (idx=0; idx<pRequestBuf->numFieldParams; idx++)
    {

      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
           "Proto %d Comp Flag %d ",
           pRequestBuf->paramsData[idx].protocolLayer,
           pRequestBuf->paramsData[idx].cmpFlag);

      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
           "Data Offset %d Data Len %d",
           pRequestBuf->paramsData[idx].dataOffset,
           pRequestBuf->paramsData[idx].dataLength);

      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
          "CData: %d:%d:%d:%d:%d:%d",
           pRequestBuf->paramsData[idx].compareData[0],
           pRequestBuf->paramsData[idx].compareData[1],
           pRequestBuf->paramsData[idx].compareData[2],
           pRequestBuf->paramsData[idx].compareData[3],
           pRequestBuf->paramsData[idx].compareData[4],
           pRequestBuf->paramsData[idx].compareData[5]);

      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
           "MData: %d:%d:%d:%d:%d:%d",
           pRequestBuf->paramsData[idx].dataMask[0],
           pRequestBuf->paramsData[idx].dataMask[1],
           pRequestBuf->paramsData[idx].dataMask[2],
           pRequestBuf->paramsData[idx].dataMask[3],
           pRequestBuf->paramsData[idx].dataMask[4],
           pRequestBuf->paramsData[idx].dataMask[5]);

    }

    if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post "
            "WDA_RECEIVE_FILTER_SET_FILTER message to WDA", __func__);
        vos_mem_free(pRequestBuf);
        return eHAL_STATUS_FAILURE;
    }

    return eHAL_STATUS_SUCCESS;
}

eHalStatus sme_GetFilterMatchCount(tHalHandle hHal,
                                   FilterMatchCountCallback callbackRoutine,
                                   void *callbackContext,
                                   tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status;

    VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "+%s", __func__);

    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme)))
    {
        pmcGetFilterMatchCount(hHal, callbackRoutine, callbackContext, sessionId);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "-%s", __func__);

    return (status);
}

eHalStatus sme_ReceiveFilterClearFilter(tHalHandle hHal, tpSirRcvFltPktClearParam pRcvFltPktClearParam,
                                             tANI_U8 sessionId)
{
    tpSirRcvFltPktClearParam pRequestBuf;
    vos_msg_t               msg;
    tpAniSirGlobal          pMac = PMAC_STRUCT(hHal);
    tCsrRoamSession         *pSession = CSR_GET_SESSION( pMac, sessionId );

    VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterId = %d", __func__,
               pRcvFltPktClearParam->filterId);

    pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltPktClearParam));
    if (NULL == pRequestBuf)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            "%s: Not able to allocate memory for Receive Filter "
            "Clear Filter request", __func__);
        return eHAL_STATUS_FAILED_ALLOC;
    }
    if( NULL == pSession )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            "%s: Session Not find ", __func__);
        vos_mem_free(pRequestBuf);
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_copy(pRcvFltPktClearParam->selfMacAddr, pSession->selfMacAddr,
                 sizeof(tSirMacAddr));
    vos_mem_copy(pRcvFltPktClearParam->bssId, pSession->connectedProfile.bssid,
                 sizeof(tSirMacAddr));

    vos_mem_copy(pRequestBuf, pRcvFltPktClearParam, sizeof(tSirRcvFltPktClearParam));

    msg.type = WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ;
    msg.reserved = 0;
    msg.bodyptr = pRequestBuf;
    MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG, sessionId,
                                                          msg.type));
    if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post "
            "WDA_RECEIVE_FILTER_CLEAR_FILTER message to WDA", __func__);
        vos_mem_free(pRequestBuf);
        return eHAL_STATUS_FAILURE;
    }

    return eHAL_STATUS_SUCCESS;
}
#endif // WLAN_FEATURE_PACKET_FILTERING

/* ---------------------------------------------------------------------------
    \fn sme_PreChannelSwitchIndFullPowerCB
    \brief  call back function for the PMC full power request because of pre
             channel switch.
    \param callbackContext
    \param status
  ---------------------------------------------------------------------------*/
void sme_PreChannelSwitchIndFullPowerCB(void *callbackContext,
                eHalStatus status)
{
    tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext;
    tSirMbMsg *pMsg;
    tANI_U16 msgLen;

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

    return;
}

/* ---------------------------------------------------------------------------
    \fn sme_PreChannelSwitchIndOffloadFullPowerCB
    \brief  call back function for the PMC full power request because of pre
             channel switch for offload case.
    \param callbackContext
    \param sessionId
    \param status
  ---------------------------------------------------------------------------*/
void sme_PreChannelSwitchIndOffloadFullPowerCB(void *callbackContext,tANI_U32 sessionId,
                eHalStatus status)
{
    tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext;
    tSirMbMsg *pMsg;
    tANI_U16 msgLen;

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

    return;
}

/* ---------------------------------------------------------------------------
    \fn sme_HandlePreChannelSwitchInd
    \brief  Processes the indication from PE for pre-channel switch.
    \param hHal
    \param void *pMsgBuf to carry session id
    \- The handle returned by macOpen. return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal, void *pMsgBuf)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tpSirSmePreSwitchChannelInd pPreSwitchChInd = (tpSirSmePreSwitchChannelInd)pMsgBuf;

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

        if(!pMac->psOffloadEnabled)
        {
            status = pmcRequestFullPower(hHal, sme_PreChannelSwitchIndFullPowerCB,
                            pMac, eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH);
        }
        else
        {
            if (NULL != pPreSwitchChInd)
            {
                status = pmcOffloadRequestFullPower(hHal, pPreSwitchChInd->sessionId,
                                                    sme_PreChannelSwitchIndOffloadFullPowerCB,
                                                    pMac, eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH);
            }
            else
	    {
                   smsLog(pMac, LOGE, "Empty pMsgBuf  message for channel switch "
                          "(eWNI_SME_PRE_SWITCH_CHL_IND), nothing to process");
            }
        }

       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_HandlePostChannelSwitchInd
    \brief  Processes the indication from PE for post-channel switch.
    \param hHal
    \- The handle returned by macOpen. return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status = pmcRequestBmps(hHal, NULL, NULL);
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}

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

    \fn sme_IsChannelValid

    \brief To check if the channel is valid for currently established domain
    This is a synchronous API.

    \param hHal - The handle returned by macOpen.
    \param channel - channel to verify

    \return TRUE/FALSE, TRUE if channel is valid

  -------------------------------------------------------------------------------*/
tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tANI_BOOLEAN valid = FALSE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {

      valid = csrRoamIsChannelValid( pMac, channel);

      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (valid);
}

/* ---------------------------------------------------------------------------
    \fn sme_SetFreqBand
    \brief  Used to set frequency band.
    \param  hHal
    \param  sessionId - Session Identifier
    \eBand  band value to be configured
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SetFreqBand(tHalHandle hHal, tANI_U8 sessionId, eCsrBand eBand)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = csrSetBand(hHal, sessionId, eBand);
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_GetFreqBand
    \brief  Used to get the current band settings.
    \param  hHal
    \pBand  pointer to hold band value
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_GetFreqBand(tHalHandle hHal, eCsrBand *pBand)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      *pBand = csrGetCurrentBand( hHal );
      sme_ReleaseGlobalLock( &pMac->sme );
   }
   return status;
}

#ifdef WLAN_WAKEUP_EVENTS
/******************************************************************************
  \fn sme_WakeReasonIndCallback

  \brief
  a callback function called when SME received eWNI_SME_WAKE_REASON_IND event from WDA

  \param hHal - HAL handle for device
  \param pMsg - Message body passed from WDA; includes Wake Reason Indication parameter

  \return eHalStatus
******************************************************************************/
eHalStatus sme_WakeReasonIndCallback (tHalHandle hHal, void* pMsg)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tSirWakeReasonInd *pWakeReasonInd = (tSirWakeReasonInd *)pMsg;

   if (NULL == pMsg)
   {
      smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
      status = eHAL_STATUS_FAILURE;
   }
   else
   {
      smsLog(pMac, LOG2, "SME: entering sme_WakeReasonIndCallback");

      /* Call Wake Reason Indication callback routine. */
      if (pMac->pmc.wakeReasonIndCB != NULL)
          pMac->pmc.wakeReasonIndCB(pMac->pmc.wakeReasonIndCBContext, pWakeReasonInd);

      pMac->pmc.wakeReasonIndCB = NULL;
      pMac->pmc.wakeReasonIndCBContext = NULL;

      smsLog(pMac, LOG1, "Wake Reason Indication in %s(), reason=%d", __func__, pWakeReasonInd->ulReason);
   }

   return(status);
}
#endif // WLAN_WAKEUP_EVENTS

/**
 * sme_SetMaxTxPowerPerBand() - Set the Maximum Transmit Power
 * specific to band dynamically
 * @band: Band for which power needs to be applied
 * @dB: power to set in dB
 * @hal: HAL handle
 *
 * Set the maximum transmit power dynamically per band
 *
 * Return: eHalStatus
 */
eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB,
                  tHalHandle hal)
{
	eHalStatus status;
	tSmeCmd *set_max_tx_pwr_per_band;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

        if (mac_ctx->max_power_cmd_pending) {
           smsLog(mac_ctx, LOG1,
                 FL("set max tx power already in progress"));
           return eHAL_STATUS_RESOURCES;
        }

	smsLog(mac_ctx, LOG1,
		  FL("band : %d power %d dB"),
		  band, dB);

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		set_max_tx_pwr_per_band = csrGetCommandBuffer(mac_ctx);
		if (set_max_tx_pwr_per_band) {
			set_max_tx_pwr_per_band->command =
					eSmeCommandSetMaxTxPowerPerBand;
			set_max_tx_pwr_per_band->u.
				set_tx_max_pwr_per_band.band = band;
			set_max_tx_pwr_per_band->u.
				set_tx_max_pwr_per_band.power = dB;
                        mac_ctx->max_power_cmd_pending = true;
			status = csrQueueSmeCommand(mac_ctx,
						set_max_tx_pwr_per_band,
						eANI_BOOLEAN_TRUE);
			if (!HAL_STATUS_SUCCESS(status)) {
				smsLog(mac_ctx, LOGE,
					FL("fail to send msg status = %d"),
						status);
				csrReleaseCommand(mac_ctx,
						set_max_tx_pwr_per_band);
                                mac_ctx->max_power_cmd_pending = false;
			}
		} else {
			smsLog(mac_ctx, LOGE,
				FL("can not obtain a common buffer"));
			status = eHAL_STATUS_RESOURCES;
		}
	sme_ReleaseGlobalLock(&mac_ctx->sme);
	}
	return status;
}

/**
 * sme_SetMaxTxPower() - Set the Maximum Transmit Power
 *
 * @hHal: hal pointer.
 * @bssid: bssid to set the power cap for
 * @self_mac_addr:self mac address
 * @db: power to set in dB
 *
 * Set the maximum transmit power dynamically.
 *
 * Return: eHalStatus
 *
 */
eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr bssid,
				tSirMacAddr self_mac_addr, v_S7_t db)
{
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hHal);
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tSmeCmd *set_max_tx_pwr;

        if (mac_ptr->max_power_cmd_pending) {
           smsLog(mac_ptr, LOG1,
                 FL("set max tx power already in progress"));
           return eHAL_STATUS_RESOURCES;
        }

	MTRACE(vos_trace(VOS_MODULE_ID_SME,
		TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0));
	smsLog(mac_ptr, LOG1,
	  FL("bssid :" MAC_ADDRESS_STR " self addr: "MAC_ADDRESS_STR" power %d Db"),
	  MAC_ADDR_ARRAY(bssid), MAC_ADDR_ARRAY(self_mac_addr), db);

	status = sme_AcquireGlobalLock(&mac_ptr->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		set_max_tx_pwr = csrGetCommandBuffer(mac_ptr);
		if (set_max_tx_pwr) {
			set_max_tx_pwr->command = eSmeCommandSetMaxTxPower;
			vos_mem_copy(set_max_tx_pwr->u.set_tx_max_pwr.bssid,
				bssid, SIR_MAC_ADDR_LENGTH);
			vos_mem_copy(set_max_tx_pwr->u.set_tx_max_pwr.self_sta_mac_addr,
				self_mac_addr, SIR_MAC_ADDR_LENGTH);
			set_max_tx_pwr->u.set_tx_max_pwr.power = db;
                        mac_ptr->max_power_cmd_pending = true;
			status = csrQueueSmeCommand(mac_ptr, set_max_tx_pwr,
							eANI_BOOLEAN_TRUE);
			if (!HAL_STATUS_SUCCESS(status)) {
				smsLog(mac_ptr, LOGE,
					FL("fail to send msg status = %d"),
									status);
				csrReleaseCommandScan(mac_ptr, set_max_tx_pwr);
                                mac_ptr->max_power_cmd_pending = false;
			}
		}
		else
		{
			smsLog(mac_ptr, LOGE,
				FL("can not obtain a common buffer"));
			status = eHAL_STATUS_RESOURCES;
		}
		sme_ReleaseGlobalLock(&mac_ptr->sme);
	}
	return status;
}

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

    \fn sme_SetCustomMacAddr

    \brief Set the customer Mac Address.

    \param customMacAddr  customer MAC Address
    \- return eHalStatus

  ---------------------------------------------------------------------------*/
eHalStatus sme_SetCustomMacAddr(tSirMacAddr customMacAddr)
{
    vos_msg_t msg;
    tSirMacAddr *pBaseMacAddr;

    pBaseMacAddr = vos_mem_malloc(sizeof(tSirMacAddr));
    if (NULL == pBaseMacAddr)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("Not able to allocate memory for pBaseMacAddr"));
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr));

    msg.type = SIR_HAL_SET_BASE_MACADDR_IND;
    msg.reserved = 0;
    msg.bodyptr = pBaseMacAddr;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WDA"));
        vos_mem_free(pBaseMacAddr);
        return eHAL_STATUS_FAILURE;
    }

    return eHAL_STATUS_SUCCESS;
}

/* ----------------------------------------------------------------------------
   \fn sme_SetTxPower
   \brief Set Transmit Power dynamically.
   \param  hHal
   \param sessionId  Target Session ID
   \pBSSId BSSID
   \dev_mode dev_mode such as station, P2PGO, SAP
   \param dBm  power to set
   \- return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetTxPower(tHalHandle hHal, v_U8_t sessionId,
                          tSirMacAddr pBSSId,
                          tVOS_CON_MODE dev_mode, int dBm)
{
   vos_msg_t msg;
   tpMaxTxPowerParams pTxParams = NULL;
   v_S7_t power = (v_S7_t)dBm;

  MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0));

   /* make sure there is no overflow */
   if ((int)power != dBm) {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: error, invalid power = %d", __func__, dBm);
      return eHAL_STATUS_FAILURE;
   }

   pTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams));
   if (NULL == pTxParams)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              "%s: Not able to allocate memory for pTxParams", __func__);
       return eHAL_STATUS_FAILURE;
   }

   vos_mem_copy(pTxParams->bssId, pBSSId, SIR_MAC_ADDR_LENGTH);
   pTxParams->power = power; /* unit is dBm */
   pTxParams->dev_mode = dev_mode;
   msg.type = WDA_SET_TX_POWER_REQ;
   msg.reserved = 0;
   msg.bodyptr = pTxParams;

   if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: failed to post WDA_SET_TX_POWER_REQ to WDA",
                __func__);
      vos_mem_free(pTxParams);
      return eHAL_STATUS_FAILURE;
   }

   return eHAL_STATUS_SUCCESS;
}

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

    \fn sme_HideSSID

    \brief hide/show SSID dynamically. Note: this setting will
    not persist over reboots.

    \param hHal
    \param sessionId
    \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID
    \- return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_HideSSID(tHalHandle hHal, v_U8_t sessionId, v_U8_t ssidHidden)
{
    eHalStatus status   = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tANI_U16 len;

    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        tpSirUpdateParams pMsg;
        tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

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

        if( !pSession->sessionActive )
            VOS_ASSERT(0);

        /* Create the message and send to lim */
        len = sizeof(tSirUpdateParams);
        pMsg = vos_mem_malloc(len);
        if ( NULL == pMsg )
           status = eHAL_STATUS_FAILURE;
        else
        {
            vos_mem_set(pMsg, sizeof(tSirUpdateParams), 0);
            pMsg->messageType     = eWNI_SME_HIDE_SSID_REQ;
            pMsg->length          = len;
            /* Data starts from here */
            pMsg->sessionId       = sessionId;
            pMsg->ssidHidden      = ssidHidden;
            status = palSendMBMessage(pMac->hHdd, pMsg);
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
   return status;
}

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

    \fn sme_SetTmLevel
    \brief  Set Thermal Mitigation Level to RIVA
    \param  hHal - The handle returned by macOpen.
    \param  newTMLevel - new Thermal Mitigation Level
    \param  tmMode - Thermal Mitigation handle mode, default 0
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetTmLevel(tHalHandle hHal, v_U16_t newTMLevel, v_U16_t tmMode)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
    vos_msg_t           vosMessage;
    tAniSetTmLevelReq  *setTmLevelReq = NULL;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                         TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0));
    if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
    {
        setTmLevelReq = (tAniSetTmLevelReq *)vos_mem_malloc(sizeof(tAniSetTmLevelReq));
        if (NULL == setTmLevelReq)
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Not able to allocate memory for sme_SetTmLevel", __func__);
           sme_ReleaseGlobalLock( &pMac->sme );
           return eHAL_STATUS_FAILURE;
        }

        setTmLevelReq->tmMode     = tmMode;
        setTmLevelReq->newTmLevel = newTMLevel;

        /* serialize the req through MC thread */
        vosMessage.bodyptr = setTmLevelReq;
        vosMessage.type    = WDA_SET_TM_LEVEL_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Post Set TM Level MSG fail", __func__);
           vos_mem_free(setTmLevelReq);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return(status);
}

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

  \brief sme_featureCapsExchange() - SME interface to exchange capabilities between
  Host and FW.

  \param  hHal - HAL handle for device

  \return NONE

---------------------------------------------------------------------------*/
void sme_featureCapsExchange( tHalHandle hHal)
{
    v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_CAPS_EXCH, NO_SESSION, 0));
    WDA_featureCapsExchange(vosContext);
}

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

  \brief sme_disableFeatureCapablity() - SME interface to disable Active mode
                                       offload capability in Host.

  \param  hHal - HAL handle for device

  \return NONE

---------------------------------------------------------------------------*/
void sme_disableFeatureCapablity(tANI_U8 feature_index)
{
    WDA_disableCapablityFeature(feature_index);
}



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

    \fn sme_GetDefaultCountryCode

    \brief Get the default country code from NV

    \param  hHal
    \param  pCountry
    \- return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_GetDefaultCountryCodeFrmNv(tHalHandle hHal, tANI_U8 *pCountry)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_GET_DEFCCNV, NO_SESSION, 0));
    return csrGetDefaultCountryCodeFrmNv(pMac, pCountry);
}

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

    \fn sme_GetCurrentCountryCode

    \brief Get the current country code

    \param  hHal
    \param  pCountry
    \- return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus sme_GetCurrentCountryCode(tHalHandle hHal, tANI_U8 *pCountry)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_GET_CURCC, NO_SESSION, 0));
    return csrGetCurrentCountryCode(pMac, pCountry);
}

/* ---------------------------------------------------------------------------
    \fn sme_transportDebug
    \brief  Dynamically monitoring Transport channels
            Private IOCTL will query transport channel status if driver loaded
    \param  hHal Upper MAC context
    \param  displaySnapshot Display transport channel snapshot option
    \param  toggleStallDetect Enable stall detect feature
                              This feature will take effect to data performance
                              Not integrate till fully verification
    \- return NONE
    -------------------------------------------------------------------------*/
void sme_transportDebug(tHalHandle hHal, v_BOOL_t displaySnapshot, v_BOOL_t toggleStallDetect)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   if (NULL == pMac)
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: invalid context", __func__);
      return;
   }
   WDA_TransportChannelDebug(pMac, displaySnapshot, toggleStallDetect);
}

/* ---------------------------------------------------------------------------
    \fn     sme_ResetPowerValuesFor5G
    \brief  Reset the power values for 5G band with NV power values.
    \param  hHal - HAL handle for device
    \- return NONE
    -------------------------------------------------------------------------*/
void sme_ResetPowerValuesFor5G (tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT (hHal);
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0));
    csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE);
    csrApplyPower2Current(pMac);     // Store the channel+power info in the global place: Cfg
}

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
/* ---------------------------------------------------------------------------
    \fn sme_UpdateRoamPrefer5GHz
    \brief  enable/disable Roam prefer 5G runtime option
            This function is called through dynamic setConfig callback function
            to configure the Roam prefer 5G runtime option
    \param  hHal - HAL handle for device
    \param  nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option
    \- return Success or failure
    -------------------------------------------------------------------------*/

eHalStatus sme_UpdateRoamPrefer5GHz(tHalHandle hHal, v_BOOL_t nRoamPrefer5GHz)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                       TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: gRoamPrefer5GHz is changed from %d to %d", __func__,
                      pMac->roam.configParam.nRoamPrefer5GHz,
                      nRoamPrefer5GHz);
        pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_setRoamIntraBand
    \brief  enable/disable Intra band roaming
            This function is called through dynamic setConfig callback function
            to configure the intra band roaming
    \param  hHal - HAL handle for device
    \param  nRoamIntraBand Enable/Disable Intra band roaming
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_setRoamIntraBand(tHalHandle hHal, const v_BOOL_t nRoamIntraBand)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: gRoamIntraBand is changed from %d to %d", __func__,
                      pMac->roam.configParam.nRoamIntraBand,
                      nRoamIntraBand);
        pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_UpdateRoamScanNProbes
    \brief  function to update roam scan N probes
            This function is called through dynamic setConfig callback function
            to update roam scan N probes
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nProbes number of probe requests to be sent out
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_UpdateRoamScanNProbes(tHalHandle hHal, tANI_U8 sessionId,
                                     const v_U8_t nProbes)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: gRoamScanNProbes is changed from %d to %d", __func__,
                      pMac->roam.configParam.nProbes,
                      nProbes);
        pMac->roam.configParam.nProbes = nProbes;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
        csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                           REASON_NPROBES_CHANGED);
    }
#endif
    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_UpdateRoamScanHomeAwayTime
    \brief  function to update roam scan Home away time
            This function is called through dynamic setConfig callback function
            to update roam scan home away time
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamScanAwayTime Scan home away time
    \param  bSendOffloadCmd If TRUE then send offload command to firmware
                            If FALSE then command is not sent to firmware
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_UpdateRoamScanHomeAwayTime(tHalHandle hHal,
                                          tANI_U8 sessionId,
                                          const v_U16_t nRoamScanHomeAwayTime,
                                          const eAniBoolean bSendOffloadCmd)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: gRoamScanHomeAwayTime is changed from %d to %d", __func__,
                      pMac->roam.configParam.nRoamScanHomeAwayTime,
                      nRoamScanHomeAwayTime);
        pMac->roam.configParam.nRoamScanHomeAwayTime = nRoamScanHomeAwayTime;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled && bSendOffloadCmd)
    {
        csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                           REASON_HOME_AWAY_TIME_CHANGED);
    }
#endif
    return status;
}

/**
 * sme_ext_change_channel()- function to post send ECSA
 * action frame to csr.
 * @hHal: Hal context
 * @channel: new channel to switch
 * @session_id: senssion it should be sent on.
 *
 * This function is called to post ECSA frame to csr.
 *
 * Return: success if msg is sent else return failure
 */
eHalStatus sme_ext_change_channel(tHalHandle hHal, uint32_t channel,
						uint8_t session_id)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx  = PMAC_STRUCT(hHal);
	uint8_t channel_state;

	smsLog(mac_ctx, LOGE, FL(" Set Channel %d "), channel);
	channel_state =
		vos_nv_getChannelEnabledState(channel);

	if ((NV_CHANNEL_DISABLE == channel_state)) {
		smsLog(mac_ctx, LOGE, FL(" Invalid channel %d "), channel);
		return eHAL_STATUS_FAILURE;
	}

	status = sme_AcquireGlobalLock(&mac_ctx->sme);

	if (eHAL_STATUS_SUCCESS == status) {
		/* update the channel list to the firmware */
		status = csr_send_ext_change_channel(mac_ctx,
						channel, session_id);
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}

	return status;
}
/* ---------------------------------------------------------------------------
    \fn sme_getRoamIntraBand
    \brief  get Intra band roaming
    \param  hHal - HAL handle for device
    \- return Success or failure
    -------------------------------------------------------------------------*/
v_BOOL_t sme_getRoamIntraBand(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
              TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0));
    return pMac->roam.configParam.nRoamIntraBand;
}

/* ---------------------------------------------------------------------------
    \fn sme_getRoamScanNProbes
    \brief  get N Probes
    \param  hHal - HAL handle for device
    \- return Success or failure
    -------------------------------------------------------------------------*/
v_U8_t sme_getRoamScanNProbes(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.nProbes;
}

/* ---------------------------------------------------------------------------
    \fn sme_getRoamScanHomeAwayTime
    \brief  get Roam scan home away time
    \param  hHal - HAL handle for device
    \- return Success or failure
    -------------------------------------------------------------------------*/
v_U16_t sme_getRoamScanHomeAwayTime(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.nRoamScanHomeAwayTime;
}


/* ---------------------------------------------------------------------------
    \fn sme_UpdateImmediateRoamRssiDiff
    \brief  Update nImmediateRoamRssiDiff
            This function is called through dynamic setConfig callback function
            to configure nImmediateRoamRssiDiff
            Usage: adb shell iwpriv wlan0 setConfig gImmediateRoamRssiDiff=[0 .. 125]
    \param  hHal - HAL handle for device
    \param  nImmediateRoamRssiDiff - minimum rssi difference between potential
            candidate and current AP.
    \param  sessionId - Session Identifier
    \- return Success or failure
    -------------------------------------------------------------------------*/

eHalStatus sme_UpdateImmediateRoamRssiDiff(tHalHandle hHal,
                                           v_U8_t nImmediateRoamRssiDiff,
                                           tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
               TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF, NO_SESSION, 0));
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set immediate roam rssi diff to %d - old value is %d - roam state is %s",
                     nImmediateRoamRssiDiff,
                     pMac->roam.configParam.nImmediateRoamRssiDiff,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pMac->roam.configParam.nImmediateRoamRssiDiff = nImmediateRoamRssiDiff;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_UpdateRoamRssiDiff
    \brief  Update RoamRssiDiff
            This function is called through dynamic setConfig callback function
            to configure RoamRssiDiff
            Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  RoamRssiDiff - minimum rssi difference between potential
            candidate and current AP.
    \- return Success or failure
    -------------------------------------------------------------------------*/

eHalStatus sme_UpdateRoamRssiDiff(tHalHandle hHal, tANI_U8 sessionId,
                                  v_U8_t RoamRssiDiff)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set roam rssi diff to %d - old value is %d - roam state is %s",
                     RoamRssiDiff,
                     pMac->roam.configParam.RoamRssiDiff,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_RSSI_DIFF_CHANGED);
    }
#endif
    return status ;
}

/*--------------------------------------------------------------------------
  \brief sme_UpdateFastTransitionEnabled() - enable/disable Fast Transition support at runtime
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  isFastTransitionEnabled.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS - SME update isFastTransitionEnabled config successfully.
          Other status means SME is failed to update isFastTransitionEnabled.
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_UpdateFastTransitionEnabled(tHalHandle hHal,
        v_BOOL_t isFastTransitionEnabled)
{
  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
            TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: FastTransitionEnabled is changed from %d to %d", __func__,
                      pMac->roam.configParam.isFastTransitionEnabled,
                      isFastTransitionEnabled);
        pMac->roam.configParam.isFastTransitionEnabled = isFastTransitionEnabled;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_UpdateWESMode
    \brief  Update WES Mode
            This function is called through dynamic setConfig callback function
            to configure isWESModeEnabled
    \param  hHal - HAL handle for device
    \param  isWESModeEnabled - WES mode
    \param  sessionId - Session Identifier
    \return eHAL_STATUS_SUCCESS - SME update isWESModeEnabled config successfully.
          Other status means SME is failed to update isWESModeEnabled.
    -------------------------------------------------------------------------*/

eHalStatus sme_UpdateWESMode(tHalHandle hHal, v_BOOL_t isWESModeEnabled,
                               tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set WES Mode to %d - old value is %d - roam state is %s",
                     isWESModeEnabled,
                     pMac->roam.configParam.isWESModeEnabled,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_SetRoamScanControl
    \brief  Set roam scan control
            This function is called to set roam scan control
            if roam scan control is set to 0, roaming scan cache is cleared
            any value other than 0 is treated as invalid value
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \return eHAL_STATUS_SUCCESS - SME update config successfully.
          Other status means SME failure to update
    -------------------------------------------------------------------------*/
eHalStatus sme_SetRoamScanControl(tHalHandle hHal, tANI_U8 sessionId,
                                  v_BOOL_t roamScanControl)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
             TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                    "LFR runtime successfully set roam scan control to %d - old value is %d - roam state is %s",
                     roamScanControl,
                     pMac->roam.configParam.nRoamScanControl,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pMac->roam.configParam.nRoamScanControl = roamScanControl;
        if ( 0 == roamScanControl)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully cleared roam scan cache");
            csrFlushCfgBgScanRoamChannelList(pMac, sessionId);
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
           if (pMac->roam.configParam.isRoamOffloadScanEnabled)
           {
               csrRoamOffloadScan(pMac, sessionId,
                                  ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                                  REASON_FLUSH_CHANNEL_LIST);
           }
#endif
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status ;
}
#endif /* (WLAN_FEATURE_VOWIFI_11R) || (FEATURE_WLAN_ESE) || (FEATURE_WLAN_LFR) */

#ifdef FEATURE_WLAN_LFR
/*--------------------------------------------------------------------------
  \brief sme_UpdateIsFastRoamIniFeatureEnabled() - enable/disable LFR support at runtime
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  isFastRoamIniFeatureEnabled.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config successfully.
          Other status means SME is failed to update isFastRoamIniFeatureEnabled.
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_UpdateIsFastRoamIniFeatureEnabled
(
    tHalHandle hHal,
    tANI_U8 sessionId,
    const v_BOOL_t isFastRoamIniFeatureEnabled)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    if (pMac->roam.configParam.isFastRoamIniFeatureEnabled ==
                  isFastRoamIniFeatureEnabled)
    {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", __func__,
             pMac->roam.configParam.isFastRoamIniFeatureEnabled,
             isFastRoamIniFeatureEnabled);
        return eHAL_STATUS_SUCCESS;
    }

  if (smeNeighborMiddleOfRoaming(hHal, sessionId))
  {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                "%s: In middle of roaming isFastRoamIniFeatureEnabled %d",
                __func__, isFastRoamIniFeatureEnabled);
      if (!isFastRoamIniFeatureEnabled)
          pMac->roam.pending_roam_disable = TRUE;

      return eHAL_STATUS_SUCCESS;
  }

  VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "%s: FastRoamEnabled is changed from %d to %d", __func__,
           pMac->roam.configParam.isFastRoamIniFeatureEnabled,
           isFastRoamIniFeatureEnabled);
    pMac->roam.configParam.isFastRoamIniFeatureEnabled =
                                            isFastRoamIniFeatureEnabled;
    csrNeighborRoamUpdateFastRoamingEnabled(pMac, sessionId,
                                            isFastRoamIniFeatureEnabled);

  return eHAL_STATUS_SUCCESS;
}

/**
 * sme_config_fast_roaming() - enable/disable LFR support at runtime
 * @hhal - The handle returned by macOpen.
 * @session_id - Session Identifier
 * @is_fast_roam_enabled - flag to enable/disable roaming
 *
 * When Supplicant issues enabled/disable fast roaming on the basis
 * of the Bssid modification in network block (e.g. AutoJoin mode N/W block)
 *
 * Return: eHalStatus
 */

eHalStatus sme_config_fast_roaming(tHalHandle hhal, tANI_U8 session_id,
				    const bool is_fast_roam_enabled)
{
	tpAniSirGlobal pmac = PMAC_STRUCT(hhal);
	tCsrRoamSession *psession = CSR_GET_SESSION(pmac, session_id);
	eHalStatus status;

	if (!pmac->roam.configParam.isFastRoamIniFeatureEnabled) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
			  FL("FastRoam is disabled through ini"));
		if (!is_fast_roam_enabled)
			return eHAL_STATUS_SUCCESS;
		return  eHAL_STATUS_FAILURE;
	}

	if (is_fast_roam_enabled && psession && psession->pCurRoamProfile)
		psession->pCurRoamProfile->do_not_roam = false;
	status = csrNeighborRoamUpdateFastRoamingEnabled(pmac,
					 session_id, is_fast_roam_enabled);
	if (!HAL_STATUS_SUCCESS(status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("csrNeighborRoamUpdateFastRoamingEnabled failed"));
		return  eHAL_STATUS_FAILURE;
	}

	return eHAL_STATUS_SUCCESS;
}

/*--------------------------------------------------------------------------
  \brief sme_UpdateIsMAWCIniFeatureEnabled() -
  Enable/disable LFR MAWC support at runtime
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  isMAWCIniFeatureEnabled.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS - SME update MAWCEnabled config successfully.
          Other status means SME is failed to update MAWCEnabled.
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_UpdateIsMAWCIniFeatureEnabled(tHalHandle hHal,
        const v_BOOL_t MAWCEnabled)
{
  tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
  eHalStatus status = eHAL_STATUS_SUCCESS;

  status = sme_AcquireGlobalLock( &pMac->sme );
  if ( HAL_STATUS_SUCCESS( status ) )
  {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                "%s: MAWCEnabled is changed from %d to %d", __func__,
                pMac->roam.configParam.MAWCEnabled,
                MAWCEnabled);
      pMac->roam.configParam.MAWCEnabled = MAWCEnabled;
      sme_ReleaseGlobalLock( &pMac->sme );
  }

  return status ;

}

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/*--------------------------------------------------------------------------
  \brief sme_stopRoaming() - Stop roaming for a given sessionId
   This is a synchronous call
  \param hHal      - The handle returned by macOpen
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS on success
          Other status on failure
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_stopRoaming(tHalHandle hHal,
                           tANI_U8 sessionId,
                           tANI_U8 reason)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus  status  = eHAL_STATUS_SUCCESS;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP, reason);
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return status;
}

/*--------------------------------------------------------------------------
  \brief sme_startRoaming() - Start roaming for a given sessionId
   This is a synchronous call
  \param hHal      - The handle returned by macOpen
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS on success
          Other status on failure
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_startRoaming(tHalHandle hHal,
                           tANI_U8 sessionId,
                           tANI_U8 reason)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus  status  = eHAL_STATUS_SUCCESS;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, reason);
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return status;
}

/*--------------------------------------------------------------------------
  \brief sme_UpdateEnableFastRoamInConcurrency() - enable/disable LFR if Concurrent session exists
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS
          Other status means SME is failed
  \sa
  --------------------------------------------------------------------------*/

eHalStatus sme_UpdateEnableFastRoamInConcurrency(tHalHandle hHal,
                          v_BOOL_t bFastRoamInConIniFeatureEnabled)
{

    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus  status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = bFastRoamInConIniFeatureEnabled;
        if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled)
        {
            pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = 0;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status;
}
#endif
#endif /* FEATURE_WLAN_LFR */

#ifdef FEATURE_WLAN_ESE
/*--------------------------------------------------------------------------
  \brief sme_UpdateIsEseFeatureEnabled() - enable/disable ESE support at runtime
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  isEseIniFeatureEnabled.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param sessionId - Session Identifier
  \param isEseIniFeatureEnabled - flag to enable/disable
  \return eHAL_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config successfully.
          Other status means SME is failed to update isEseIniFeatureEnabled.
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_UpdateIsEseFeatureEnabled
(
    tHalHandle hHal,
    tANI_U8 sessionId,
    const v_BOOL_t isEseIniFeatureEnabled)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    if (pMac->roam.configParam.isEseIniFeatureEnabled == isEseIniFeatureEnabled)
    {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", __func__,
                  pMac->roam.configParam.isEseIniFeatureEnabled,
                  isEseIniFeatureEnabled);
        return eHAL_STATUS_SUCCESS;
    }

  VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: EseEnabled is changed from %d to %d", __func__,
           pMac->roam.configParam.isEseIniFeatureEnabled,
           isEseIniFeatureEnabled);
    pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled;
    csrNeighborRoamUpdateEseModeEnabled(pMac, sessionId,
                                        isEseIniFeatureEnabled);

    if (TRUE == isEseIniFeatureEnabled)
    {
        sme_UpdateFastTransitionEnabled(hHal, TRUE);
    }

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_ESE_INI_CFG_CHANGED);
    }
#endif
    return eHAL_STATUS_SUCCESS;
}
#endif /* FEATURE_WLAN_ESE */

/*--------------------------------------------------------------------------
  \brief sme_UpdateConfigFwRssiMonitoring() - enable/disable firmware RSSI Monitoring at runtime
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  fEnableFwRssiMonitoring.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring. config successfully.
          Other status means SME is failed to update fEnableFwRssiMonitoring.
  \sa
  --------------------------------------------------------------------------*/

eHalStatus sme_UpdateConfigFwRssiMonitoring(tHalHandle hHal,
        v_BOOL_t fEnableFwRssiMonitoring)
{
    eHalStatus halStatus = eHAL_STATUS_SUCCESS;

    if (ccmCfgSetInt(hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR, fEnableFwRssiMonitoring,
                    NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
    {
        halStatus = eHAL_STATUS_FAILURE;
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "Failure: Could not pass on WNI_CFG_PS_RSSI_MONITOR configuration info to CCM");
    }

    return (halStatus);
}

#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
/* ---------------------------------------------------------------------------
    \fn     sme_SetRoamOpportunisticScanThresholdDiff
    \brief  Update Opportunistic Scan threshold diff
            This function is called through dynamic setConfig callback function
            to configure  nOpportunisticThresholdDiff
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nOpportunisticThresholdDiff - Opportunistic Scan threshold diff
    \return eHAL_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config
            successfully.
            else SME is failed to update nOpportunisticThresholdDiff.
    -------------------------------------------------------------------------*/
eHalStatus sme_SetRoamOpportunisticScanThresholdDiff(tHalHandle hHal,
                            tANI_U8 sessionId,
                            const v_U8_t nOpportunisticThresholdDiff)
{
    tpAniSirGlobal pMac    = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrNeighborRoamSetOpportunisticScanThresholdDiff(pMac,
                                         sessionId,
                                         nOpportunisticThresholdDiff);
        if (HAL_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                "LFR runtime successfully set "
                "opportunistic threshold diff to %d"
                " - old value is %d - roam state is %d",
                nOpportunisticThresholdDiff,
                pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff,
                pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
            pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff = nOpportunisticThresholdDiff;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status;
}

/*--------------------------------------------------------------------------
  \fn    sme_GetRoamOpportunisticScanThresholdDiff()
  \brief gets Opportunistic Scan threshold diff
         This is a synchronous call
  \param hHal - The handle returned by macOpen
  \return v_U8_t - nOpportunisticThresholdDiff
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_GetRoamOpportunisticScanThresholdDiff(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff;
}

/* ---------------------------------------------------------------------------
    \fn     sme_SetRoamRescanRssiDiff
    \brief  Update roam rescan rssi diff
            This function is called through dynamic setConfig callback function
            to configure  nRoamRescanRssiDiff
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamRescanRssiDiff - roam rescan rssi diff
    \return eHAL_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config
            successfully.
            else SME is failed to update nRoamRescanRssiDiff.
    -------------------------------------------------------------------------*/
eHalStatus sme_SetRoamRescanRssiDiff(tHalHandle hHal,
                                     tANI_U8 sessionId,
                                     const v_U8_t nRoamRescanRssiDiff)
{
    tpAniSirGlobal pMac    = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrNeighborRoamSetRoamRescanRssiDiff(pMac, sessionId,
        nRoamRescanRssiDiff);
        if (HAL_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                "LFR runtime successfully set "
                "opportunistic threshold diff to %d"
                " - old value is %d - roam state is %d",
                nRoamRescanRssiDiff,
                pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff,
                pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
            pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff =
                nRoamRescanRssiDiff;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/*--------------------------------------------------------------------------
  \fn    sme_GetRoamRescanRssiDiff
  \brief gets roam rescan rssi diff
         This is a synchronous call
  \param hHal - The handle returned by macOpen
  \return v_S7_t - nRoamRescanRssiDiff
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_GetRoamRescanRssiDiff(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
}

/* ---------------------------------------------------------------------------
    \fn     sme_SetRoamBmissFirstBcnt
    \brief  Update Roam count for first beacon miss
            This function is called through dynamic setConfig callback function
            to configure nRoamBmissFirstBcnt
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamBmissFirstBcnt - Roam first bmiss count
    \return eHAL_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt
            successfully.
            else SME is failed to update nRoamBmissFirstBcnt
    -------------------------------------------------------------------------*/
eHalStatus sme_SetRoamBmissFirstBcnt(tHalHandle hHal,
                                     tANI_U8 sessionId,
                                     const v_U8_t nRoamBmissFirstBcnt)
{
    tpAniSirGlobal pMac    = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrNeighborRoamSetRoamBmissFirstBcnt(pMac, sessionId,
                                                      nRoamBmissFirstBcnt);
        if (HAL_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                "LFR runtime successfully set "
                "beacon miss first beacon count to %d"
                " - old value is %d - roam state is %d",
                nRoamBmissFirstBcnt,
                pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt,
                pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
            pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt =
                nRoamBmissFirstBcnt;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_GetRoamBmissFirstBcnt
    \brief  get neighbor roam beacon miss first count
    \param hHal - The handle returned by macOpen.
    \return v_U8_t - neighbor roam beacon miss first count
    -------------------------------------------------------------------------*/
v_U8_t sme_GetRoamBmissFirstBcnt(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
}

/* ---------------------------------------------------------------------------
    \fn     sme_SetRoamBmissFinalBcnt
    \brief  Update Roam count for final beacon miss
            This function is called through dynamic setConfig callback function
            to configure nRoamBmissFinalBcnt
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamBmissFinalBcnt - Roam final bmiss count
    \return eHAL_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt
            successfully.
            else SME is failed to update nRoamBmissFinalBcnt
    -------------------------------------------------------------------------*/
eHalStatus sme_SetRoamBmissFinalBcnt(tHalHandle hHal,
                                     tANI_U8 sessionId,
                                     const v_U8_t nRoamBmissFinalBcnt)
{
    tpAniSirGlobal pMac    = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrNeighborRoamSetRoamBmissFinalBcnt(pMac, sessionId,
                                                      nRoamBmissFinalBcnt);
        if (HAL_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                "LFR runtime successfully set "
                "beacon miss final beacon count to %d"
                " - old value is %d - roam state is %d",
                nRoamBmissFinalBcnt,
                pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt,
                pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
            pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt =
                nRoamBmissFinalBcnt;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/*--------------------------------------------------------------------------
  \fn    sme_GetRoamBmissFinalBcnt
  \brief gets Roam count for final beacon miss
         This is a synchronous call
  \param hHal - The handle returned by macOpen
  \return v_U8_t - nRoamBmissFinalBcnt
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_GetRoamBmissFinalBcnt(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
}

/* ---------------------------------------------------------------------------
    \fn     sme_SetRoamBeaconRssiWeight
    \brief  Update Roam beacon rssi weight
            This function is called through dynamic setConfig callback function
            to configure nRoamBeaconRssiWeight
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamBeaconRssiWeight - Roam beacon rssi weight
    \return eHAL_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config
            successfully.
            else SME is failed to update nRoamBeaconRssiWeight
    -------------------------------------------------------------------------*/
eHalStatus sme_SetRoamBeaconRssiWeight(tHalHandle hHal,
                                       tANI_U8 sessionId,
                                     const v_U8_t nRoamBeaconRssiWeight)
{
    tpAniSirGlobal pMac    = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrNeighborRoamSetRoamBeaconRssiWeight(pMac, sessionId,
                                                        nRoamBeaconRssiWeight);
        if (HAL_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                "LFR runtime successfully set "
                "beacon miss final beacon count to %d"
                " - old value is %d - roam state is %d",
                nRoamBeaconRssiWeight,
                pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight,
                pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
            pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight =
                nRoamBeaconRssiWeight;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/*--------------------------------------------------------------------------
  \fn    sme_GetRoamBeaconRssiWeight
  \brief gets Roam beacon rssi weight
         This is a synchronous call
  \param hHal - The handle returned by macOpen
  \return v_U8_t - nRoamBeaconRssiWeight
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_GetRoamBeaconRssiWeight(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
}
/*--------------------------------------------------------------------------
  \brief sme_setNeighborLookupRssiThreshold() - update neighbor lookup rssi threshold
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_setNeighborLookupRssiThreshold
(
    tHalHandle hHal,
    tANI_U8 sessionId,
    v_U8_t neighborLookupRssiThreshold)
{
    tpAniSirGlobal pMac    = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if (HAL_STATUS_SUCCESS(status))
    {
        status = csrNeighborRoamSetLookupRssiThreshold(pMac, sessionId,
                                                  neighborLookupRssiThreshold);
        if (HAL_STATUS_SUCCESS(status))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                      "LFR runtime successfully set Lookup threshold to %d - old value is %d - roam state is %s",
                      neighborLookupRssiThreshold,
                      pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold,
                      macTraceGetNeighbourRoamState(
                      pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
            pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold =
                                            neighborLookupRssiThreshold;
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status;
}

/*--------------------------------------------------------------------------
  \brief sme_set_delay_before_vdev_stop() - update delay before VDEV_STOP
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_set_delay_before_vdev_stop(tHalHandle hHal,
                                          tANI_U8    sessionId,
                                          v_U8_t     delay_before_vdev_stop)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus     status  = eHAL_STATUS_SUCCESS;
    status = sme_AcquireGlobalLock( &pMac->sme );
    if (HAL_STATUS_SUCCESS(status))
    {
       VOS_TRACE(VOS_MODULE_ID_SME,
                 VOS_TRACE_LEVEL_DEBUG,
                 FL("LFR param delay_before_vdev_stop changed from %d to %d"),
              pMac->roam.configParam.neighborRoamConfig.delay_before_vdev_stop,
              delay_before_vdev_stop);

       pMac->roam.neighborRoamInfo[sessionId].cfgParams.delay_before_vdev_stop =
                                                         delay_before_vdev_stop;
       pMac->roam.configParam.neighborRoamConfig.delay_before_vdev_stop =
                                                         delay_before_vdev_stop;
       sme_ReleaseGlobalLock( &pMac->sme );
    }
    return eHAL_STATUS_SUCCESS;
}

/*--------------------------------------------------------------------------
  \brief sme_setNeighborReassocRssiThreshold() - update neighbor reassoc rssi threshold
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_setNeighborReassocRssiThreshold
(
    tHalHandle hHal,
    tANI_U8 sessionId,
    v_U8_t neighborReassocRssiThreshold)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if (HAL_STATUS_SUCCESS(status))
    {
        pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig;
        pNeighborRoamInfo   = &pMac->roam.neighborRoamInfo[sessionId];
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set Reassoc threshold to %d- old value is %d - roam state is %s",
                     neighborReassocRssiThreshold,
                     pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pNeighborRoamConfig->nNeighborReassocRssiThreshold =
                                      neighborReassocRssiThreshold;
        pNeighborRoamInfo->cfgParams.neighborReassocThreshold =
                                      neighborReassocRssiThreshold;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}


/*--------------------------------------------------------------------------
  \brief sme_getNeighborLookupRssiThreshold() - get neighbor lookup rssi threshold
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_getNeighborLookupRssiThreshold(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
}

/*--------------------------------------------------------------------------
  \brief sme_setNeighborScanRefreshPeriod() - set neighbor scan results refresh period
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanRefreshPeriod
(
    tHalHandle hHal,
    tANI_U8 sessionId,
    v_U16_t neighborScanResultsRefreshPeriod)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig;
        pNeighborRoamInfo   = &pMac->roam.neighborRoamInfo[sessionId];
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set roam scan refresh period to %d- old value is %d - roam state is %s",
                     neighborScanResultsRefreshPeriod,
                     pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pNeighborRoamConfig->nNeighborResultsRefreshPeriod =
                                  neighborScanResultsRefreshPeriod;
        pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
                                  neighborScanResultsRefreshPeriod;

        sme_ReleaseGlobalLock( &pMac->sme );
    }

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED);
    }
#endif
    return status ;
}

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/*--------------------------------------------------------------------------
  \brief sme_UpdateRoamScanOffloadEnabled() -
         Enable/disable roam scan offload feature
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  gRoamScanOffloadEnabled.
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS - SME update config successfully.
          Other status means SME is failed to update.
  \sa
  --------------------------------------------------------------------------*/

eHalStatus sme_UpdateRoamScanOffloadEnabled(tHalHandle hHal,
        v_BOOL_t nRoamScanOffloadEnabled)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
               FL("gRoamScanOffloadEnabled is changed from %d to %d"),
               pMac->roam.configParam.isRoamOffloadScanEnabled,
               nRoamScanOffloadEnabled);
        pMac->roam.configParam.isRoamOffloadScanEnabled =
                                           nRoamScanOffloadEnabled;
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return status ;
}
#endif

/*--------------------------------------------------------------------------
  \brief sme_getNeighborScanRefreshPeriod() - get neighbor scan results refresh period
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return v_U16_t - Neighbor scan results refresh period value
  \sa
  --------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanRefreshPeriod(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
}

/*--------------------------------------------------------------------------
  \brief sme_getEmptyScanRefreshPeriod() - get empty scan refresh period
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
v_U16_t sme_getEmptyScanRefreshPeriod(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod;
}

/* ---------------------------------------------------------------------------
    \fn sme_UpdateEmptyScanRefreshPeriod
    \brief  Update nEmptyScanRefreshPeriod
            This function is called through dynamic setConfig callback function
            to configure nEmptyScanRefreshPeriod
            Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nEmptyScanRefreshPeriod - scan period following empty scan results.
    \- return Success or failure
    -------------------------------------------------------------------------*/

eHalStatus sme_UpdateEmptyScanRefreshPeriod(tHalHandle hHal, tANI_U8 sessionId,
                                            v_U16_t nEmptyScanRefreshPeriod)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig;
        pNeighborRoamInfo   = &pMac->roam.neighborRoamInfo[sessionId];
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set roam scan period to %d -old value is %d - roam state is %s",
                     nEmptyScanRefreshPeriod,
                     pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pNeighborRoamConfig->nEmptyScanRefreshPeriod = nEmptyScanRefreshPeriod;
        pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
                                             nEmptyScanRefreshPeriod;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_EMPTY_SCAN_REF_PERIOD_CHANGED);
    }
#endif
    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_setNeighborScanMinChanTime
    \brief  Update nNeighborScanMinChanTime
            This function is called through dynamic setConfig callback function
            to configure gNeighborScanChannelMinTime
            Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMinTime=[0 .. 60]
    \param  hHal - HAL handle for device
    \param  nNeighborScanMinChanTime - Channel minimum dwell time
    \param  sessionId - Session Identifier
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanMinChanTime(tHalHandle hHal,
                                        const v_U16_t nNeighborScanMinChanTime,
                                        tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set channel min dwell time to %d - old value is %d - roam state is %s",
                     nNeighborScanMinChanTime,
                     pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));

        pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime =
                                                       nNeighborScanMinChanTime;
        pMac->roam.neighborRoamInfo[sessionId].cfgParams.minChannelScanTime =
                                                       nNeighborScanMinChanTime;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_setNeighborScanMaxChanTime
    \brief  Update nNeighborScanMaxChanTime
            This function is called through dynamic setConfig callback function
            to configure gNeighborScanChannelMaxTime
            Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMaxTime=[0 .. 60]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nNeighborScanMinChanTime - Channel maximum dwell time
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanMaxChanTime(tHalHandle hHal, tANI_U8 sessionId,
                                        const v_U16_t nNeighborScanMaxChanTime)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig;
        pNeighborRoamInfo   = &pMac->roam.neighborRoamInfo[sessionId];
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set channel max dwell time to %d - old value is %d - roam state is %s",
                     nNeighborScanMaxChanTime,
                     pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pNeighborRoamConfig->nNeighborScanMaxChanTime =
                                                  nNeighborScanMaxChanTime;
        pNeighborRoamInfo->cfgParams.maxChannelScanTime =
                                                  nNeighborScanMaxChanTime;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_SCAN_CH_TIME_CHANGED);
    }
#endif

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_getNeighborScanMinChanTime
    \brief  get neighbor scan min channel time
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U16_t - channel min time value
    -------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanMinChanTime(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.neighborRoamInfo[sessionId].cfgParams.minChannelScanTime;
}

/* ---------------------------------------------------------------------------
    \fn sme_getNeighborRoamState
    \brief  get neighbor roam state
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U32_t - neighbor roam state
    -------------------------------------------------------------------------*/
v_U32_t sme_getNeighborRoamState(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState;
}

/* ---------------------------------------------------------------------------
    \fn sme_getCurrentRoamState
    \brief  get current roam state
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U32_t - current roam state
    -------------------------------------------------------------------------*/
v_U32_t sme_getCurrentRoamState(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->roam.curState[sessionId];
}

/* ---------------------------------------------------------------------------
    \fn sme_getCurrentRoamSubState
    \brief  get neighbor roam sub state
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U32_t - current roam sub state
    -------------------------------------------------------------------------*/
v_U32_t sme_getCurrentRoamSubState(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->roam.curSubState[sessionId];
}

/* ---------------------------------------------------------------------------
    \fn sme_getLimSmeState
    \brief  get Lim Sme state
    \param hHal - The handle returned by macOpen.
    \return v_U32_t - Lim Sme state
    -------------------------------------------------------------------------*/
v_U32_t sme_getLimSmeState(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->lim.gLimSmeState;
}

/* ---------------------------------------------------------------------------
    \fn sme_getLimMlmState
    \brief  get Lim Mlm state
    \param hHal - The handle returned by macOpen.
    \return v_U32_t - Lim Mlm state
    -------------------------------------------------------------------------*/
v_U32_t sme_getLimMlmState(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->lim.gLimMlmState;
}

/* ---------------------------------------------------------------------------
    \fn sme_IsLimSessionValid
    \brief  is Lim session valid
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_BOOL_t - true or false
    -------------------------------------------------------------------------*/
v_BOOL_t sme_IsLimSessionValid(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    if (sessionId > pMac->lim.maxBssId) {
        smsLog(pMac, LOG1, FL("invalid sessionId:%d"), sessionId);
        return FALSE;
    }

    return pMac->lim.gpSession[sessionId].valid;
}

/* ---------------------------------------------------------------------------
    \fn sme_getLimSmeSessionState
    \brief  get Lim Sme session state
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U32_t - Lim Sme session state
    -------------------------------------------------------------------------*/
v_U32_t sme_getLimSmeSessionState(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->lim.gpSession[sessionId].limSmeState;
}

/* ---------------------------------------------------------------------------
    \fn sme_getLimMlmSessionState
    \brief  get Lim Mlm session state
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U32_t - Lim Mlm session state
    -------------------------------------------------------------------------*/
v_U32_t sme_getLimMlmSessionState(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    return pMac->lim.gpSession[sessionId].limMlmState;
}


/* ---------------------------------------------------------------------------
    \fn sme_getNeighborScanMaxChanTime
    \brief  get neighbor scan max channel time
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U16_t - channel max time value
    -------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanMaxChanTime(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.neighborRoamInfo[sessionId].cfgParams.maxChannelScanTime;
}

/* ---------------------------------------------------------------------------
    \fn sme_setNeighborScanPeriod
    \brief  Update nNeighborScanPeriod
            This function is called through dynamic setConfig callback function
            to configure nNeighborScanPeriod
            Usage: adb shell iwpriv wlan0 setConfig nNeighborScanPeriod=[0 .. 1000]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nNeighborScanPeriod - neighbor scan period
    \- return Success or failure
    -------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanPeriod(tHalHandle hHal, tANI_U8 sessionId,
                                     const v_U16_t nNeighborScanPeriod)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig;
        pNeighborRoamInfo   = &pMac->roam.neighborRoamInfo[sessionId];
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set neighbor scan period to %d"
                     " - old value is %d - roam state is %s",
                     nNeighborScanPeriod,
                     pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pNeighborRoamConfig->nNeighborScanTimerPeriod = nNeighborScanPeriod;
        pNeighborRoamInfo->cfgParams.neighborScanPeriod = nNeighborScanPeriod;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_SCAN_HOME_TIME_CHANGED);
    }
#endif

    return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_getNeighborScanPeriod
    \brief  get neighbor scan period
    \param hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return v_U16_t - neighbor scan period
    -------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanPeriod(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.neighborRoamInfo[sessionId].cfgParams.neighborScanPeriod;
}

#endif

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)

/*--------------------------------------------------------------------------
  \brief sme_getRoamRssiDiff() - get Roam rssi diff
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return v_U16_t - Rssi diff value
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_getRoamRssiDiff(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.RoamRssiDiff;
}

/*--------------------------------------------------------------------------
  \brief sme_ChangeRoamScanChannelList() - Change roam scan channel list
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \param  pChannelList - Output channel list
  \param  numChannels - Output number of channels
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 sessionId,
                                         tANI_U8 *pChannelList,
                                         tANI_U8 numChannels)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
                                        &pMac->roam.neighborRoamInfo[sessionId];
    tANI_U8 oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0};
    tANI_U8 newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0};
    tANI_U8 i = 0, j = 0;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
        {
            for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
            {
                if (j < sizeof(oldChannelList))
                {
                    j += snprintf(oldChannelList + j, sizeof(oldChannelList) - j," %d",
                    pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
                }
                else
                {
                    break;
                }
            }
        }
        csrFlushCfgBgScanRoamChannelList(pMac, sessionId);
        csrCreateBgScanRoamChannelList(pMac, sessionId, pChannelList,
                                       numChannels);
        sme_SetRoamScanControl(hHal, sessionId, 1);
        if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
        {
            j = 0;
            for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
            {
                if (j < sizeof(newChannelList))
                {
                    j += snprintf(newChannelList + j, sizeof(newChannelList) - j," %d",
                           pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
                }
                else
                {
                    break;
                }
            }
        }
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                  "LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d",
                  newChannelList, oldChannelList,
                  pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId,
                          ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_CHANNEL_LIST_CHANGED);
    }
#endif

    return status ;
}

#ifdef FEATURE_WLAN_ESE_UPLOAD
/*--------------------------------------------------------------------------
  \brief sme_SetEseRoamScanChannelList() - set ese roam scan channel list
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \param  pChannelList - Input channel list
  \param  numChannels - Input number of channels
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_SetEseRoamScanChannelList(tHalHandle hHal,
                                         tANI_U8 sessionId,
                                         tANI_U8 *pChannelList,
                                         tANI_U8 numChannels)
{
    tpAniSirGlobal      pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpCsrNeighborRoamControlInfo    pNeighborRoamInfo
       = &pMac->roam.neighborRoamInfo[sessionId];
    tpCsrChannelInfo    currChannelListInfo
       = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
    tANI_U8             oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0};
    tANI_U8             newChannelList[128] = {0};
    tANI_U8             i = 0, j = 0;
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if (NULL != currChannelListInfo->ChannelList)
        {
            for (i = 0; i < currChannelListInfo->numOfChannels; i++)
            {
                j += snprintf(oldChannelList + j,
                              sizeof(oldChannelList) - j,
                              " %d",
                              currChannelListInfo->ChannelList[i]);
            }
        }
        status = csrCreateRoamScanChannelList(pMac, sessionId, pChannelList,
                   numChannels, csrGetCurrentBand(hHal));
        if ( HAL_STATUS_SUCCESS( status ))
        {
            if (NULL != currChannelListInfo->ChannelList)
            {
                j = 0;
                for (i = 0; i < currChannelListInfo->numOfChannels; i++)
                {
                    j += snprintf(newChannelList + j,
                                  sizeof(newChannelList) - j,
                                  " %d",
                    currChannelListInfo->ChannelList[i]);
                }
            }
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
"ESE roam scan channel list successfully set to \
%s - old value is %s - roam state is %d",
                      newChannelList, oldChannelList,
                      pNeighborRoamInfo->neighborRoamState);
        }
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
        if (pMac->roam.configParam.isRoamOffloadScanEnabled)
        {
           csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                              REASON_CHANNEL_LIST_CHANGED);
        }
#endif
    return status ;
}
#endif

/*--------------------------------------------------------------------------
  \brief sme_getRoamScanChannelList() - get roam scan channel list
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  pChannelList - Output channel list
  \param  numChannels - Output number of channels
  \param  sessionId - Session Identifier
  \return eHAL_STATUS_SUCCESS - SME update config successful.
          Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
eHalStatus sme_getRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList,
                                     tANI_U8 *pNumChannels, tANI_U8 sessionId)
{
    int i  = 0;
    tANI_U8 *pOutPtr = pChannelList;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
                                        &pMac->roam.neighborRoamInfo[sessionId];
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
                     "Roam Scan channel list is NOT yet initialized");
            *pNumChannels = 0;
            sme_ReleaseGlobalLock( &pMac->sme );
            return status;
        }

        *pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels;
        for (i = 0; i < (*pNumChannels); i++)
        {
            pOutPtr[i] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
        }
        pOutPtr[i] = '\0';
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return status ;
}

/*--------------------------------------------------------------------------
  \brief sme_getIsEseFeatureEnabled() - get ESE feature enabled or not
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return TRUE (1) - if the ESE feature is enabled
          FALSE (0) - if feature is disabled (compile or runtime)
  \sa
  --------------------------------------------------------------------------*/
tANI_BOOLEAN sme_getIsEseFeatureEnabled(tHalHandle hHal)
{
#ifdef FEATURE_WLAN_ESE
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return csrRoamIsEseIniFeatureEnabled(pMac);
#else
    return eANI_BOOLEAN_FALSE;
#endif
}

/*--------------------------------------------------------------------------
  \brief sme_GetWESMode() - get WES Mode
  This is a synchronous call
  \param hHal - The handle returned by macOpen
  \return v_U8_t - WES Mode Enabled(1)/Disabled(0)
  \sa
  --------------------------------------------------------------------------*/
v_BOOL_t sme_GetWESMode(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.isWESModeEnabled;
}

/*--------------------------------------------------------------------------
  \brief sme_GetRoamScanControl() - get scan control
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return v_BOOL_t - Enabled(1)/Disabled(0)
  \sa
  --------------------------------------------------------------------------*/
v_BOOL_t sme_GetRoamScanControl(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.nRoamScanControl;
}
#endif

/*--------------------------------------------------------------------------
  \brief sme_getIsLfrFeatureEnabled() - get LFR feature enabled or not
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return TRUE (1) - if the feature is enabled
          FALSE (0) - if feature is disabled (compile or runtime)
  \sa
  --------------------------------------------------------------------------*/
tANI_BOOLEAN sme_getIsLfrFeatureEnabled(tHalHandle hHal)
{
#ifdef FEATURE_WLAN_LFR
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
#else
    return eANI_BOOLEAN_FALSE;
#endif
}

/*--------------------------------------------------------------------------
  \brief sme_getIsFtFeatureEnabled() - get FT feature enabled or not
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return TRUE (1) - if the feature is enabled
          FALSE (0) - if feature is disabled (compile or runtime)
  \sa
  --------------------------------------------------------------------------*/
tANI_BOOLEAN sme_getIsFtFeatureEnabled(tHalHandle hHal)
{
#ifdef WLAN_FEATURE_VOWIFI_11R
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.isFastTransitionEnabled;
#else
    return eANI_BOOLEAN_FALSE;
#endif
}


/* ---------------------------------------------------------------------------
    \fn sme_IsFeatureSupportedByFW
    \brief  Check if an feature is enabled by FW

    \param  feattEnumValue - Enumeration value from placeHolderInCapBitmap
    \- return 1/0 (TRUE/FALSE)
    -------------------------------------------------------------------------*/
tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue)
{
   return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue);
}
#ifdef FEATURE_WLAN_TDLS

/* ---------------------------------------------------------------------------
    \fn sme_SendTdlsLinkEstablishParams
    \brief  API to send TDLS Peer Link Establishment Parameters.

    \param  peerMac - peer's Mac Address.
    \param  tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters
    \- return VOS_STATUS_SUCCES
    -------------------------------------------------------------------------*/
VOS_STATUS sme_SendTdlsLinkEstablishParams(tHalHandle hHal,
                                           tANI_U8 sessionId,
                                           const tSirMacAddr peerMac,
                                           tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                   TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM,
                   sessionId, tdlsLinkEstablishParams->isOffChannelSupported));
    status = sme_AcquireGlobalLock( &pMac->sme );

    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrTdlsSendLinkEstablishParams(hHal, sessionId, peerMac, tdlsLinkEstablishParams) ;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
   return status ;
}

/* ---------------------------------------------------------------------------
    \fn sme_SendTdlsMgmtFrame
    \brief  API to send TDLS management frames.

    \param  peerMac - peer's Mac Address.
    \param frame_type - Type of TDLS mgmt frame to be sent.
    \param dialog - dialog token used in the frame.
    \param status - status to be included in the frame.
    \param peerCapability - peer capabilities
    \param buf - additional IEs to be included
    \param len - length of additional Ies
    \param responder - Tdls request type
    \- return VOS_STATUS_SUCCES
    -------------------------------------------------------------------------*/
VOS_STATUS sme_SendTdlsMgmtFrame(tHalHandle hHal, tANI_U8 sessionId,
                                 const tSirMacAddr peerMac, tANI_U8 frame_type,
                                 tANI_U8 dialog, tANI_U16 statusCode,
                                 tANI_U32 peerCapability, tANI_U8 *buf,
                                 tANI_U8 len, tANI_U8 responder)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tCsrTdlsSendMgmt sendTdlsReq = {{0}} ;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME,
                     sessionId, statusCode));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        vos_mem_copy(sendTdlsReq.peerMac, peerMac, sizeof(tSirMacAddr)) ;
        sendTdlsReq.frameType = frame_type;
        sendTdlsReq.buf = buf;
        sendTdlsReq.len = len;
        sendTdlsReq.dialog = dialog;
        sendTdlsReq.statusCode = statusCode;
        sendTdlsReq.responder = responder;
        sendTdlsReq.peerCapability = peerCapability;

        status = csrTdlsSendMgmtReq(hHal, sessionId, &sendTdlsReq) ;

        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;

}
/* ---------------------------------------------------------------------------
    \fn sme_ChangeTdlsPeerSta
    \brief  API to Update TDLS peer sta parameters.

    \param  peerMac - peer's Mac Address.
    \param  staParams - Peer Station Parameters
    \- return VOS_STATUS_SUCCES
    -------------------------------------------------------------------------*/
VOS_STATUS sme_ChangeTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId,
                                 const tSirMacAddr peerMac,
                                 tCsrStaParams *pstaParams)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    if (NULL == pstaParams)
    {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s :pstaParams is NULL",__func__);
        return eHAL_STATUS_FAILURE;
    }
    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA, sessionId,
                     pstaParams->capability));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrTdlsChangePeerSta(hHal, sessionId, peerMac, pstaParams);

        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;

}

/* ---------------------------------------------------------------------------
    \fn sme_AddTdlsPeerSta
    \brief  API to Add TDLS peer sta entry.

    \param  peerMac - peer's Mac Address.
    \- return VOS_STATUS_SUCCES
    -------------------------------------------------------------------------*/
VOS_STATUS sme_AddTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId,
                              const tSirMacAddr peerMac)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA,
                     sessionId, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrTdlsAddPeerSta(hHal, sessionId, peerMac);

        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;

}
/* ---------------------------------------------------------------------------
    \fn sme_DeleteTdlsPeerSta
    \brief  API to Delete TDLS peer sta entry.

    \param  peerMac - peer's Mac Address.
    \- return VOS_STATUS_SUCCES
    -------------------------------------------------------------------------*/
VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal,
                                 tANI_U8 sessionId,
                                 const tSirMacAddr peerMac)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA,
                     sessionId, 0));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrTdlsDelPeerSta(hHal, sessionId, peerMac) ;
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;

}
/* ---------------------------------------------------------------------------
    \fn sme_SetTdlsPowerSaveProhibited
    \API to set/reset the isTdlsPowerSaveProhibited.

    \- return void
    -------------------------------------------------------------------------*/
void sme_SetTdlsPowerSaveProhibited(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t val)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    if (!pMac->psOffloadEnabled)
    {
        pMac->isTdlsPowerSaveProhibited = val;
    }
    else
    {
        pmcOffloadSetTdlsProhibitBmpsStatus(hHal, sessionId, val);
    }
    smsLog(pMac, LOG1, FL("isTdlsPowerSaveProhibited is %d"),
                   pMac->isTdlsPowerSaveProhibited);
    return;
}

/* ---------------------------------------------------------------------------
  \fn    sme_UpdateFwTdlsState

  \brief
    SME will send message to WMA to set TDLS state in f/w

  \param

    hHal - The handle returned by macOpen

    psmeTdlsParams - TDLS state info to update in f/w

    useSmeLock - Need to acquire SME Global Lock before state update or not

  \return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_UpdateFwTdlsState(tHalHandle hHal, void  *psmeTdlsParams,
                                 tANI_BOOLEAN useSmeLock)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = NULL;
    vos_msg_t vosMessage;

    pMac = PMAC_STRUCT(hHal);
    if (NULL == pMac) {
        return eHAL_STATUS_FAILURE;
    }

    /* only acquire sme global lock before state update if asked to */
    if (useSmeLock) {
        status = sme_AcquireGlobalLock(&pMac->sme);
        if (eHAL_STATUS_SUCCESS != status)
            return status;
    }

    /* serialize the req through MC thread */
    vosMessage.bodyptr = psmeTdlsParams;
    vosMessage.type    = WDA_UPDATE_FW_TDLS_STATE;
    vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
    if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        status = eHAL_STATUS_FAILURE;

    /* release the lock if it was acquired */
    if (useSmeLock)
        sme_ReleaseGlobalLock(&pMac->sme);

    return(status);
}

/* ---------------------------------------------------------------------------
  \fn    sme_UpdateTdlsPeerState

  \brief
    SME will send message to WMA to set TDLS Peer state in f/w

  \param

    hHal - The handle returned by macOpen

    peerStateParams - TDLS Peer state info to update in f/w

  \return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal,
                                   tSmeTdlsPeerStateParams *peerStateParams)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tTdlsPeerStateParams *pTdlsPeerStateParams = NULL;
    vos_msg_t vosMessage;
    tANI_U8 num;
    tANI_U8 chanId;
    tANI_U8 i;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
    {
        pTdlsPeerStateParams = vos_mem_malloc(sizeof(*pTdlsPeerStateParams));
        if (NULL == pTdlsPeerStateParams)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: failed to allocate mem for tdls peer state param",
                      __func__);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        vos_mem_zero(pTdlsPeerStateParams, sizeof(*pTdlsPeerStateParams));
        vos_mem_copy(&pTdlsPeerStateParams->peerMacAddr,
                     &peerStateParams->peerMacAddr,
                     sizeof(tSirMacAddr));
        pTdlsPeerStateParams->vdevId = peerStateParams->vdevId;
        pTdlsPeerStateParams->peerState = peerStateParams->peerState;

        switch (peerStateParams->peerState)
        {
           case eSME_TDLS_PEER_STATE_PEERING:
              pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_STATE_PEERING;
              break;

           case eSME_TDLS_PEER_STATE_CONNECTED:
              pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_STATE_CONNECTED;
              break;

           case eSME_TDLS_PEER_STATE_TEARDOWN:
              pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_STATE_TEARDOWN;
              break;

           case eSME_TDLS_PEER_ADD_MAC_ADDR:
              pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_ADD_MAC_ADDR;
              break;

           case eSME_TDLS_PEER_REMOVE_MAC_ADDR:
              pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_REMOVE_MAC_ADDR;
              break;

           default:
              VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s: invalid peer state param (%d)",
                        __func__, peerStateParams->peerState);
              vos_mem_free(pTdlsPeerStateParams);
              sme_ReleaseGlobalLock(&pMac->sme);
              return eHAL_STATUS_FAILURE;
       }

       pTdlsPeerStateParams->peerCap.isPeerResponder =
           peerStateParams->peerCap.isPeerResponder;
       pTdlsPeerStateParams->peerCap.peerUapsdQueue =
           peerStateParams->peerCap.peerUapsdQueue;
       pTdlsPeerStateParams->peerCap.peerMaxSp =
           peerStateParams->peerCap.peerMaxSp;
       pTdlsPeerStateParams->peerCap.peerBuffStaSupport =
           peerStateParams->peerCap.peerBuffStaSupport;
       pTdlsPeerStateParams->peerCap.peerOffChanSupport =
           peerStateParams->peerCap.peerOffChanSupport;
       pTdlsPeerStateParams->peerCap.peerCurrOperClass =
           peerStateParams->peerCap.peerCurrOperClass;
       pTdlsPeerStateParams->peerCap.selfCurrOperClass =
           peerStateParams->peerCap.selfCurrOperClass;

       num = 0;
       for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++)
       {
           chanId = peerStateParams->peerCap.peerChan[i];
           if (csrRoamIsChannelValid(pMac, chanId))
           {
               pTdlsPeerStateParams->peerCap.peerChan[num].chanId = chanId;
               pTdlsPeerStateParams->peerCap.peerChan[num].pwr =
                                         csrGetCfgMaxTxPower(pMac, chanId);

               if (vos_nv_getChannelEnabledState(chanId) == NV_CHANNEL_DFS)
                   continue;
               else
               {
                   pTdlsPeerStateParams->peerCap.peerChan[num].dfsSet =
                                                                  VOS_FALSE;
               }

               if (vos_nv_skip_dsrc_dfs_2g(chanId, NV_CHANNEL_SKIP_DSRC))
                   continue;

               num++;
           }
       }
       pTdlsPeerStateParams->peerCap.peerChanLen = num;

       pTdlsPeerStateParams->peerCap.peerOperClassLen =
           peerStateParams->peerCap.peerOperClassLen;
       for (i = 0; i < HAL_TDLS_MAX_SUPP_OPER_CLASSES; i++)
       {
           pTdlsPeerStateParams->peerCap.peerOperClass[i] =
               peerStateParams->peerCap.peerOperClass[i];
       }

       pTdlsPeerStateParams->peerCap.prefOffChanNum =
           peerStateParams->peerCap.prefOffChanNum;
       pTdlsPeerStateParams->peerCap.prefOffChanBandwidth =
           peerStateParams->peerCap.prefOffChanBandwidth;
       pTdlsPeerStateParams->peerCap.opClassForPrefOffChan =
           peerStateParams->peerCap.opClassForPrefOffChan;

       vosMessage.type = WDA_UPDATE_TDLS_PEER_STATE;
       vosMessage.reserved = 0;
       vosMessage.bodyptr = pTdlsPeerStateParams;

       vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
       if (!VOS_IS_STATUS_SUCCESS(vosStatus))
       {
          vos_mem_free(pTdlsPeerStateParams);
          status = eHAL_STATUS_FAILURE;
       }

       sme_ReleaseGlobalLock(&pMac->sme);
    }
    return(status);
}

/* ---------------------------------------------------------------------------
    \fn sme_SendTdlsChanSwitchReq
    \brief  API to send TDLS channel switch parameters to WMA.

    \param  hHal - Umac handle.
    \param  chanSwitchParams-  vdev, channel, offset, mode, peerMac
    \- return VOS_STATUS_SUCCES
    -------------------------------------------------------------------------*/
eHalStatus sme_SendTdlsChanSwitchReq(tHalHandle hHal,
                                     tSmeTdlsChanSwitchParams *chanSwitchParams)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tTdlsChanSwitchParams *pTdlsChanSwitchParams = NULL;
    vos_msg_t vosMessage;

    MTRACE(vos_trace(VOS_MODULE_ID_SME,
                     TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ, NO_SESSION,
                     chanSwitchParams->tdls_off_channel));
    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        pTdlsChanSwitchParams = vos_mem_malloc(sizeof(*pTdlsChanSwitchParams));
        if (NULL == pTdlsChanSwitchParams)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      FL("failed to allocate mem for tdls chan switch param"));
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }
        vos_mem_zero(pTdlsChanSwitchParams, sizeof(*pTdlsChanSwitchParams));

        switch (chanSwitchParams->tdls_off_ch_mode)
        {
            case ENABLE_CHANSWITCH:
                pTdlsChanSwitchParams->tdlsSwMode =
                                       WDA_TDLS_ENABLE_OFFCHANNEL;
                break;

            case DISABLE_CHANSWITCH:
                pTdlsChanSwitchParams->tdlsSwMode =
                                       WDA_TDLS_DISABLE_OFFCHANNEL;
                break;

            default:
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("invalid off channel command (%d)"),
                          chanSwitchParams->tdls_off_ch_mode);
                vos_mem_free(pTdlsChanSwitchParams);
                sme_ReleaseGlobalLock(&pMac->sme);
                return eHAL_STATUS_FAILURE;
        }

        vos_mem_copy(&pTdlsChanSwitchParams->peerMacAddr,
                     &chanSwitchParams->peer_mac_addr,
                     sizeof(tSirMacAddr));
        pTdlsChanSwitchParams->vdevId =
             chanSwitchParams->vdev_id;
        pTdlsChanSwitchParams->tdlsOffCh =
             chanSwitchParams->tdls_off_channel;
        pTdlsChanSwitchParams->tdlsOffChBwOffset =
             chanSwitchParams->tdls_off_ch_bw_offset;
        pTdlsChanSwitchParams->is_responder=
             chanSwitchParams->is_responder;
        pTdlsChanSwitchParams->operClass = chanSwitchParams->opclass;

        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                  FL("Country Code=%s, Requested offset=%d, Selected Operating Class=%d"),
                  pMac->scan.countryCodeCurrent,
                  pTdlsChanSwitchParams->tdlsOffChBwOffset,
                  pTdlsChanSwitchParams->operClass);

        vosMessage.type = WDA_TDLS_SET_OFFCHAN_MODE;
        vosMessage.reserved = 0;
        vosMessage.bodyptr = pTdlsChanSwitchParams;

        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      FL("Message Post failed status=%d"), vosStatus);
            vos_mem_free(pTdlsChanSwitchParams);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return(status);
}
#endif /* FEATURE_WLAN_TDLS */

eHalStatus sme_GetLinkSpeed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq, void *plsContext,
                            void (*pCallbackfn)(tSirLinkSpeedInfo *indParam, void *pContext) )
{

    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
    vos_msg_t           vosMessage;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        if ( (NULL == pCallbackfn) &&
            (NULL == pMac->sme.pLinkSpeedIndCb))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Indication Call back did not registered", __func__);
           sme_ReleaseGlobalLock(&pMac->sme);
           return eHAL_STATUS_FAILURE;
        }
        else if (NULL != pCallbackfn)
        {
           pMac->sme.pLinkSpeedCbContext = plsContext;
           pMac->sme.pLinkSpeedIndCb = pCallbackfn;
        }
        /* serialize the req through MC thread */
        vosMessage.bodyptr = vos_mem_malloc(sizeof(*lsReq));
        if (NULL == vosMessage.bodyptr) {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Memory allocation failed.", __func__);
                     sme_ReleaseGlobalLock(&pMac->sme);
           return eHAL_STATUS_E_MALLOC_FAILED;
        }
        vos_mem_copy(vosMessage.bodyptr, lsReq, sizeof(*lsReq));
        vosMessage.type    = WDA_GET_LINK_SPEED;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Post Link Speed msg fail", __func__);
           vos_mem_free(vosMessage.bodyptr);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return(status);
}


/**
 * sme_get_peer_info() - get station's info
 * @hal: hal interface
 * @req: get peer info request information
 * @context: event handle context
 * @pcallbackfn: callback function pointer
 *
 * This function will send WDA_GET_PEER_INFO to WMA
 *
 * Return: 0 on success, otherwise error value
 */
eHalStatus sme_get_peer_info(tHalHandle hal, struct sir_peer_info_req req,
			void *context,
			void (*callbackfn)(struct sir_peer_info_resp *param,
						void *pcontext))
{

	eHalStatus          status    = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vosstatus = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac       = PMAC_STRUCT(hal);
	vos_msg_t           vosmessage;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		if (NULL == callbackfn) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Indication Call back is NULL",
				__func__);
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_FAILURE;
		}

		mac->sme.pget_peer_info_ind_cb = callbackfn;
		mac->sme.pget_peer_info_cb_context = context;

		/* serialize the req through MC thread */
		vosmessage.bodyptr = vos_mem_malloc(sizeof(req));
		if (NULL == vosmessage.bodyptr) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Memory allocation failed.", __func__);
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_E_MALLOC_FAILED;
		}
		vos_mem_copy(vosmessage.bodyptr, &req, sizeof(req));
		vosmessage.type    = WDA_GET_PEER_INFO;
		vosstatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosmessage);
		if (!VOS_IS_STATUS_SUCCESS(vosstatus)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Post get peer info msg fail", __func__);
			vos_mem_free(vosmessage.bodyptr);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
	}
	return status;
}

/**
 * sme_get_peer_info_ext() - get info for remote peer
 * @hal: hal interface
 * @req: get peer info request pointer
 * @context: event handle context
 * @callbackfn: callback function pointer
 *
 * This function will send WDA_GET_PEER_INFO_EXT to WMA
 *
 * Return: 0 on success, otherwise error value
 */
eHalStatus sme_get_peer_info_ext(tHalHandle hal,
		struct sir_peer_info_ext_req *req,
		void *context,
		void (*callbackfn)(struct sir_peer_info_ext_resp *param,
			void *pcontext))
{

	eHalStatus          status    = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vosstatus = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac       = PMAC_STRUCT(hal);
	vos_msg_t           vosmessage;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		if (NULL == callbackfn) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Indication Call back is NULL",
				__func__);
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_FAILURE;
		}

		mac->sme.pget_peer_info_ext_ind_cb = callbackfn;
		mac->sme.pget_peer_info_ext_cb_context = context;

		/* serialize the req through MC thread */
		vosmessage.bodyptr =
			vos_mem_malloc(sizeof(struct sir_peer_info_ext_req));
		if (NULL == vosmessage.bodyptr) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Memory allocation failed.", __func__);
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_E_MALLOC_FAILED;
		}
		vos_mem_copy(vosmessage.bodyptr,
				req,
				sizeof(struct sir_peer_info_ext_req));
		vosmessage.type    = WDA_GET_PEER_INFO_EXT;
		vosstatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosmessage);
		if (!VOS_IS_STATUS_SUCCESS(vosstatus)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Post get rssi msg fail", __func__);
			vos_mem_free(vosmessage.bodyptr);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
	}
	return status;
}

eHalStatus sme_get_isolation(tHalHandle hal,
           void *context,
           void (*callbackfn)(struct sir_isolation_resp *param,
                       void *pcontext))
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosstatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      mac       = PMAC_STRUCT(hal);
    vos_msg_t           vosmessage;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            "%s: get isolation", __func__);

    status = sme_AcquireGlobalLock(&mac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        if (NULL == callbackfn) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                    "%s: Indication Call back is NULL",
                    __func__);
            sme_ReleaseGlobalLock(&mac->sme);
            return eHAL_STATUS_FAILURE;
        }

        mac->sme.get_isolation = callbackfn;
        mac->sme.get_isolation_cb_context = context;

        vosmessage.bodyptr = NULL;
        vosmessage.type    = WDA_GET_ISOLATION;
        vosstatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosmessage);
        if (!VOS_IS_STATUS_SUCCESS(vosstatus)) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                    "%s: Post get isolation msg fail", __func__);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&mac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_IsPmcBmps
    \API to Check if PMC state is BMPS.

    \- return v_BOOL_t
    -------------------------------------------------------------------------*/
v_BOOL_t sme_IsPmcBmps(tHalHandle hHal)
{
    return (BMPS == pmcGetPmcState(hHal));
}


eHalStatus sme_UpdateDfsSetting(tHalHandle hHal, tANI_U8 fUpdateEnableDFSChnlScan)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    smsLog(pMac, LOG2, FL("enter"));
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pMac->scan.fEnableDFSChnlScan = fUpdateEnableDFSChnlScan;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    smsLog(pMac, LOG2, FL("exit status %d"), status);

    return (status);
}

/*
 * SME API to enable/disable WLAN driver initiated SSR
 */
void sme_UpdateEnableSSR(tHalHandle hHal, tANI_BOOLEAN enableSSR)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus     status = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (HAL_STATUS_SUCCESS(status))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "SSR level is changed %d", enableSSR);
       /* not serializing this message, as this is only going
        * to set a variable in WDA/WDI
        */
        WDA_SetEnableSSR(enableSSR);
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return;
}

/*
 * SME API to stringify bonding mode. (hostapd convention)
 */

static const char* sme_CBMode2String( tANI_U32 mode)
{
   switch (mode)
   {
      case eCSR_INI_SINGLE_CHANNEL_CENTERED:
         return "HT20";
      case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
         return "HT40-"; /* lower secondary channel */
      case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
         return "HT40+"; /* upper secondary channel */
#ifdef WLAN_FEATURE_11AC
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
         return "VHT80+40+"; /* upper secondary channels */
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
         return "VHT80+40-"; /* 1 lower and 2 upper secondary channels */
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
         return "VHT80-40+"; /* 2 lower and 1 upper secondary channels */
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
         return "VHT80-40-"; /* lower secondary channels */
#endif
      default:
         VOS_ASSERT(0);
         return "Unknown";
   }
}

/*
 * SME API to adjust bonding mode to regulatory, dfs nol .. etc.
 *
 */
static VOS_STATUS sme_AdjustCBMode(tAniSirGlobal* pMac,
      tSmeConfigParams  *smeConfig,
      uint8_t channel, uint16_t *vht_channel_width)
{

   const tANI_U8 step = 4;
   tANI_U8 i, startChan = channel, chanCnt = 0, chanBitmap = 0;
   tANI_BOOLEAN violation = VOS_FALSE;
   tANI_U32 newMode, mode;
   tANI_U8 center_chan = channel;
   /* to validate 40MHz channels against the regulatory domain */
   tANI_BOOLEAN ht40_phymode = VOS_FALSE;

   /* get the bonding mode */
   mode = (channel <= 14) ? smeConfig->csrConfig.channelBondingMode24GHz :
                        smeConfig->csrConfig.channelBondingMode5GHz;
   newMode = mode;

   /* get the channels */
   switch (mode)
   {
      case eCSR_INI_SINGLE_CHANNEL_CENTERED:
         startChan = channel;
         chanCnt = 1;
         break;
      case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
         startChan = channel - step;
         chanCnt = 2;
         center_chan = channel - CSR_CB_CENTER_CHANNEL_OFFSET;
         ht40_phymode = VOS_TRUE;
         break;
      case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
         startChan = channel;
         chanCnt=2;
         center_chan = channel + CSR_CB_CENTER_CHANNEL_OFFSET;
         ht40_phymode = VOS_TRUE;
         break;
#ifdef WLAN_FEATURE_11AC
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
         startChan = channel;
         chanCnt = 4;
         break;
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
         startChan = channel - step;
         chanCnt = 4;
         break;
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
         startChan = channel - 2*step;
         chanCnt = 4;
         break;
      case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
         startChan = channel - 3*step;
         chanCnt = 4;
         break;
#endif
      default:
         VOS_ASSERT(0);
         return VOS_STATUS_E_FAILURE;
   }

   /* find violation; also map valid channels to a bitmap */
   for (i = 0; i < chanCnt; i++) {
      if (csrIsValidChannel(pMac, (startChan + (i * step))) ==
            VOS_STATUS_SUCCESS)
         chanBitmap = chanBitmap | 1 << i;
      else
         violation = VOS_TRUE;
   }

   /* validate if 40MHz channel is allowed */
   if (ht40_phymode) {
       if (!csrRoamIsValid40MhzChannel(pMac, center_chan))
          violation = VOS_TRUE;
   }

   /* no channels are valid */
   if (chanBitmap == 0)
   {
      /* never be in this case */
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("channel %d %s is not supported"),
            channel,
            sme_CBMode2String(mode));
      return VOS_STATUS_E_INVAL;
   }

   /* fix violation */
   if (violation)
   {
      const tANI_U8 lowerMask = 0x03, upperMask = 0x0c;
      /* fall back to single channel in all exception cases */
      newMode = eCSR_INI_SINGLE_CHANNEL_CENTERED;

      switch (mode)
      {
         case eCSR_INI_SINGLE_CHANNEL_CENTERED:
            /* fall thru */
         case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
            /* fall thru */
         case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
            break;
#ifdef WLAN_FEATURE_11AC
         case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
            if ((chanBitmap & lowerMask) == lowerMask)
               newMode = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
            break;
         case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
            if ((chanBitmap & lowerMask) == lowerMask)
               newMode = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
            break;
         case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
            if ((chanBitmap & upperMask) == upperMask)
               newMode = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
            break;
         case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
            if ((chanBitmap & upperMask) == upperMask)
               newMode = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
            break;
#endif
         default:
            return VOS_STATUS_E_NOSUPPORT;
            break;
      }

      if (eCSR_INI_SINGLE_CHANNEL_CENTERED == newMode) {
          *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;
      } else {
          *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ;
      }

      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
            FL("bonding mode adjust: %s to %s"),
            sme_CBMode2String(mode),
            sme_CBMode2String(newMode));
   }

   /* check for mode change */
   if (newMode != mode)
   {
      if (channel <= 14)
          smeConfig->csrConfig.channelBondingMode24GHz = newMode;
      else
          smeConfig->csrConfig.channelBondingMode5GHz = newMode;
   }

   return VOS_STATUS_SUCCESS;

}

/*
 * SME API to determine the channel bonding mode
 */
eIniChanBondState sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode,
                            uint8_t channel, uint8_t ht_sec_ch,
                            uint16_t *vht_channel_width,
                            uint16_t ch_width_orig)
{
   tSmeConfigParams  smeConfig;
   tANI_U32 ht40plus2gendch = 0;
   tpAniSirGlobal    pMac = PMAC_STRUCT(hHal);
   eIniChanBondState cb_mode = eCSR_INI_SINGLE_CHANNEL_CENTERED;
   /* Donot check pMac->roam.configParam.channelBondingMode5GHz / 24GHz
    * Doing so results in circular reference
    */
   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: HW: %d CH: %d ORIG_BW: %d\n", __func__, eCsrPhyMode,
                channel, ch_width_orig);

   *vht_channel_width = ch_width_orig;
   vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
   sme_GetConfigParam(pMac, &smeConfig);

   if ((eCSR_DOT11_MODE_11ac == eCsrPhyMode ||
        eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode) &&
        (eHT_CHANNEL_WIDTH_80MHZ == ch_width_orig)) {
      if (channel== 36 || channel == 52 || channel == 100 ||
                channel == 116 || channel == 149 || channel == 132) {
          smeConfig.csrConfig.channelBondingMode5GHz =
                eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
      } else if (channel == 40 || channel == 56 || channel == 104 ||
                     channel == 120 || channel == 153 || channel == 136) {
          smeConfig.csrConfig.channelBondingMode5GHz =
                eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
      } else if (channel == 44 || channel == 60 || channel == 108 ||
                     channel == 124 || channel == 157 || channel == 140) {
          smeConfig.csrConfig.channelBondingMode5GHz =
                eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
      } else if (channel == 48 || channel == 64 || channel == 112 ||
                     channel == 128 || channel == 144 || channel == 161) {
          smeConfig.csrConfig.channelBondingMode5GHz =
                eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
      } else if (channel == 165) {
          smeConfig.csrConfig.channelBondingMode5GHz =
                                     eCSR_INI_SINGLE_CHANNEL_CENTERED;
          *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;
      } else if (channel >= 1 && channel < 5) {
          smeConfig.csrConfig.channelBondingMode24GHz =
                eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
          *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ;
      } else if (channel >= 5 && channel <= 9) {
          if (0 != ht_sec_ch) {
              if (ht_sec_ch > channel)
                  smeConfig.csrConfig.channelBondingMode24GHz =
                        eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
              else
                  smeConfig.csrConfig.channelBondingMode24GHz =
                        eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
	  }
          *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ;
      } else if (channel > 9 && channel <= 13) {
          smeConfig.csrConfig.channelBondingMode24GHz =
                eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
          *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ;
      } else if (channel ==14) {
          smeConfig.csrConfig.channelBondingMode24GHz =
                eCSR_INI_SINGLE_CHANNEL_CENTERED;
          *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;
      }
   } else if ((eCSR_DOT11_MODE_11n == eCsrPhyMode ||
        eCSR_DOT11_MODE_11n_ONLY == eCsrPhyMode ||
        eCSR_DOT11_MODE_11ac == eCsrPhyMode ||
        eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode) &&
        (eHT_CHANNEL_WIDTH_40MHZ == ch_width_orig)) {
       if (vos_is_fcc_regdomain())
           ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
       else
           ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
       if (channel== 40 || channel == 48 || channel == 56 ||
                channel == 64 || channel == 104 || channel == 112 ||
                channel == 120 || channel == 128 || channel == 136 ||
                channel == 153 || channel == 161 || channel == 144) {
           smeConfig.csrConfig.channelBondingMode5GHz =
                                    eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
       } else if (channel== 36 || channel == 44 || channel == 52 ||
                channel == 60 || channel == 100 || channel == 108 ||
                channel == 116 || channel == 124 || channel == 132 ||
                channel == 149 || channel == 157 || channel == 140) {
           smeConfig.csrConfig.channelBondingMode5GHz =
                                        eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
       } else if (channel == 165) {
           smeConfig.csrConfig.channelBondingMode5GHz =
                                            eCSR_INI_SINGLE_CHANNEL_CENTERED;
           *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;
       } else if (channel >= 1 && channel < 5) {
           smeConfig.csrConfig.channelBondingMode24GHz =
                                           eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
       } else if (channel >= 5 && channel <= ht40plus2gendch) {
          if (ht_sec_ch > channel)
              smeConfig.csrConfig.channelBondingMode24GHz =
                    eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
          else
              smeConfig.csrConfig.channelBondingMode24GHz =
                    eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
       } else if (channel > ht40plus2gendch && channel <= 13) {
           smeConfig.csrConfig.channelBondingMode24GHz =
                                           eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
       } else if (channel ==14) {
           smeConfig.csrConfig.channelBondingMode24GHz =
              eCSR_INI_SINGLE_CHANNEL_CENTERED;
           *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;
       }
   } else {
       *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ;
       if (channel <= 14) {
           smeConfig.csrConfig.channelBondingMode24GHz =
                            eCSR_INI_SINGLE_CHANNEL_CENTERED;
       } else {
           smeConfig.csrConfig.channelBondingMode5GHz =
                            eCSR_INI_SINGLE_CHANNEL_CENTERED;
       }
   }

   sme_AdjustCBMode(pMac, &smeConfig, channel, vht_channel_width);
   sme_UpdateConfig (pMac, &smeConfig);
   cb_mode = (channel <= 14) ? smeConfig.csrConfig.channelBondingMode24GHz :
                        smeConfig.csrConfig.channelBondingMode5GHz;
   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
         "%s: CH: %d NEW_BW: %d %s-CB_Mode:%d", __func__, channel,
         *vht_channel_width, (channel <=14) ? "2G" : "5G", cb_mode);

   return cb_mode;
}

/*convert the ini value to the ENUM used in csr and MAC for CB state*/
ePhyChanBondState sme_GetCBPhyStateFromCBIniValue(tANI_U32 cb_ini_value)
{
   return(csrConvertCBIniValueToPhyCBState(cb_ini_value));
}
/*--------------------------------------------------------------------------

  \brief sme_SetCurrDeviceMode() - Sets the current operating device mode.
  \param hHal - The handle returned by macOpen.
  \param currDeviceMode - Current operating device mode.
  --------------------------------------------------------------------------*/

void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    pMac->sme.currDeviceMode = currDeviceMode;
    return;
}

/**
 * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req
 *
 * @hal: Pointer to HAL
 * @enable2x2: 1x1 or 2x2 mode.
 *
 * Sends the set pdev IE req with Nss value.
 *
 * Return: None
 */
void sme_set_pdev_ht_vht_ies(tHalHandle hal, bool enable2x2)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_set_ht_vht_cfg *ht_vht_cfg;
	eHalStatus status = eHAL_STATUS_FAILURE;

	if (!mac_ctx->per_band_chainmask_supp)
		return;

	if (!((mac_ctx->roam.configParam.uCfgDot11Mode ==
					eCSR_CFG_DOT11_MODE_AUTO) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11N) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11N_ONLY) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11AC) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11AC_ONLY)))
		return;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		ht_vht_cfg = vos_mem_malloc(sizeof(*ht_vht_cfg));
		if (NULL == ht_vht_cfg) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
					"%s: mem alloc failed for ht_vht_cfg",
					__func__);
			sme_ReleaseGlobalLock(&mac_ctx->sme);
			return;
		}

		ht_vht_cfg->pdev_id = 0;
		if (enable2x2)
			ht_vht_cfg->nss = 2;
		else
			ht_vht_cfg->nss = 1;
		ht_vht_cfg->dot11mode =
			(tANI_U8)csrTranslateToWNICfgDot11Mode(mac_ctx,
				mac_ctx->roam.configParam.uCfgDot11Mode);

		ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE;
		ht_vht_cfg->len = sizeof(*ht_vht_cfg);
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
				"%s: send PDEV_SET_HT_VHT_IE with nss - %d, dot11mode - %d",
				__func__, ht_vht_cfg->nss, ht_vht_cfg->dot11mode);
		status = palSendMBMessage(mac_ctx->hHdd, ht_vht_cfg);
		if (eHAL_STATUS_SUCCESS != status) {
			smsLog(mac_ctx, LOGE, FL(
				"SME_PDEV_SET_HT_VHT_IE msg to PE failed"));
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}
	return;
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/*--------------------------------------------------------------------------
  \brief sme_HandoffRequest() - a wrapper function to Request a handoff
  from CSR.
  This is a synchronous call
  \param hHal - The handle returned by macOpen
  \param  sessionId - Session Identifier
  \param pHandoffInfo - info provided by HDD with the handoff request (namely:
  BSSID, channel etc.)
  \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully.
          Other status means SME is failed to send the request.
  \sa
  --------------------------------------------------------------------------*/

eHalStatus sme_HandoffRequest(tHalHandle hHal,
                              tANI_U8 sessionId,
                              tCsrHandoffRequest *pHandoffInfo)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: invoked", __func__);
        status = csrHandoffRequest(pMac, sessionId, pHandoffInfo);
        sme_ReleaseGlobalLock( &pMac->sme );
    }

    return status ;
}

#ifdef IPA_UC_OFFLOAD
/* ---------------------------------------------------------------------------
    \fn sme_ipa_offload_enable_disable
    \brief  API to enable/disable IPA offload
    \param  hal - The handle returned by macOpen.
    \param  session_id - Session Identifier
    \param  request -  Pointer to the offload request.
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_ipa_offload_enable_disable(tHalHandle hal, tANI_U8 session_id,
                                struct sir_ipa_offload_enable_disable *request)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hal );
    eHalStatus status = eHAL_STATUS_FAILURE;
    struct sir_ipa_offload_enable_disable *request_buf;
    vos_msg_t msg;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        request_buf = vos_mem_malloc(sizeof(*request_buf));
        if (NULL == request_buf)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
               "%s: Not able to allocate memory for IPA_OFFLOAD_ENABLE_DISABLE",
               __func__);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILED_ALLOC;
        }

        request_buf->offload_type = request->offload_type;
        request_buf->vdev_id = request->vdev_id;
        request_buf->enable = request->enable;

        msg.type     = WDA_IPA_OFFLOAD_ENABLE_DISABLE;
        msg.reserved = 0;
        msg.bodyptr  = request_buf;
        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: Not able to post WDA_IPA_OFFLOAD_ENABLE_DISABLE message to WDA",
                      __func__);
            vos_mem_free(request_buf);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return eHAL_STATUS_SUCCESS;
}
#endif

#endif

/*
 * SME API to check if there is any infra station or
 * P2P client is connected
 */
VOS_STATUS sme_isSta_p2p_clientConnected(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    if(csrIsInfraConnected(pMac))
    {
        return VOS_STATUS_SUCCESS;
    }
    return VOS_STATUS_E_FAILURE;
}


#ifdef FEATURE_WLAN_LPHB
/* ---------------------------------------------------------------------------
    \fn sme_LPHBConfigReq
    \API to make configuration LPHB within FW.
    \param hHal - The handle returned by macOpen
    \param lphdReq - LPHB request argument by client
    \param pCallbackfn - LPHB timeout notification callback function pointer
    \- return Configuration message posting status, SUCCESS or Fail
    -------------------------------------------------------------------------*/
eHalStatus sme_LPHBConfigReq
(
   tHalHandle hHal,
   tSirLPHBReq *lphdReq,
   void (*pCallbackfn)(void *pHddCtx, tSirLPHBInd *indParam)
)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
    vos_msg_t           vosMessage;

    MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ,
                                       NO_SESSION, lphdReq->cmd));
    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) &&
            (NULL == pCallbackfn) &&
            (NULL == pMac->sme.pLphbIndCb))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Indication Call back did not registered", __func__);
           sme_ReleaseGlobalLock(&pMac->sme);
           return eHAL_STATUS_FAILURE;
        }
        else if (NULL != pCallbackfn)
        {
           pMac->sme.pLphbIndCb = pCallbackfn;
        }

        /* serialize the req through MC thread */
        vosMessage.bodyptr = lphdReq;
        vosMessage.type    = WDA_LPHB_CONF_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Post Config LPHB MSG fail", __func__);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

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

/**
 * sme_AddPeriodicTxPtrn() - Add Periodic TX Pattern
 * @hal: global hal handle
 * @addPeriodicTxPtrnParams: request message
 *
 * Return: eHalStatus enumeration
 */
eHalStatus
sme_AddPeriodicTxPtrn(tHalHandle hal,
		      struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams)
{
	eHalStatus status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	struct sSirAddPeriodicTxPtrn *req_msg;
	vos_msg_t msg;

	smsLog(mac, LOG1, FL("enter"));

	req_msg = vos_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		smsLog(mac, LOGE, FL("vos_mem_malloc failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*req_msg = *addPeriodicTxPtrnParams;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	msg.bodyptr = req_msg;
	msg.type    = WDA_ADD_PERIODIC_TX_PTRN_IND;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                        NO_SESSION, msg.type));
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		vos_mem_free(req_msg);
		status = eHAL_STATUS_FAILURE;
	}
	sme_ReleaseGlobalLock(&mac->sme);
	return status;
}

/**
 * sme_DelPeriodicTxPtrn() - Delete Periodic TX Pattern
 * @hal: global hal handle
 * @delPeriodicTxPtrnParams: request message
 *
 * Return: eHalStatus enumeration
 */
eHalStatus
sme_DelPeriodicTxPtrn(tHalHandle hal,
		      struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams)
{
	eHalStatus status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	struct sSirDelPeriodicTxPtrn *req_msg;
	vos_msg_t msg;

	smsLog(mac, LOG1, FL("enter"));

	req_msg = vos_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		smsLog(mac, LOGE, FL("vos_mem_malloc failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*req_msg = *delPeriodicTxPtrnParams;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	msg.bodyptr = req_msg;
	msg.type    = WDA_DEL_PERIODIC_TX_PTRN_IND;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                        NO_SESSION, msg.type));
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		vos_mem_free(req_msg);
		status = eHAL_STATUS_FAILURE;
	}
	sme_ReleaseGlobalLock(&mac->sme);
	return status;
}

/**
 * sme_enable_rmc() - enable RMC
 * @hHal: handle
 * @sessionId: session id
 *
 * @Return: eHalStatus
 */
eHalStatus sme_enable_rmc(tHalHandle hHal, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    vos_msg_t vosMessage;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;

    smsLog(pMac, LOG1, FL("enable RMC"));
    status = sme_AcquireGlobalLock(&pMac->sme);
    if (HAL_STATUS_SUCCESS(status))
    {
        vosMessage.bodyptr = NULL;
        vosMessage.type = WDA_RMC_ENABLE_IND;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: failed to post message to WDA", __func__);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/**
 * sme_disable_rmc() - disable RMC
 * @hHal: handle
 * @sessionId: session id
 *
 * @Return: eHalStatus
 */
eHalStatus sme_disable_rmc(tHalHandle hHal, tANI_U32 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    vos_msg_t vosMessage;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;

   smsLog(pMac, LOG1, FL("disable RMC"));
   status = sme_AcquireGlobalLock(&pMac->sme);
   if (HAL_STATUS_SUCCESS(status))
   {
        vosMessage.bodyptr = NULL;
        vosMessage.type = WDA_RMC_DISABLE_IND;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: failed to post message to WDA", __func__);
           status = eHAL_STATUS_FAILURE;
        }
      sme_ReleaseGlobalLock(&pMac->sme);
   }
   return status;
}


/* ---------------------------------------------------------------------------
    \fn sme_SendRmcActionPeriod
    \brief  Used to send RMC action period param to fw
    \param  hHal
    \param  sessionId
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SendRmcActionPeriod(tHalHandle hHal, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        vosMessage.bodyptr = NULL;
        vosMessage.type = WDA_RMC_ACTION_PERIOD_IND;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: failed to post message to WDA", __func__);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return(status);
}

/* ---------------------------------------------------------------------------
    \fn sme_GetIBSSPeerInfo
    \brief  Used to disable RMC
    setting will not persist over reboots
    \param  hHal
    \param  ibssPeerInfoReq  multicast Group IP address
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_RequestIBSSPeerInfo(tHalHandle hHal, void *pUserData,
                                            pIbssPeerInfoCb peerInfoCbk,
                                            tANI_BOOLEAN allPeerInfoReqd,
                                            tANI_U8 staIdx)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   vos_msg_t vosMessage;
   tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams;

   status = sme_AcquireGlobalLock(&pMac->sme);
   if ( eHAL_STATUS_SUCCESS == status)
   {
       pMac->sme.peerInfoParams.peerInfoCbk = peerInfoCbk;
       pMac->sme.peerInfoParams.pUserData = pUserData;

       pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *)
                        vos_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams));
       if (NULL == pIbssInfoReqParams)
       {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: Not able to allocate memory for dhcp start", __func__);
           sme_ReleaseGlobalLock( &pMac->sme );
           return eHAL_STATUS_FAILURE;
       }
       pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd;
       pIbssInfoReqParams->staIdx = staIdx;

       vosMessage.type = WDA_GET_IBSS_PEER_INFO_REQ;
       vosMessage.bodyptr = pIbssInfoReqParams;
       vosMessage.reserved = 0;
       MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                NO_SESSION, vosMessage.type));
       vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage );
       if ( VOS_STATUS_SUCCESS != vosStatus )
       {
          VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s: Post WDA_GET_IBSS_PEER_INFO_REQ MSG failed", __func__);
          vos_mem_free(pIbssInfoReqParams);
          vosStatus = eHAL_STATUS_FAILURE;
       }
       sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (vosStatus);
}

/* ---------------------------------------------------------------------------
    \fn sme_SendCesiumEnableInd
    \brief  Used to send proprietary cesium enable indication to fw
    \param  hHal
    \param  sessionId
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SendCesiumEnableInd(tHalHandle hHal, tANI_U32 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        vosMessage.bodyptr = NULL;
        vosMessage.type = WDA_IBSS_CESIUM_ENABLE_IND;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: failed to post message to WDA", __func__);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return(status);
}

void smeGetCommandQStatus( tHalHandle hHal )
{
    tSmeCmd *pTempCmd = NULL;
    tListElem *pEntry;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (NULL == pMac)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: pMac is NULL", __func__);
        return;
    }

    pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
    if( pEntry )
    {
        pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
    }
    smsLog( pMac, LOGE, "Currently smeCmdActiveList has command (0x%X)",
            (pTempCmd) ? pTempCmd->command : eSmeNoCommand );
    if(pTempCmd)
    {
        if( eSmeCsrCommandMask & pTempCmd->command )
        {
            //CSR command is stuck. See what the reason code is for that command
            dumpCsrCommandInfo(pMac, pTempCmd);
        }
    } //if(pTempCmd)

    smsLog( pMac, LOGE, "Currently smeCmdPendingList has %d commands",
            csrLLCount(&pMac->sme.smeCmdPendingList));

    smsLog( pMac, LOGE, "Currently roamCmdPendingList has %d commands",
            csrLLCount(&pMac->roam.roamCmdPendingList));

    return;
}
#ifdef WLAN_FEATURE_DSRC
/* -------------------------------------------------------------------------
   \fn sme_set_dot11p_config
   \brief API to Set 802.11p config
   \param hal - The handle returned by macOpen
   \param enable_dot11p - 802.11p config param
   \return eHalStatus
---------------------------------------------------------------------------*/
void sme_set_dot11p_config(tHalHandle hal, bool enable_dot11p)
{
    tpAniSirGlobal mac = PMAC_STRUCT(hal);
    mac->enable_dot11p = enable_dot11p;
}

/**
 * sme_ocb_set_config() - Set the OCB configuration
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @config: the OCB configuration
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_ocb_set_config(tHalHandle hHal, void *context,
                              ocb_callback callback,
                              struct sir_ocb_config *config)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	vos_msg_t msg = {0};
	struct sir_ocb_config *msg_body;

	/* Lock the SME structure */
	status = sme_AcquireGlobalLock(&pMac->sme);
	if (!HAL_STATUS_SUCCESS(status))
		return status;

	/* Check if there is a pending request and return an error if one exists */
	if (pMac->sme.ocb_set_config_callback) {
		status = eHAL_STATUS_FW_PS_BUSY;
		goto end;
	}

	msg_body = sir_copy_sir_ocb_config(config);

	if (!msg_body) {
		status = eHAL_STATUS_FAILED_ALLOC;
		goto end;
	}

	msg.type = WDA_OCB_SET_CONFIG_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and context */
	pMac->sme.ocb_set_config_callback = callback;
	pMac->sme.ocb_set_config_context = context;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
		      FL("Error posting message to WDA: %d"), vos_status);
		pMac->sme.ocb_set_config_callback = callback;
		pMac->sme.ocb_set_config_context = context;
		vos_mem_free(msg_body);
		goto end;
	}

end:
	sme_ReleaseGlobalLock(&pMac->sme);

	if (status)
		return status;
	if (vos_status)
		return eHAL_STATUS_FAILURE;
	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_ocb_set_utc_time() - Set the OCB UTC time
 * @utc: the UTC time struct
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_ocb_set_utc_time(struct sir_ocb_utc *utc)
{
	vos_msg_t msg = {0};
	struct sir_ocb_utc *sme_utc;

	sme_utc = vos_mem_malloc(sizeof(*sme_utc));
	if (!sme_utc) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return eHAL_STATUS_E_MALLOC_FAILED;
	}
	*sme_utc = *utc;

	msg.type = WDA_OCB_SET_UTC_TIME_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_utc;
	if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
						       &msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_utc);
		return eHAL_STATUS_FAILURE;
	}

	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_ocb_start_timing_advert() - Start sending timing advert frames
 * @timing_advert: the timing advertisement struct
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_ocb_start_timing_advert(
    struct sir_ocb_timing_advert *timing_advert)
{
	vos_msg_t msg;
	void *buf;
	struct sir_ocb_timing_advert *sme_timing_advert;

	buf = vos_mem_malloc(sizeof(*sme_timing_advert) +
			     timing_advert->template_length);
	if (!buf) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory for start TA"));
		return eHAL_STATUS_E_MALLOC_FAILED;
	}

	sme_timing_advert = (struct sir_ocb_timing_advert *)buf;
	*sme_timing_advert = *timing_advert;
	sme_timing_advert->template_value = buf + sizeof(*sme_timing_advert);
	vos_mem_copy(sme_timing_advert->template_value,
	timing_advert->template_value, timing_advert->template_length);

	msg.type = WDA_OCB_START_TIMING_ADVERT_CMD;
	msg.reserved = 0;
	msg.bodyptr = buf;
	if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
						       &msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post msg to WDA"));
		return eHAL_STATUS_FAILURE;
	}

	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_ocb_stop_timing_advert() - Stop sending timing advert frames on a channel
 * @timing_advert: the timing advertisement struct
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_ocb_stop_timing_advert(
    struct sir_ocb_timing_advert *timing_advert)
{
	vos_msg_t msg;
	struct sir_ocb_timing_advert *sme_timing_advert;

	sme_timing_advert = vos_mem_malloc(sizeof(*timing_advert));
	if (!sme_timing_advert) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory for stop TA"));
		return eHAL_STATUS_E_MALLOC_FAILED;
	}
	*sme_timing_advert = *timing_advert;

	msg.type = WDA_OCB_STOP_TIMING_ADVERT_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_timing_advert;
	if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
						       &msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post msg to WDA"));
		return eHAL_STATUS_FAILURE;
	}

	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_ocb_gen_timing_advert_frame() - generate TA frame and populate the buffer
 * @hHal: reference to the HAL
 * @self_addr: the self MAC address
 * @buf: the buffer that will contain the frame
 * @timestamp_offset: return for the offset of the timestamp field
 * @time_value_offset: return for the time_value field in the TA IE
 *
 * Return: the length of the buffer.
 */
int sme_ocb_gen_timing_advert_frame(tHalHandle hal_handle,
				    tSirMacAddr self_addr, uint8_t **buf,
				    uint32_t *timestamp_offset,
				    uint32_t *time_value_offset)
{
	int template_length;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);

	template_length = schGenTimingAdvertFrame(mac_ctx, self_addr, buf,
						  timestamp_offset,
						  time_value_offset);
	return template_length;
}

/**
 * sme_ocb_get_tsf_timer() - Get the TSF timer value
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @request: the TSF timer request
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_ocb_get_tsf_timer(tHalHandle hHal, void *context,
                                 ocb_callback callback,
                                 struct sir_ocb_get_tsf_timer *request)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	vos_msg_t msg = {0};
	struct sir_ocb_get_tsf_timer *msg_body;

	/* Lock the SME structure */
	status = sme_AcquireGlobalLock(&pMac->sme);
	if (!HAL_STATUS_SUCCESS(status))
		return status;

	/* Allocate memory for the WMI request, and copy the parameter */
	msg_body = vos_mem_malloc(sizeof(*msg_body));
	if (!msg_body) {
		status = eHAL_STATUS_FAILED_ALLOC;
		goto end;
	}
	*msg_body = *request;

	msg.type = WDA_OCB_GET_TSF_TIMER_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and the context */
	pMac->sme.ocb_get_tsf_timer_callback = callback;
	pMac->sme.ocb_get_tsf_timer_context = context;

	/* Post the message to WDA */
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), vos_status);
		pMac->sme.ocb_get_tsf_timer_callback = NULL;
		pMac->sme.ocb_get_tsf_timer_context = NULL;
		vos_mem_free(msg_body);
		goto end;
	}

end:
	sme_ReleaseGlobalLock(&pMac->sme);

	if (status)
		return status;
	if (vos_status)
		return eHAL_STATUS_FAILURE;
	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_dcc_get_stats() - Get the DCC stats
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @request: the get DCC stats request
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_dcc_get_stats(tHalHandle hHal, void *context,
                             ocb_callback callback,
                             struct sir_dcc_get_stats *request)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	vos_msg_t msg = {0};
	struct sir_dcc_get_stats *msg_body;

	/* Lock the SME structure */
	status = sme_AcquireGlobalLock(&pMac->sme);
	if (!HAL_STATUS_SUCCESS(status))
		return status;

	/* Allocate memory for the WMI request, and copy the parameter */
	msg_body = vos_mem_malloc(sizeof(*msg_body) +
				  request->request_array_len);
	if (!msg_body) {
		status = eHAL_STATUS_FAILED_ALLOC;
		goto end;
	}
	*msg_body = *request;
	msg_body->request_array = (void *)msg_body + sizeof(*msg_body);
	vos_mem_copy(msg_body->request_array, request->request_array,
		     request->request_array_len);

	msg.type = WDA_DCC_GET_STATS_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and context */
	pMac->sme.dcc_get_stats_callback = callback;
	pMac->sme.dcc_get_stats_context = context;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), vos_status);
		pMac->sme.dcc_get_stats_callback = callback;
		pMac->sme.dcc_get_stats_context = context;
		vos_mem_free(msg_body);
		goto end;
	}

end:
	sme_ReleaseGlobalLock(&pMac->sme);

	if (status)
		return status;
	if (vos_status)
		return eHAL_STATUS_FAILURE;
	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_dcc_clear_stats() - Clear the DCC stats
 * @vdev_id: vdev id for OCB interface
 * @dcc_stats_bitmap: the entries in the stats to clear
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_dcc_clear_stats(uint32_t vdev_id, uint32_t dcc_stats_bitmap)
{
	vos_msg_t msg = {0};
	struct sir_dcc_clear_stats *request =
		vos_mem_malloc(sizeof(struct sir_dcc_clear_stats));
	if (!request) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory"));
		return eHAL_STATUS_E_MALLOC_FAILED;
	}
	vos_mem_zero(request, sizeof(*request));
	request->vdev_id = vdev_id;
	request->dcc_stats_bitmap = dcc_stats_bitmap;

	msg.type = WDA_DCC_CLEAR_STATS_CMD;
	msg.bodyptr = request;

	if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
						       &msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post msg to WDA"));
		vos_mem_free(request);
		return eHAL_STATUS_FAILURE;
	}

	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_dcc_update_ndl() - Update the DCC settings
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @request: the update DCC request
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_dcc_update_ndl(tHalHandle hHal, void *context,
                              ocb_callback callback,
                              struct sir_dcc_update_ndl *request)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	vos_msg_t msg = {0};
	struct sir_dcc_update_ndl *msg_body;

	/* Lock the SME structure */
	status = sme_AcquireGlobalLock(&pMac->sme);
	if (!HAL_STATUS_SUCCESS(status))
		return status;

	/* Allocate memory for the WMI request, and copy the parameter */
	msg_body = vos_mem_malloc(sizeof(*msg_body) +
				  request->dcc_ndl_chan_list_len +
				  request->dcc_ndl_active_state_list_len);
	if (!msg_body) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to allocate memory"));
		status = eHAL_STATUS_FAILED_ALLOC;
		goto end;
	}

	*msg_body = *request;

	msg_body->dcc_ndl_chan_list = (void *)msg_body + sizeof(*msg_body);
	msg_body->dcc_ndl_active_state_list = msg_body->dcc_ndl_chan_list +
		request->dcc_ndl_chan_list_len;
	vos_mem_copy(msg_body->dcc_ndl_chan_list, request->dcc_ndl_chan_list,
		     request->dcc_ndl_active_state_list_len);
	vos_mem_copy(msg_body->dcc_ndl_active_state_list,
		     request->dcc_ndl_active_state_list,
		     request->dcc_ndl_active_state_list_len);

	msg.type = WDA_DCC_UPDATE_NDL_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and the context */
	pMac->sme.dcc_update_ndl_callback = callback;
	pMac->sme.dcc_update_ndl_context = context;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), vos_status);
		pMac->sme.dcc_update_ndl_callback = NULL;
		pMac->sme.dcc_update_ndl_context = NULL;
		vos_mem_free(msg_body);
		goto end;
	}

end:
	sme_ReleaseGlobalLock(&pMac->sme);

	if (status)
		return status;
	if (vos_status)
		return eHAL_STATUS_FAILURE;
	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_register_for_dcc_stats_event() - Register for the periodic DCC stats
 *                                      event
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_register_for_dcc_stats_event(tHalHandle hHal, void *context,
                                            ocb_callback callback)
{
	tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
	eHalStatus status = eHAL_STATUS_FAILURE;

	status = sme_AcquireGlobalLock(&pMac->sme);
	pMac->sme.dcc_stats_event_callback = callback;
	pMac->sme.dcc_stats_event_context = context;
	sme_ReleaseGlobalLock(&pMac->sme);

	return 0;
}

/**
 * sme_register_radio_chan_stats_cb() - Register callback for DSRC radio
 *	channel statistics event indication.
 * @hal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_register_radio_chan_stats_cb(tHalHandle hal, void *context,
					    ocb_callback callback)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		mac->sme.radio_chan_stats_callback = callback;
		mac->sme.radio_chan_stats_context = context;
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock error"));
	}

	return status;
}

/**
 * sme_unregister_radio_chan_stats_cb() - Unregister DSRC radio channel
 *	statistics callback.
 * @hal: reference to the HAL
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_unregister_radio_chan_stats_cb(tHalHandle hal)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		mac->sme.radio_chan_stats_callback = NULL;
		mac->sme.radio_chan_stats_context = NULL;
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock error"));
	}

	return status;
}

/**
 * sme_request_radio_chan_stats() - Set request for DSRC
 *	radio channel statistics.
 * @hal: reference to the HAL
 * @req: request parameters for radio channel stats.
 *
 * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE on failure
 */
eHalStatus sme_request_radio_chan_stats(tHalHandle hal,
					struct radio_chan_stats_req *req)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	struct radio_chan_stats_req *msg_body;
	vos_msg_t msg = { 0 };

	status = sme_AcquireGlobalLock(&mac->sme);
	if (!HAL_STATUS_SUCCESS(status))
		return status;

	msg_body = vos_mem_malloc(sizeof(*msg_body));
	if (!msg_body)
		return eHAL_STATUS_FAILED_ALLOC;

	vos_mem_copy(msg_body, req, sizeof(*msg_body));

	msg.type = WDA_DSRC_RADIO_CHAN_STATS_REQ;
	msg.bodyptr = msg_body;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA, &msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), vos_status);
		vos_mem_free(msg_body);
		return eHAL_STATUS_FAILURE;
	}

	sme_ReleaseGlobalLock(&mac->sme);

	return eHAL_STATUS_SUCCESS;
}
#endif
void sme_getRecoveryStats(tHalHandle hHal) {
    tANI_U8 i;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Self Recovery Stats");
    for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) {
        if (eSmeNoCommand != gSelfRecoveryStats.activeCmdStats[i].command) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "timestamp %llu: command 0x%0X: reason %d: session %d",
                        gSelfRecoveryStats.activeCmdStats[i].timestamp,
                        gSelfRecoveryStats.activeCmdStats[i].command,
                        gSelfRecoveryStats.activeCmdStats[i].reason,
                        gSelfRecoveryStats.activeCmdStats[i].sessionId);
        }
    }
}

void sme_SaveActiveCmdStats(tHalHandle hHal) {
    tSmeCmd *pTempCmd = NULL;
    tListElem *pEntry;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tANI_U8 statsIndx = 0;

    if (NULL == pMac) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: pMac is NULL", __func__);
        return;
    }

    pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
    if (pEntry) {
        pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
    }

    if (pTempCmd) {
        if (eSmeCsrCommandMask & pTempCmd->command) {
            statsIndx =  gSelfRecoveryStats.cmdStatsIndx;
            gSelfRecoveryStats.activeCmdStats[statsIndx].command =
                                                            pTempCmd->command;
            gSelfRecoveryStats.activeCmdStats[statsIndx].sessionId =
                                                          pTempCmd->sessionId;
            gSelfRecoveryStats.activeCmdStats[statsIndx].timestamp =
                                            vos_get_monotonic_boottime();
            if (eSmeCommandRoam == pTempCmd->command) {
                gSelfRecoveryStats.activeCmdStats[statsIndx].reason =
                                                pTempCmd->u.roamCmd.roamReason;
            } else if (eSmeCommandScan == pTempCmd->command) {
                gSelfRecoveryStats.activeCmdStats[statsIndx].reason =
                                                pTempCmd->u.scanCmd.reason;
            } else {
                gSelfRecoveryStats.activeCmdStats[statsIndx].reason = 0xFF;
            }

            gSelfRecoveryStats.cmdStatsIndx =
                   ((gSelfRecoveryStats.cmdStatsIndx + 1) &
                    (MAX_ACTIVE_CMD_STATS - 1));
        }
    }
    return;
}

void activeListCmdTimeoutHandle(void *userData)
{
    tHalHandle hal = (tHalHandle) userData;
    tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
    tListElem *entry;
    tSmeCmd *temp_cmd = NULL;

    if (NULL == mac_ctx) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
            "%s: pMac is null", __func__);
        return;
    }
    /* Return if no cmd pending in active list as
     * in this case we should not be here.
     */
    if (0 == csrLLCount(&mac_ctx->sme.smeCmdActiveList))
        return;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
        "%s: Active List command timeout Cmd List Count %d", __func__,
        csrLLCount(&mac_ctx->sme.smeCmdActiveList) );
    smeGetCommandQStatus(hal);

    if (mac_ctx->roam.configParam.enable_fatal_event) {
        vos_flush_logs(WLAN_LOG_TYPE_FATAL,
                       WLAN_LOG_INDICATOR_HOST_DRIVER,
                       WLAN_LOG_REASON_SME_COMMAND_STUCK,
                       DUMP_NO_TRACE);
    } else {
        vosTraceDumpAll(mac_ctx, 0, 0, 500, 0);
    }

    entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, LL_ACCESS_LOCK);
    if (entry)
        temp_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);

    /* Ignore if ROC took more than 120 sec */
    if (temp_cmd && (eSmeCommandRemainOnChannel == temp_cmd->command))
        return;

    if (mac_ctx->sme.enableSelfRecovery) {
        sme_SaveActiveCmdStats(hal);
        vos_trigger_recovery(false);
    } else {
        if (!mac_ctx->roam.configParam.enable_fatal_event &&
            !(vos_is_load_unload_in_progress(VOS_MODULE_ID_SME, NULL) ||
            vos_is_logp_in_progress(VOS_MODULE_ID_SME, NULL)))
            vos_wlanRestart();
    }
}

VOS_STATUS sme_notify_modem_power_state(tHalHandle hHal, tANI_U32 value)
{
   vos_msg_t msg;
   tpSirModemPowerStateInd pRequestBuf;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   if (NULL == pMac)
   {
      return VOS_STATUS_E_FAILURE;
   }

   pRequestBuf = vos_mem_malloc(sizeof(tSirModemPowerStateInd));
   if (NULL == pRequestBuf)
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
       "%s: Not able to allocate memory for MODEM POWER STATE IND",
       __func__);
      return VOS_STATUS_E_FAILURE;
   }

   pRequestBuf->param = value;

   msg.type     = WDA_MODEM_POWER_STATE_IND;
   msg.reserved = 0;
   msg.bodyptr  = pRequestBuf;
   if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to post WDA_MODEM_POWER_STATE_IND message"
         " to WDA", __func__);
       vos_mem_free(pRequestBuf);
       return VOS_STATUS_E_FAILURE;
   }

   return VOS_STATUS_SUCCESS;
}

#ifdef QCA_HT_2040_COEX
VOS_STATUS sme_notify_ht2040_mode(tHalHandle hHal, tANI_U16 staId,
             v_MACADDR_t macAddrSTA, v_U8_t sessionId, tANI_U8 channel_type)
{
    vos_msg_t msg;
    tUpdateVHTOpMode *pHtOpMode = NULL;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (NULL == pMac)
   {
      return VOS_STATUS_E_FAILURE;
   }

   pHtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode));
   if ( NULL == pHtOpMode )
   {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
       "%s: Not able to allocate memory for setting OP mode",
       __func__);
      return VOS_STATUS_E_FAILURE;
   }

   switch (channel_type)
   {
   case eHT_CHAN_HT20:
       pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ;
       break;

   case eHT_CHAN_HT40MINUS:
   case eHT_CHAN_HT40PLUS:
       pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ;
       break;

   default:
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
       "%s: Invalid OP mode",
       __func__);
       return VOS_STATUS_E_FAILURE;
   }

   pHtOpMode->staId = staId,
   vos_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes,
                 sizeof(tSirMacAddr));
   pHtOpMode->smesessionId = sessionId;
   pHtOpMode->chanMode = MODE_MAX;

   msg.type     = WDA_UPDATE_OP_MODE;
   msg.reserved = 0;
   msg.bodyptr  = pHtOpMode;
   if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to post WDA_UPDATE_OP_MODE message"
         " to WDA", __func__);
       vos_mem_free(pHtOpMode);
       return VOS_STATUS_E_FAILURE;
   }

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
       "%s: Notifed FW about OP mode: %d for staId=%d",
       __func__, pHtOpMode->opMode, staId);


   return VOS_STATUS_SUCCESS;
}

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

    \fn sme_SetHT2040Mode

    \brief To update HT Operation beacon IE.

    \param hHal - The handle returned by macOPen
    \param sessionId - session id
    \param channel_type - indicates channel width
    \param obssEnabled - OBSS enabled/disabled

    \return eHalStatus  SUCCESS
                        FAILURE or RESOURCES
                        The API finished and failed.

  -------------------------------------------------------------------------------*/
eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId,
                             tANI_U8 channel_type, tANI_BOOLEAN obssEnabled)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   ePhyChanBondState cbMode;

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
       "%s: Update HT operation beacon IE, channel_type=%d",
       __func__, channel_type);

   switch (channel_type)
   {
   case eHT_CHAN_HT20:
       cbMode = PHY_SINGLE_CHANNEL_CENTERED;
       break;
   case eHT_CHAN_HT40MINUS:
       cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
       break;
   case eHT_CHAN_HT40PLUS:
       cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
       break;
   default:
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
          "%s:Error!!! Invalid HT20/40 mode !",
          __func__);
       return VOS_STATUS_E_FAILURE;
   }
   status = sme_AcquireGlobalLock(&pMac->sme);
   if (HAL_STATUS_SUCCESS(status)) {
      status = csrSetHT2040Mode(pMac, sessionId, cbMode, obssEnabled);
      sme_ReleaseGlobalLock(&pMac->sme );
   }
   return (status);
}
#endif

/*
 * SME API to enable/disable idle mode power save
 * This should be called only if power save offload
 * is enabled
 */
VOS_STATUS sme_SetIdlePowersaveConfig(v_PVOID_t vosContext, tANI_U32 value)
{
    v_PVOID_t wdaContext = vos_get_context(VOS_MODULE_ID_WDA, vosContext);

    if (NULL == wdaContext)
    {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              "%s: wdaContext is NULL", __func__);
       return VOS_STATUS_E_FAILURE;
    }
    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
              " Idle Ps Set Value %d", value);

    if (VOS_STATUS_SUCCESS != WDA_SetIdlePsConfig(wdaContext, value))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  " Failed to Set Idle Ps Value %d", value);
        return VOS_STATUS_E_FAILURE;
    }
    return VOS_STATUS_SUCCESS;
}
/**
 * sme_set_cts2self_for_p2p_go() - sme function to set ini parms to FW.
 * @hal_handle:                    reference to the HAL
 *
 * Return: hal_status
 */
eHalStatus sme_set_cts2self_for_p2p_go(tHalHandle hal_handle)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	vos_msg_t vos_msg;

	vos_msg.bodyptr = NULL;
	vos_msg.type = WDA_SET_CTS2SELF_FOR_STA;
        if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Failed to post WDA_SET_CTS2SELF_FOR_STA to WDA"));
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}

/**
 * sme_set_ac_txq_optimize() - sme function to set ini parms to FW.
 * @hal_handle:                    reference to the HAL
 * @value                          reference to the value
 * Return: hal_status
 */
eHalStatus sme_set_ac_txq_optimize(tHalHandle hal_handle, uint8_t *value)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	vos_msg_t vos_msg;

	vos_msg.bodyptr = value;
	vos_msg.type = WDA_SET_AC_TXQ_OPTIMIZE;
	if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
						       &vos_msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to post WDA_SET_AC_TXQ_OPTIMIZE to WDA"));
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}

eHalStatus sme_ConfigEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status =  pmcOffloadConfigEnablePowerSave(hHal, psMode);
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

eHalStatus sme_ConfigDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
       status =  pmcOffloadConfigDisablePowerSave(hHal, psMode);
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

eHalStatus sme_PsOffloadEnablePowerSave (tHalHandle hHal, tANI_U32 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   status = sme_AcquireGlobalLock(&pMac->sme);
   if(HAL_STATUS_SUCCESS( status ))
   {
       status =  PmcOffloadEnableStaModePowerSave(hHal, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

eHalStatus sme_PsOffloadDisablePowerSave(tHalHandle hHal,
                                         FullPowerReqCb callback_routine,
                                         void *callback_context,
                                         tANI_U32 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   status = sme_AcquireGlobalLock(&pMac->sme);
   if(HAL_STATUS_SUCCESS( status ))
   {
       status =  PmcOffloadDisableStaModePowerSave(hHal,
                         callback_routine, callback_context, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

eHalStatus sme_PsOffloadEnableDeferredPowerSave (tHalHandle hHal,
                                                 tANI_U32 sessionId,
                                                 tANI_BOOLEAN isReassoc)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   status = sme_AcquireGlobalLock(&pMac->sme);
   if (HAL_STATUS_SUCCESS( status ))
   {
       status =  PmcOffloadEnableDeferredStaModePowerSave(hHal, sessionId,
                                                          isReassoc);
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

eHalStatus sme_PsOffloadDisableDeferredPowerSave (tHalHandle hHal,
                                                  tANI_U32 sessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   status = sme_AcquireGlobalLock(&pMac->sme);
   if (HAL_STATUS_SUCCESS( status ))
   {
       status =  PmcOffloadDisableDeferredStaModePowerSave(hHal, sessionId);
       sme_ReleaseGlobalLock( &pMac->sme );
   }
   return (status);
}

tANI_S16 sme_GetHTConfig(tHalHandle hHal, tANI_U8 session_id, tANI_U16 ht_capab)
{
   tpAniSirGlobal    pMac = PMAC_STRUCT(hHal);
   tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);

   if (NULL == pSession)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: pSession is NULL", __func__);
       return -EIO;
   }
   switch (ht_capab) {
   case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
        return pSession->htConfig.ht_rx_ldpc;
   case WNI_CFG_HT_CAP_INFO_TX_STBC:
        return pSession->htConfig.ht_tx_stbc;
   case WNI_CFG_HT_CAP_INFO_RX_STBC:
        return pSession->htConfig.ht_rx_stbc;
   case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
   case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
        return pSession->htConfig.ht_sgi;
   default:
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "invalid ht capability");
        return -EIO;
   }
}

int sme_UpdateHTConfig(tHalHandle hHal, tANI_U8 sessionId, tANI_U16 htCapab,
                         int value)
{
   tpAniSirGlobal    pMac = PMAC_STRUCT(hHal);
   tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

   if (NULL == pSession)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: pSession is NULL", __func__);
       return -EIO;
   }

   if (eHAL_STATUS_SUCCESS != WDA_SetHTConfig(sessionId, htCapab, value)) {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                 "Failed to set ht capability in target");
       return -EIO;
   }

   switch (htCapab) {
   case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
        pSession->htConfig.ht_rx_ldpc = value;
        break;
   case WNI_CFG_HT_CAP_INFO_TX_STBC:
        pSession->htConfig.ht_tx_stbc = value;
        break;
   case WNI_CFG_HT_CAP_INFO_RX_STBC:
        pSession->htConfig.ht_rx_stbc = value;
        break;
   case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
   case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
        pSession->htConfig.ht_sgi = value;
        break;
   }

   return 0;
}

#define HT20_SHORT_GI_MCS7_RATE 722
/* ---------------------------------------------------------------------------
    \fn sme_SendRateUpdateInd
    \brief  API to Update rate
    \param  hHal - The handle returned by macOpen
    \param  rateUpdateParams - Pointer to rate update params
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SendRateUpdateInd(tHalHandle hHal,
                                 tSirRateUpdateInd *rateUpdateParams)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status;
    vos_msg_t msg;
    tSirRateUpdateInd *rateUpdate = vos_mem_malloc(sizeof(tSirRateUpdateInd));
    if (rateUpdate == NULL) {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                            "%s: SET_MC_RATE indication alloc fail", __func__);
        return eHAL_STATUS_FAILURE;
    }
    *rateUpdate = *rateUpdateParams;

    if (rateUpdate->mcastDataRate24GHz ==
            HT20_SHORT_GI_MCS7_RATE)
        rateUpdate->mcastDataRate24GHzTxFlag =
           eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
    else if (rateUpdate->reliableMcastDataRate ==
             HT20_SHORT_GI_MCS7_RATE)
        rateUpdate->reliableMcastDataRateTxFlag =
           eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
    {
        msg.type     = WDA_RATE_UPDATE_IND;
        msg.bodyptr  = rateUpdate;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                        NO_SESSION, msg.type));
        if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
        {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able "
                       "to post WDA_SET_RMC_RATE_IND to WDA!",
                       __func__);

            vos_mem_free(rateUpdate);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        sme_ReleaseGlobalLock(&pMac->sme);
        return eHAL_STATUS_SUCCESS;
    }
    else
    {
        vos_mem_free(rateUpdate);
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                   FL("sme_AcquireGlobalLock error"));
    }

    return status;
}

eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId,
                         tANI_U32  *regInfo1, tANI_U32  *regInfo2)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status;
    tANI_U8 i;
    eAniBoolean found = false;

    status = sme_AcquireGlobalLock(&pMac->sme);
    *regInfo1 = 0;
    *regInfo2 = 0;
    if (HAL_STATUS_SUCCESS(status))
    {
        for (i = 0 ; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++)
        {
            if (pMac->scan.defaultPowerTable[i].chanId == chanId)
            {
                SME_SET_CHANNEL_REG_POWER(*regInfo1,
                                          pMac->scan.defaultPowerTable[i].pwr);

                SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2,
                                          pMac->scan.defaultPowerTable[i].pwr);


                found = true;
                break;
            }
        }

        if (!found)
            status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* sme_get_wni_dot11_mode() - return configured wni dot11mode
 * @hHal: hal pointer
 *
 * Return: wni dot11 mode.
 */
uint32_t sme_get_wni_dot11_mode(tHalHandle hal)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	return csrTranslateToWNICfgDot11Mode(mac_ctx,
			mac_ctx->roam.configParam.uCfgDot11Mode);
}

#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
/* ---------------------------------------------------------------------------
    \fn sme_auto_shutdown_cb
    \brief  Used to plug in callback function for receiving auto shutdown evt
    \param  hHal
    \param  pCallbackfn : callback function pointer should be plugged in
    \- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_set_auto_shutdown_cb
(
   tHalHandle hHal,
   void (*pCallbackfn)(void)
)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              "%s: Plug in Auto shutdown event callback", __func__);

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        if (NULL != pCallbackfn)
        {
           pMac->sme.pAutoShutdownNotificationCb = pCallbackfn;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return(status);
}
/* ---------------------------------------------------------------------------
    \fn sme_set_auto_shutdown_timer
    \API to set auto shutdown timer value in FW.
    \param hHal - The handle returned by macOpen
    \param timer_val - The auto shutdown timer value to be set
    \- return Configuration message posting status, SUCCESS or Fail
    -------------------------------------------------------------------------*/
eHalStatus sme_set_auto_shutdown_timer(tHalHandle hHal, tANI_U32 timer_val)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
    tSirAutoShutdownCmdParams *auto_sh_cmd;
    vos_msg_t           vosMessage;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        auto_sh_cmd = (tSirAutoShutdownCmdParams *)
                  vos_mem_malloc(sizeof(tSirAutoShutdownCmdParams));
        if (auto_sh_cmd == NULL)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s Request Buffer Alloc Fail", __func__);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        auto_sh_cmd->timer_val = timer_val;

        /* serialize the req through MC thread */
        vosMessage.bodyptr = auto_sh_cmd;
        vosMessage.type    = WDA_SET_AUTO_SHUTDOWN_TIMER_REQ;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Post Auto shutdown MSG fail", __func__);
           vos_mem_free(auto_sh_cmd);
           sme_ReleaseGlobalLock(&pMac->sme);
           return eHAL_STATUS_FAILURE;
        }
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: Posted Auto shutdown MSG", __func__);
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return(status);
}
#endif

#ifdef FEATURE_WLAN_CH_AVOID
/* ---------------------------------------------------------------------------
    \fn sme_AddChAvoidCallback
    \brief  Used to plug in callback function
            Which notify channel may not be used with SAP or P2PGO mode.
            Notification come from FW.
    \param  hHal
    \param  pCallbackfn : callback function pointer should be plugged in
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_AddChAvoidCallback
(
   tHalHandle hHal,
   void (*pCallbackfn)(void *pAdapter, void *indParam)
)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              "%s: Plug in CH AVOID CB", __func__);

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        if (NULL != pCallbackfn)
        {
           pMac->sme.pChAvoidNotificationCb = pCallbackfn;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return(status);
}

/* ---------------------------------------------------------------------------
    \fn sme_ChAvoidUpdateReq
    \API to request channel avoidance update from FW.
    \param hHal - The handle returned by macOpen
    \param update_type - The udpate_type parameter of this request call
    \- return Configuration message posting status, SUCCESS or Fail
    -------------------------------------------------------------------------*/
eHalStatus sme_ChAvoidUpdateReq
(
   tHalHandle hHal
)
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
    tSirChAvoidUpdateReq *cauReq;
    vos_msg_t           vosMessage;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        cauReq = (tSirChAvoidUpdateReq *)
                  vos_mem_malloc(sizeof(tSirChAvoidUpdateReq));
        if (NULL == cauReq)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s Request Buffer Alloc Fail", __func__);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        cauReq->reserved_param = 0;

        /* serialize the req through MC thread */
        vosMessage.bodyptr = cauReq;
        vosMessage.type    = WDA_CH_AVOID_UPDATE_REQ;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Post Ch Avoid Update MSG fail", __func__);
           vos_mem_free(cauReq);
           sme_ReleaseGlobalLock(&pMac->sme);
           return eHAL_STATUS_FAILURE;
        }
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "%s: Posted Ch Avoid Update MSG", __func__);
        sme_ReleaseGlobalLock(&pMac->sme);
    }

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

/**
 * sme_set_miracast() - Function to set miracast value to UMAC
 * @hal:                Handle returned by macOpen
 * @filter_type:        0-Disabled, 1-Source, 2-sink
 *
 * This function passes down the value of miracast set by
 * framework to UMAC
 *
 * Return: Configuration message posting status, SUCCESS or Fail
 *
 */
eHalStatus sme_set_miracast(tHalHandle hal, uint8_t filter_type)
{
	vos_msg_t msg;
	uint32_t *val;
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal);

	if (NULL == mac_ptr) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Invalid MAC pointer", __func__);
		return eHAL_STATUS_FAILURE;
	}
	val = vos_mem_malloc(sizeof(*val));
	if (NULL == val) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Invalid pointer", __func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}

	*val = filter_type;

	msg.type = SIR_HAL_SET_MIRACAST;
	msg.reserved = 0;
	msg.bodyptr = val;

	if (!VOS_IS_STATUS_SUCCESS(
				vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Not able to post SIR_HAL_SET_MIRACAST to WMA!",
			__func__);
		vos_mem_free(val);
		return eHAL_STATUS_FAILURE;
	}

	mac_ptr->sme.miracast_value = filter_type;
	return eHAL_STATUS_SUCCESS;
}

/**
 * sme_set_mas() - Function to set MAS value to UMAC
 * @val:	1-Enable, 0-Disable
 *
 * This function passes down the value of MAS to the UMAC. A
 * value of 1 will enable MAS and a value of 0 will disable MAS
 *
 * Return: Configuration message posting status, SUCCESS or Fail
 *
 */
eHalStatus sme_set_mas(uint32_t val)
{
	vos_msg_t msg;
	uint32_t *ptr_val;

	ptr_val = vos_mem_malloc(sizeof(*ptr_val));
	if (NULL == ptr_val) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: could not allocate ptr_val", __func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}

	*ptr_val = val;

	msg.type = SIR_HAL_SET_MAS;
	msg.reserved = 0;
	msg.bodyptr = ptr_val;

	if (!VOS_IS_STATUS_SUCCESS(
				vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
				__func__);
		vos_mem_free(ptr_val);
		return eHAL_STATUS_FAILURE;
	}
	return eHAL_STATUS_SUCCESS;
}

/* -------------------------------------------------------------------------
   \fn sme_RoamChannelChangeReq
   \brief API to Indicate Channel change to new target channel
   \return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_RoamChannelChangeReq(tHalHandle hHal, tCsrBssid bssid,
                                    tANI_U32 cbMode, tCsrRoamProfile *pprofile)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    u_int8_t ch_mode;

    ch_mode = (pprofile->ChannelInfo.ChannelList[0] <= 14) ?
                      pMac->roam.configParam.channelBondingMode24GHz :
                      pMac->roam.configParam.channelBondingMode5GHz;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("sapdfs: requested CBmode=%d & new negotiated CBmode=%d"),
                  cbMode, ch_mode);
        status = csrRoamChannelChangeReq(pMac, bssid, ch_mode, pprofile);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

/* -------------------------------------------------------------------------
   \fn sme_ProcessChannelChangeResp
   \brief API to Indicate Channel change response message to SAP.
   \return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac,
                                     v_U16_t msg_type, void *pMsgBuf)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tCsrRoamInfo *roam_info;
    eCsrRoamResult roamResult;
    tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf;
    tANI_U32 SessionId = pChnlParams->peSessionId;
    tpPESession psessionEntry;

    roam_info = vos_mem_malloc(sizeof(*roam_info));
    if (!roam_info)
        return eHAL_STATUS_FAILED_ALLOC;
    vos_mem_zero(roam_info, sizeof(*roam_info));

    psessionEntry = peFindSessionBySessionId(pMac, SessionId);
    if (psessionEntry)
	    roam_info->staId = psessionEntry->staId;

    roam_info->channelChangeRespEvent =
        (tSirChanChangeResponse *)vos_mem_malloc(
                                sizeof(tSirChanChangeResponse));
    if (NULL == roam_info->channelChangeRespEvent)
    {
        status = eHAL_STATUS_FAILURE;
        smsLog(pMac, LOGE, "Channel Change Event Allocation Failed: %d\n",
              status);
        vos_mem_free(roam_info);

        return status;
    }
    if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ( pMac, SessionId))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
                "sapdfs: Abort channel change in STOP_BSS_REQ state on sessionId[%d]",
                SessionId);
        status = eHAL_STATUS_FAILURE;
        vos_mem_free(roam_info);

        return status;
    }
    if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP)
    {
        roam_info->channelChangeRespEvent->sessionId = SessionId;
        roam_info->channelChangeRespEvent->newChannelNumber =
                                           pChnlParams->channelNumber;
        roam_info->channelChangeRespEvent->secondaryChannelOffset =
                                  pChnlParams->secondaryChannelOffset;

        if (pChnlParams->status == eHAL_STATUS_SUCCESS)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
            "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
                      SessionId);
            roam_info->channelChangeRespEvent->channelChangeStatus = 1;
            roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS;
        }
        else
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
            "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
                      SessionId);
            roam_info->channelChangeRespEvent->channelChangeStatus = 0;
            roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;
        }

        csrRoamCallCallback(pMac, SessionId, roam_info, 0,
                            eCSR_ROAM_SET_CHANNEL_RSP, roamResult);

    }
    else
    {
        status = eHAL_STATUS_FAILURE;
        smsLog(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n",
              status);
    }
    vos_mem_free(roam_info->channelChangeRespEvent);
    vos_mem_free(roam_info);

    return status;
}

/* -------------------------------------------------------------------------
   \fn sme_RoamStartBeaconReq
   \brief API to Indicate LIM to start Beacon Tx
   \after SAP CAC Wait is completed.
   \param hHal - The handle returned by macOpen
   \param sessionId - session ID
   \param dfsCacWaitStatus - CAC WAIT status flag
   \return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal, tCsrBssid bssid,
                              tANI_U8 dfsCacWaitStatus)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    status = sme_AcquireGlobalLock( &pMac->sme );

    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrRoamStartBeaconReq( pMac, bssid, dfsCacWaitStatus);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

/* -------------------------------------------------------------------------
   \fn sme_RoamCsaIeRequest
   \brief API to request CSA IE transmission from PE
   \param hHal - The handle returned by macOpen
   \param pDfsCsaReq - CSA IE request
   \param bssid - SAP bssid
   \param ch_bandwidth - Channel offset
   \return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_RoamCsaIeRequest(tHalHandle hHal, tCsrBssid bssid,
                                    tANI_U8 targetChannel,
                                    tANI_U8 csaIeReqd,
                                    u_int8_t ch_bandwidth)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrRoamSendChanSwIERequest(pMac, bssid, targetChannel,
                                                  csaIeReqd, ch_bandwidth);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_InitThermalInfo
    \brief  SME API to initialize the thermal mitigation parameters
    \param  hHal
    \param  thermalParam : thermal mitigation parameters
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_InitThermalInfo( tHalHandle hHal,
                                tSmeThermalParams thermalParam )
{
    t_thermal_mgmt * pWdaParam;
    vos_msg_t msg;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pWdaParam = (t_thermal_mgmt *)vos_mem_malloc(sizeof(t_thermal_mgmt));
    if (NULL == pWdaParam)
    {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                 "%s: could not allocate tThermalMgmt", __func__);
       return eHAL_STATUS_E_MALLOC_FAILED;
    }

    vos_mem_zero((void*)pWdaParam, sizeof(t_thermal_mgmt));

    pWdaParam->thermalMgmtEnabled = thermalParam.smeThermalMgmtEnabled;
    pWdaParam->throttlePeriod = thermalParam.smeThrottlePeriod;
    pWdaParam->throttle_duty_cycle_tbl[0]=
        thermalParam.sme_throttle_duty_cycle_tbl[0];
    pWdaParam->throttle_duty_cycle_tbl[1]=
        thermalParam.sme_throttle_duty_cycle_tbl[1];
    pWdaParam->throttle_duty_cycle_tbl[2]=
        thermalParam.sme_throttle_duty_cycle_tbl[2];
    pWdaParam->throttle_duty_cycle_tbl[3]=
        thermalParam.sme_throttle_duty_cycle_tbl[3];
    pWdaParam->thermalLevels[0].minTempThreshold =
        thermalParam.smeThermalLevels[0].smeMinTempThreshold;
    pWdaParam->thermalLevels[0].maxTempThreshold =
        thermalParam.smeThermalLevels[0].smeMaxTempThreshold;
    pWdaParam->thermalLevels[1].minTempThreshold =
        thermalParam.smeThermalLevels[1].smeMinTempThreshold;
    pWdaParam->thermalLevels[1].maxTempThreshold =
        thermalParam.smeThermalLevels[1].smeMaxTempThreshold;
    pWdaParam->thermalLevels[2].minTempThreshold =
        thermalParam.smeThermalLevels[2].smeMinTempThreshold;
    pWdaParam->thermalLevels[2].maxTempThreshold =
        thermalParam.smeThermalLevels[2].smeMaxTempThreshold;
    pWdaParam->thermalLevels[3].minTempThreshold =
         thermalParam.smeThermalLevels[3].smeMinTempThreshold;
    pWdaParam->thermalLevels[3].maxTempThreshold =
         thermalParam.smeThermalLevels[3].smeMaxTempThreshold;

#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN
    pWdaParam->thermal_shutdown_enabled = thermalParam.thermal_shutdown_enabled;
    pWdaParam->thermal_shutdown_auto_enabled =
        thermalParam.thermal_shutdown_auto_enabled;
    pWdaParam->thermal_resume_threshold =thermalParam.thermal_resume_threshold;
    pWdaParam->thermal_warning_threshold =
        thermalParam.thermal_warning_threshold;
    pWdaParam->thermal_suspend_threshold =
        thermalParam.thermal_suspend_threshold;
    pWdaParam->thermal_sample_rate = thermalParam.thermal_sample_rate;
#endif

    if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
    {
        msg.type     = WDA_INIT_THERMAL_INFO_CMD;
        msg.bodyptr  = pWdaParam;

        if (!VOS_IS_STATUS_SUCCESS(
           vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
        {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: Not able to post WDA_SET_THERMAL_INFO_CMD to WDA!",
                       __func__);
            vos_mem_free(pWdaParam);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
        return eHAL_STATUS_SUCCESS;
    }
    vos_mem_free(pWdaParam);
    return eHAL_STATUS_FAILURE;
}

/* ---------------------------------------------------------------------------
    \fn sme_InitDPDRecalInfo
    \brief  SME API to initialize the Runtime DPD Recaliberation parameters
    \param  hHal
    \param  DPDParam : DPD Recal parameters
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_InitDPDRecalInfo( tHalHandle hHal,
                                tSmeDPDRecalParams DPDParam )
{
    t_dpd_recal_mgmt * pWdaParam;
    vos_msg_t msg;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pWdaParam = (t_dpd_recal_mgmt *)vos_mem_malloc(sizeof(t_dpd_recal_mgmt));
    if (NULL == pWdaParam)
    {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                 "%s: could not allocate t_dpd_recal_mgmt", __func__);
       return eHAL_STATUS_E_MALLOC_FAILED;
    }

    vos_mem_zero((void*)pWdaParam, sizeof(t_dpd_recal_mgmt));
    pWdaParam->dpd_enable = DPDParam.enable;
    pWdaParam->dpd_delta_degreeHigh = DPDParam.delta_degreeHigh;
    pWdaParam->dpd_delta_degreeLow = DPDParam.delta_degreeLow;
    pWdaParam->dpd_cooling_time = DPDParam.cooling_time;
    pWdaParam->dpd_duration_max = DPDParam.dpd_dur_max;

    if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
    {
        msg.type     = WDA_INIT_DPD_RECAL_INFO_CMD;
        msg.bodyptr  = pWdaParam;

        if (!VOS_IS_STATUS_SUCCESS(
           vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
        {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: Not able to post WDA_INIT_DPD_RECAL_INFO_CMD to WDA!",
                       __func__);
            vos_mem_free(pWdaParam);
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
        return eHAL_STATUS_SUCCESS;
    }
    vos_mem_free(pWdaParam);
    return eHAL_STATUS_FAILURE;
}

/*
 * Plug in set thermal level callback
 */
void sme_add_set_thermal_level_callback(tHalHandle hHal,
                   tSmeSetThermalLevelCallback callback)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pMac->sme.set_thermal_level_cb = callback;
}

/**
 * sme_SetThermalLevel() - SME API to set the thermal mitigation level
 * hHal:	Handler to HAL
 * level:	Thermal mitigation level
 *
 * Return: HAL status code
 */
eHalStatus sme_SetThermalLevel( tHalHandle hHal, tANI_U8 level )
{
	vos_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;

	if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) {
		vos_mem_set(&msg, sizeof(msg), 0);
		msg.type = WDA_SET_THERMAL_LEVEL;
		msg.bodyval = level;

		vosStatus =  vos_mq_post_message(VOS_MODULE_ID_WDA, &msg);
		if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				   "%s: Not able to post WDA_SET_THERMAL_LEVEL to WDA!",
				   __func__);
			sme_ReleaseGlobalLock(&pMac->sme);
			return eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
		return eHAL_STATUS_SUCCESS;
	}
	return eHAL_STATUS_FAILURE;
}

#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN
/**
 * sme_add_thermal_temperature_ind_callback() - Set callback fn for thermal
 * temperature indication
 * hHal: Handler to HAL
 * callback: The callback function
 *
 * Return: void
 */
void sme_add_thermal_temperature_ind_callback(tHalHandle hHal,
				   tSmeThermalTempIndCb callback)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pMac->sme.thermal_temp_ind_cb = callback;
}
#else
inline void sme_add_thermal_temperature_ind_callback(tHalHandle hHal,
				   tSmeThermalTempIndCb callback)
{
	return;
}
#endif

/* ---------------------------------------------------------------------------
   \fn sme_TxpowerLimit
   \brief SME API to set txpower limits
   \param hHal
   \param psmetx : power limits for 2g/5g
   \- return eHalStatus
 -------------------------------------------------------------------------*/
eHalStatus sme_TxpowerLimit(tHalHandle hHal, tSirTxPowerLimit *psmetx)
{
     eHalStatus status = eHAL_STATUS_SUCCESS;
     VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
     vos_msg_t vosMessage;
     tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

     if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
     {
          vosMessage.type = WDA_TX_POWER_LIMIT;
          vosMessage.reserved = 0;
          vosMessage.bodyptr = psmetx;

          vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
          if (!VOS_IS_STATUS_SUCCESS(vosStatus))
          {
             VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                        "%s: not able to post WDA_TX_POWER_LIMIT",
                        __func__);
             status = eHAL_STATUS_FAILURE;
             vos_mem_free(psmetx);
          }
          sme_ReleaseGlobalLock(&pMac->sme);
     }
     return(status);
}

eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    pMac->fEnableDebugLog = set_value;
    return (status);
}

/* ---------------------------------------------------------------------------
  \fn    sme_ApDisableIntraBssFwd

  \brief
    SME will send message to WMA to set Intra BSS in txrx

  \param

    hHal - The handle returned by macOpen

    sessionId - session id ( vdev id)

    disablefwd - boolean value that indicate disable intrabss fwd disable

  \return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_ApDisableIntraBssFwd(tHalHandle hHal, tANI_U8 sessionId,
                                    tANI_BOOLEAN disablefwd)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    int status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    vos_msg_t vosMessage;
    tpDisableIntraBssFwd pSapDisableIntraFwd = NULL;

    //Prepare the request to send to SME.
    pSapDisableIntraFwd = vos_mem_malloc(sizeof(tDisableIntraBssFwd));
    if (NULL == pSapDisableIntraFwd)
    {
       smsLog(pMac, LOGP, "Memory Allocation Failure!!! %s", __func__);
       return eSIR_MEM_ALLOC_FAILED;
    }

    vos_mem_zero(pSapDisableIntraFwd, sizeof(tDisableIntraBssFwd));

    pSapDisableIntraFwd->sessionId = sessionId;
    pSapDisableIntraFwd->disableintrabssfwd = disablefwd;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
    {
        /* serialize the req through MC thread */
        vosMessage.bodyptr = pSapDisableIntraFwd;
        vosMessage.type    = WDA_SET_SAP_INTRABSS_DIS;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           status = eHAL_STATUS_FAILURE;
           vos_mem_free(pSapDisableIntraFwd);
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return (status);
}

#ifdef WLAN_FEATURE_STATS_EXT

/******************************************************************************
  \fn sme_StatsExtRegisterCallback

  \brief
  a function called to register the callback that send vendor event for stats
  ext

  \param callback - callback to be registered
******************************************************************************/
void sme_StatsExtRegisterCallback(tHalHandle hHal, StatsExtCallback callback)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pMac->sme.StatsExtCallback = callback;
}

/******************************************************************************
  \fn sme_StatsExtRequest

  \brief
  a function called when HDD receives STATS EXT vendor command from user space

  \param sessionID - vdevID for the stats ext request

  \param input - Stats Ext Request structure ptr

  \return eHalStatus
******************************************************************************/
eHalStatus sme_StatsExtRequest(tANI_U8 session_id, tpStatsExtRequestReq input)
{
    vos_msg_t msg;
    tpStatsExtRequest data;
    size_t data_len;

    data_len = sizeof(tStatsExtRequest) + input->request_data_len;
    data = vos_mem_malloc(data_len);

    if (data == NULL) {
        return eHAL_STATUS_FAILURE;
    }

    vos_mem_zero(data, data_len);
    data->vdev_id = session_id;
    data->request_data_len = input->request_data_len;
    if (input->request_data_len) {
        vos_mem_copy(data->request_data,
                     input->request_data, input->request_data_len);
    }

    msg.type = WDA_STATS_EXT_REQUEST;
    msg.reserved = 0;
    msg.bodyptr = data;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
                                                  &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: Not able to post WDA_STATS_EXT_REQUEST message to WDA",
                  __func__);
        vos_mem_free(data);
        return eHAL_STATUS_FAILURE;
    }

    return eHAL_STATUS_SUCCESS;
}


/******************************************************************************
  \fn sme_StatsExtEvent

  \brief
  a callback function called when SME received eWNI_SME_STATS_EXT_EVENT
  response from WDA

  \param hHal - HAL handle for device
  \param pMsg - Message body passed from WDA; includes NAN header
  \return eHalStatus
******************************************************************************/
eHalStatus sme_StatsExtEvent(tHalHandle hHal, void* pMsg)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status = eHAL_STATUS_SUCCESS;

    if (NULL == pMsg) {
        smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__);
        status = eHAL_STATUS_FAILURE;
    } else {
        smsLog(pMac, LOG2, "SME: entering %s", __func__);

        if (pMac->sme.StatsExtCallback) {
            pMac->sme.StatsExtCallback(pMac->hHdd, (tpStatsExtEvent)pMsg);
        }
    }

    return status;
}

#endif

#if defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL)
/**
 * sme_init_bad_peer_txctl_info() - SME API to initialize the bad peer
 *                                  tx flow control parameters
 * @hHal:		handle of Hal.
 * @param:		Configuration of SME module.
 *
 * Read configuation from SME module setting, and then update the setting
 * to WMA module.
 *
 * Return: Status of the WMA message sending
 */
eHalStatus sme_init_bad_peer_txctl_info( tHalHandle hHal,
			struct sme_bad_peer_txctl_param param )
{
	struct t_bad_peer_txtcl_config *p_config;
	vos_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	int i = 0;

	p_config = vos_mem_malloc(sizeof(struct t_bad_peer_txtcl_config));
	if (NULL == p_config) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: could not allocate tBadPeerInfo",
				__func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}

	vos_mem_zero((void*)p_config, sizeof(struct t_bad_peer_txtcl_config));
	p_config->enable      =	param.enabled;
	p_config->period      = param.period;
	p_config->txq_limit   = param.txq_limit;
	p_config->tgt_backoff =	param.tgt_backoff;
	p_config->tgt_report_prd = param.tgt_report_prd;

	for (i = 0; i <= WLAN_WMA_IEEE80211_AC_LEVEL; i++) {
		p_config->threshold[i].cond       = param.thresh[i].cond;
		p_config->threshold[i].delta      = param.thresh[i].delta;
		p_config->threshold[i].percentage = param.thresh[i].percentage;
		p_config->threshold[i].thresh[0]  = param.thresh[i].thresh;
		p_config->threshold[i].txlimit    = param.thresh[i].limit;
	}

	if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) {
		msg.type     = WDA_INIT_BAD_PEER_TX_CTL_INFO_CMD;
		msg.bodyptr  = p_config;

		if (!VOS_IS_STATUS_SUCCESS (
		vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) {
			VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Not able to post WDA_INIT_BAD_PEER_TX_CTL_INFO_CMD to WDA!",
				 __func__);

			vos_mem_free(p_config);
			sme_ReleaseGlobalLock(&pMac->sme);
			return eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
		return eHAL_STATUS_SUCCESS;
	}
	vos_mem_free(p_config);
	return eHAL_STATUS_FAILURE;
}
#endif /* defined(CONFIG_HL_SUPPORT) && defined(QCA_BAD_PEER_TX_FLOW_CL) */

/* ---------------------------------------------------------------------------
    \fn sme_UpdateDFSScanMode
    \brief  Update DFS roam scan mode
            This function is called through dynamic setConfig callback function
            to configure allowDFSChannelRoam.
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  allowDFSChannelRoam - DFS roaming scan mode 0 (disable),
            1 (passive), 2 (active)
    \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config
            successfully.
            Other status means SME failed to update DFS roaming scan config.
    \sa
    -------------------------------------------------------------------------*/
eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, tANI_U8 sessionId,
                                 v_U8_t allowDFSChannelRoam)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus          status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                     "LFR runtime successfully set AllowDFSChannelRoam Mode to "
                     "%d - old value is %d - roam state is %s",
                     allowDFSChannelRoam,
                     pMac->roam.configParam.allowDFSChannelRoam,
                     macTraceGetNeighbourRoamState(
                     pMac->roam.neighborRoamInfo[sessionId].neighborRoamState));
        pMac->roam.configParam.allowDFSChannelRoam = allowDFSChannelRoam;
        sme_ReleaseGlobalLock( &pMac->sme );
    }
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
       csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
                          REASON_ROAM_DFS_SCAN_MODE_CHANGED);
    }
#endif

    return status ;
}

/*--------------------------------------------------------------------------
  \brief sme_GetDFSScanMode() - get DFS roam scan mode
            This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active)
  \sa
  --------------------------------------------------------------------------*/
v_U8_t sme_GetDFSScanMode(tHalHandle hHal)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    return pMac->roam.configParam.allowDFSChannelRoam;
}


/*----------------------------------------------------------------------------
 \fn  sme_ModifyAddIE
 \brief  This function sends msg to updates the additional IE buffers in PE
 \param  hHal - global structure
 \param  pModifyIE - pointer to tModifyIE structure
 \param  updateType - type of buffer
 \- return Success or failure
-----------------------------------------------------------------------------*/
eHalStatus sme_ModifyAddIE(tHalHandle hHal,
                           tSirModifyIE *pModifyIE,
                           eUpdateIEsType updateType)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (!pMac)
        return status;

    status = sme_AcquireGlobalLock( &pMac->sme );

    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrRoamModifyAddIEs(pMac, pModifyIE, updateType);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

/*----------------------------------------------------------------------------
 \fn  sme_UpdateAddIE
 \brief  This function sends msg to updates the additional IE buffers in PE
 \param  hHal - global structure
 \param  pUpdateIE - pointer to structure tUpdateIE
 \param  updateType - type of buffer
 \- return Success or failure
-----------------------------------------------------------------------------*/
eHalStatus sme_UpdateAddIE(tHalHandle hHal,
                           tSirUpdateIE *pUpdateIE,
                           eUpdateIEsType updateType)
{
    eHalStatus status = eHAL_STATUS_FAILURE;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    if (!pMac)
       return status;

    status = sme_AcquireGlobalLock( &pMac->sme );

    if ( HAL_STATUS_SUCCESS( status ) )
    {
        status = csrRoamUpdateAddIEs(pMac, pUpdateIE, updateType);
        sme_ReleaseGlobalLock( &pMac->sme );
    }
    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_PsOffloadIsStaInPowerSave
    \brief  This function returns TRUE if STA is in power save
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \return TRUE or FALSE
    -------------------------------------------------------------------------*/
tANI_BOOLEAN sme_PsOffloadIsStaInPowerSave(tHalHandle hHal, tANI_U8 sessionId)
{
    tpAniSirGlobal pMac   = PMAC_STRUCT( hHal );
    eHalStatus     status = eHAL_STATUS_SUCCESS;
    tANI_BOOLEAN   ret    = FALSE;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        ret = pmcOffloadIsStaInPowerSave(pMac, sessionId);
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return ret;
}

VOS_STATUS sme_UpdateDSCPtoUPMapping( tHalHandle hHal,
                                      sme_QosWmmUpType  *dscpmapping,
                                      v_U8_t sessionId )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    v_U8_t i, j, peSessionId;
    tCsrRoamSession *pCsrSession = NULL;
    tpPESession pSession = NULL;

    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
        pCsrSession = CSR_GET_SESSION( pMac, sessionId );
        if (pCsrSession == NULL)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Session lookup fails for CSR session", __func__);
            sme_ReleaseGlobalLock( &pMac->sme);
            return eHAL_STATUS_FAILURE;
        }
        if (!CSR_IS_SESSION_VALID( pMac, sessionId ))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Invalid session Id %u", __func__, sessionId);
            sme_ReleaseGlobalLock( &pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        pSession = peFindSessionByBssid( pMac,
            pCsrSession->connectedProfile.bssid, &peSessionId );

        if (pSession == NULL)
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                     "%s: Session lookup fails for BSSID", __func__);
            sme_ReleaseGlobalLock( &pMac->sme);
            return eHAL_STATUS_FAILURE;
        }

        if (!pSession->QosMapSet.present) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     FL("QOS Mapping IE not present"));
            sme_ReleaseGlobalLock( &pMac->sme);
            return eHAL_STATUS_FAILURE;
        }
        else
        {
            for (i = 0; i < SME_QOS_WMM_UP_MAX; i++)
            {
                for (j = pSession->QosMapSet.dscp_range[i][0];
                               j <= pSession->QosMapSet.dscp_range[i][1]; j++)
                {
                   if ((pSession->QosMapSet.dscp_range[i][0] == 255) &&
                                (pSession->QosMapSet.dscp_range[i][1] == 255))
                   {
                       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: User Priority %d is not used in mapping",
                                                             __func__, i);
                       break;
                   }
                   else
                   {
                       dscpmapping[j]= i;
                   }
                }
            }
            for (i = 0; i< pSession->QosMapSet.num_dscp_exceptions; i++)
            {
                if (pSession->QosMapSet.dscp_exceptions[i][0] != 255)
                {
                    dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0] ] =
                                         pSession->QosMapSet.dscp_exceptions[i][1];
                }
            }
        }
    }
    sme_ReleaseGlobalLock( &pMac->sme);
    return status;
}

#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/* ---------------------------------------------------------------------------
    \fn sme_abortRoamScan
    \brief  API to abort current roam scan cycle by roam scan offload module.
    \param  hHal - The handle returned by macOpen.
    \param  sessionId - Session Identifier
    \return eHalStatus
  ---------------------------------------------------------------------------*/

eHalStatus sme_abortRoamScan(tHalHandle hHal, tANI_U8 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    smsLog(pMac, LOGW, "entering function %s", __func__);
    if (pMac->roam.configParam.isRoamOffloadScanEnabled)
    {
        /* acquire the lock for the sme object */
        status = sme_AcquireGlobalLock(&pMac->sme);
        if (HAL_STATUS_SUCCESS(status))
        {
            csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_ABORT_SCAN,
                               REASON_ROAM_ABORT_ROAM_SCAN);
            /* release the lock for the sme object */
            sme_ReleaseGlobalLock( &pMac->sme );
        }
    }

    return(status);
}
#endif //#if WLAN_FEATURE_ROAM_SCAN_OFFLOAD

#ifdef FEATURE_WLAN_EXTSCAN
/* ---------------------------------------------------------------------------
    \fn sme_GetValidChannelsByBand
    \brief  SME API to fetch all valid channels filtered by band
    \param  hHal
    \param  wifiBand: RF band information
    \param  aValidChannels: output array to store channel info
    \param  pNumChannels: output number of channels
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_GetValidChannelsByBand(tHalHandle hHal,
                                      tANI_U8 wifiBand,
                                      tANI_U32 *aValidChannels,
                                      tANI_U8 *pNumChannels)
{
    eHalStatus status                                = eHAL_STATUS_SUCCESS;
    tANI_U8 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
    tpAniSirGlobal pMac                              = PMAC_STRUCT(hHal);
    tANI_U8 numChannels                              = 0;
    tANI_U8 i                                        = 0;
    tANI_U32 totValidChannels                 = WNI_CFG_VALID_CHANNEL_LIST_LEN;

    if (!aValidChannels || !pNumChannels) {
        smsLog(pMac, VOS_TRACE_LEVEL_ERROR,
               FL("Output channel list/NumChannels is NULL"));
        return eHAL_STATUS_INVALID_PARAMETER;
    }

    if ((wifiBand < WIFI_BAND_UNSPECIFIED) || (wifiBand >= WIFI_BAND_MAX)) {
        smsLog(pMac, VOS_TRACE_LEVEL_ERROR,
                     FL("Invalid wifiBand (%d)"), wifiBand);
        return eHAL_STATUS_INVALID_PARAMETER;
    }

    status = sme_GetCfgValidChannels(hHal, &chanList[0],
                                     &totValidChannels);
    if (!HAL_STATUS_SUCCESS(status)) {
        smsLog(pMac, VOS_TRACE_LEVEL_ERROR,
               FL("Failed to get valid channel list (err=%d)"), status);
        return status;
    }

    switch (wifiBand) {
    case WIFI_BAND_UNSPECIFIED:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO, FL("Unspecified wifiBand, "
                         "return all (%d) valid channels"), totValidChannels);
            numChannels = totValidChannels;
            for (i = 0; i < totValidChannels; i++) {
                aValidChannels[i] = vos_chan_to_freq(chanList[i]);
            }
            break;

    case WIFI_BAND_BG:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO, FL("WIFI_BAND_BG (2.4 GHz)"));
            for (i = 0; i < totValidChannels; i++) {
                if (CSR_IS_CHANNEL_24GHZ(chanList[i])) {
                    aValidChannels[numChannels++] =
                                                 vos_chan_to_freq(chanList[i]);
                }
            }
            break;

    case WIFI_BAND_A:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO,
                          FL("WIFI_BAND_A (5 GHz without DFS)"));
            for (i = 0; i < totValidChannels; i++) {
                if (CSR_IS_CHANNEL_5GHZ(chanList[i]) &&
                             !CSR_IS_CHANNEL_DFS(chanList[i])) {
                    aValidChannels[numChannels++] =
                                                 vos_chan_to_freq(chanList[i]);
                }
            }
            break;

    case WIFI_BAND_ABG:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO,
                          FL("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)"));
            for (i = 0; i < totValidChannels; i++) {
                if ((CSR_IS_CHANNEL_24GHZ(chanList[i]) ||
                             CSR_IS_CHANNEL_5GHZ(chanList[i])) &&
                             !CSR_IS_CHANNEL_DFS(chanList[i])) {
                    aValidChannels[numChannels++] =
                                                 vos_chan_to_freq(chanList[i]);
                }
            }
            break;

    case WIFI_BAND_A_DFS_ONLY:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO,
                          FL("WIFI_BAND_A_DFS (5 GHz DFS only)"));
            for (i = 0; i < totValidChannels; i++) {
                if (CSR_IS_CHANNEL_5GHZ(chanList[i]) &&
                             CSR_IS_CHANNEL_DFS(chanList[i])) {
                    aValidChannels[numChannels++] =
                                                 vos_chan_to_freq(chanList[i]);
                }
            }
            break;

    case WIFI_BAND_A_WITH_DFS:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO,
                          FL("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)"));
            for (i = 0; i < totValidChannels; i++) {
                if (CSR_IS_CHANNEL_5GHZ(chanList[i])) {
                    aValidChannels[numChannels++] =
                                                 vos_chan_to_freq(chanList[i]);
                }
            }
            break;

    case WIFI_BAND_ABG_WITH_DFS:
            smsLog(pMac, VOS_TRACE_LEVEL_INFO,
                     FL("WIFI_BAND_ABG_WITH_DFS (2.4 GHz + 5 GHz with DFS)"));
            for (i = 0; i < totValidChannels; i++) {
                if (CSR_IS_CHANNEL_24GHZ(chanList[i]) ||
                             CSR_IS_CHANNEL_5GHZ(chanList[i])) {
                    aValidChannels[numChannels++] =
                                                 vos_chan_to_freq(chanList[i]);
                }
            }
            break;

    default:
            smsLog(pMac, VOS_TRACE_LEVEL_ERROR,
                    FL("Unknown wifiBand (%d))"), wifiBand);
            return eHAL_STATUS_INVALID_PARAMETER;
            break;
    }
    *pNumChannels = numChannels;

    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ExtScanGetCapabilities
    \brief  SME API to fetch extscan capabilities
    \param  hHal
    \param  pReq: extscan capabilities structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_ExtScanGetCapabilities (tHalHandle hHal,
                                     tSirGetExtScanCapabilitiesReqParams *pReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pReq;
        vosMessage.type    = WDA_EXTSCAN_GET_CAPABILITIES_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ExtScanStart
    \brief  SME API to issue extscan start
    \param  hHal
    \param  pStartCmd: extscan start structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_ExtScanStart (tHalHandle hHal,
                           tSirWifiScanCmdReqParams *pStartCmd)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pStartCmd;
        vosMessage.type    = WDA_EXTSCAN_START_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ExtScanStop
    \brief  SME API to issue extscan stop
    \param  hHal
    \param  pStopReq: extscan stop structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_ExtScanStop(tHalHandle hHal, tSirExtScanStopReqParams *pStopReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pStopReq;
        vosMessage.type    = WDA_EXTSCAN_STOP_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_SetBssHotlist
    \brief  SME API to set BSSID hotlist
    \param  hHal
    \param  pSetHotListReq: extscan set hotlist structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SetBssHotlist (tHalHandle hHal,
                          tSirExtScanSetBssidHotListReqParams *pSetHotListReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pSetHotListReq;
        vosMessage.type    = WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ResetBssHotlist
    \brief  SME API to reset BSSID hotlist
    \param  hHal
    \param  pSetHotListReq: extscan set hotlist structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_ResetBssHotlist (tHalHandle hHal,
                              tSirExtScanResetBssidHotlistReqParams *pResetReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pResetReq;
        vosMessage.type    = WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_SetSignificantChange
    \brief  SME API to set significant change
    \param  hHal
    \param  pSetSignificantChangeReq: extscan set significant change structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SetSignificantChange (tHalHandle hHal,
                    tSirExtScanSetSigChangeReqParams *pSetSignificantChangeReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pSetSignificantChangeReq;
        vosMessage.type    = WDA_EXTSCAN_SET_SIGNF_CHANGE_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ResetSignificantChange
    \brief  SME API to reset significant change
    \param  hHal
    \param  pResetReq: extscan reset significant change structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_ResetSignificantChange (tHalHandle hHal,
                        tSirExtScanResetSignificantChangeReqParams *pResetReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pResetReq;
        vosMessage.type    = WDA_EXTSCAN_RESET_SIGNF_CHANGE_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_getCachedResults
    \brief  SME API to get cached results
    \param  hHal
    \param  pCachedResultsReq: extscan get cached results structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_getCachedResults (tHalHandle hHal,
                      tSirExtScanGetCachedResultsReqParams *pCachedResultsReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pCachedResultsReq;
        vosMessage.type    = WDA_EXTSCAN_GET_CACHED_RESULTS_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
           status = eHAL_STATUS_FAILURE;

        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

/**
 * sme_get_chain_rssi - sme api to get chain rssi
 * @hHal: global hal handle
 * @input: get chain rssi req params
 *
 * Return: eHalStatus enumeration.
 */
eHalStatus sme_get_chain_rssi(tHalHandle phal,
	struct get_chain_rssi_req_params *input)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(phal);
	vos_msg_t vos_message;
	struct get_chain_rssi_req_params *req_msg;

	req_msg = vos_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
		"%s: Not able to allocate memory", __func__);
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*req_msg = *input;

	status = sme_AcquireGlobalLock(&pmac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* serialize the req through MC thread */
		vos_message.bodyptr = req_msg;
		vos_message.type    = SIR_HAL_GET_CHAIN_RSSI_REQ;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("Post Get Chain Rssi msg fail"));
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pmac->sme);
	}

	return status;
}

/**
 * sme_set_epno_list() - set epno network list
 * @hHal: global hal handle
 * @input: request message
 *
 * This function constructs the vos message and fill in message type,
 * bodyptr with %input and posts it to WDA queue.
 *
 * Return: eHalStatus enumeration
 */
eHalStatus sme_set_epno_list(tHalHandle hal,
				struct wifi_epno_params *input)
{
        eHalStatus status     = eHAL_STATUS_SUCCESS;
        VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	vos_msg_t vos_message;
	struct wifi_epno_params *req_msg;
	int len, i;

	smsLog(mac, LOG1, FL("enter"));
	len = sizeof(*req_msg) +
		    (input->num_networks * sizeof(struct wifi_epno_network));

	req_msg = vos_mem_malloc(len);
	if (!req_msg) {
		smsLog(mac, LOGE, FL("vos_mem_malloc failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	vos_mem_zero(req_msg, len);
	req_msg->num_networks = input->num_networks;
	req_msg->request_id = input->request_id;
	req_msg->session_id = input->session_id;

	/* Fill only when num_networks are non zero */
	if (req_msg->num_networks) {
		req_msg->min_5ghz_rssi = input->min_5ghz_rssi;
		req_msg->min_24ghz_rssi = input->min_24ghz_rssi;
		req_msg->initial_score_max = input->initial_score_max;
		req_msg->same_network_bonus = input->same_network_bonus;
		req_msg->secure_bonus = input->secure_bonus;
		req_msg->band_5ghz_bonus = input->band_5ghz_bonus;
		req_msg->current_connection_bonus =
			input->current_connection_bonus;

		for (i = 0; i < req_msg->num_networks; i++) {
			req_msg->networks[i].flags = input->networks[i].flags;
			req_msg->networks[i].auth_bit_field =
					input->networks[i].auth_bit_field;
			req_msg->networks[i].ssid.length =
					input->networks[i].ssid.length;
			vos_mem_copy(req_msg->networks[i].ssid.ssId,
					input->networks[i].ssid.ssId,
					req_msg->networks[i].ssid.length);
		}
	}

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	vos_message.bodyptr = req_msg;
	vos_message.type    = WDA_SET_EPNO_LIST_REQ;
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		vos_mem_free(req_msg);
		status = eHAL_STATUS_FAILURE;
	}
	sme_ReleaseGlobalLock(&mac->sme);
        return status;
}

/**
 * sme_set_passpoint_list() - set passpoint network list
 * @hal: global hal handle
 * @input: request message
 *
 * This function constructs the vos message and fill in message type,
 * bodyptr with @input and posts it to WDA queue.
 *
 * Return: eHalStatus enumeration
 */
eHalStatus sme_set_passpoint_list(tHalHandle hal,
				struct wifi_passpoint_req *input)
{
	eHalStatus status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	vos_msg_t vos_message;
	struct wifi_passpoint_req *req_msg;
	int len, i;

	smsLog(mac, LOG1, FL("enter"));
	len = sizeof(*req_msg) +
		(input->num_networks * sizeof(struct wifi_passpoint_network));
	req_msg = vos_mem_malloc(len);
	if (!req_msg) {
		smsLog(mac, LOGE, FL("vos_mem_malloc failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	vos_mem_zero(req_msg, len);
	req_msg->num_networks = input->num_networks;
	req_msg->request_id = input->request_id;
	req_msg->session_id = input->session_id;
	for (i = 0; i < req_msg->num_networks; i++) {
		req_msg->networks[i].id =
				input->networks[i].id;
		vos_mem_copy(req_msg->networks[i].realm,
				input->networks[i].realm,
				strlen(input->networks[i].realm) + 1);
		vos_mem_copy(req_msg->networks[i].plmn,
				input->networks[i].plmn,
				SIR_PASSPOINT_PLMN_LEN);
		vos_mem_copy(req_msg->networks[i].roaming_consortium_ids,
			     input->networks[i].roaming_consortium_ids,
			sizeof(req_msg->networks[i].roaming_consortium_ids));
	}

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	vos_message.bodyptr = req_msg;
	vos_message.type    = WDA_SET_PASSPOINT_LIST_REQ;
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		vos_mem_free(req_msg);
		status = eHAL_STATUS_FAILURE;
	}
	sme_ReleaseGlobalLock(&mac->sme);
        return status;
}

/**
 * sme_reset_passpoint_list() - reset passpoint network list
 * @hHal: global hal handle
 * @input: request message
 *
 * Return: eHalStatus enumeration
 */
eHalStatus sme_reset_passpoint_list(tHalHandle hal,
				    struct wifi_passpoint_req *input)
{
	eHalStatus status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	vos_msg_t vos_message;
	struct wifi_passpoint_req *req_msg;

	smsLog(mac, LOG1, FL("enter"));
	req_msg = vos_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		smsLog(mac, LOGE, FL("vos_mem_malloc failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	vos_mem_zero(req_msg, sizeof(*req_msg));
	req_msg->request_id = input->request_id;
	req_msg->session_id = input->session_id;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	vos_message.bodyptr = req_msg;
	vos_message.type    = WDA_RESET_PASSPOINT_LIST_REQ;
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		vos_mem_free(req_msg);
		status = eHAL_STATUS_FAILURE;
	}
	sme_ReleaseGlobalLock(&mac->sme);
        return status;
}

eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal,
                         void (*pExtScanIndCb)(void *, const tANI_U16, void *))
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        pMac->sme.pExtScanIndCb = pExtScanIndCb;
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

#endif /* FEATURE_WLAN_EXTSCAN */

/**
 * sme_chain_rssi_register_callback - chain rssi callback
 * @hal: global hal handle
 * @pchain_rssi_ind_cb: callback function pointer
 *
 * Return: eHalStatus enumeration.
 */
eHalStatus sme_chain_rssi_register_callback(tHalHandle phal,
			void (*pchain_rssi_ind_cb)(void *, void *))
{
	eHalStatus status    = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal pmac  = PMAC_STRUCT(phal);

	status = sme_AcquireGlobalLock(&pmac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		pmac->sme.pchain_rssi_ind_cb = pchain_rssi_ind_cb;
		sme_ReleaseGlobalLock(&pmac->sme);
	}
	return status;
}

/**
 * sme_set_rssi_threshold_breached_cb() - set rssi threshold breached callback
 * @hal: global hal handle
 * @cb: callback function pointer
 *
 * This function stores the rssi threshold breached callback function.
 *
 * Return: eHalStatus enumeration.
 */
eHalStatus sme_set_rssi_threshold_breached_cb(tHalHandle hal,
				void (*cb)(void *, struct rssi_breach_event *))
{
	eHalStatus status  = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		return status;
	}

	mac->sme.rssi_threshold_breached_cb = cb;
	sme_ReleaseGlobalLock(&mac->sme);
	return status;
}
/**
 * sme_set_chip_pwr_save_fail_cb() - set chip power save failure callback
 * @hal: global hal handle
 * @cb: callback function pointer
 *
 * This function stores the chip power save failure callback function.
 *
 * Return: eHalStatus enumeration.
 */
eHalStatus sme_set_chip_pwr_save_fail_cb(tHalHandle hal,
				void (*cb)(
				void *,
				 struct chip_pwr_save_fail_detected_params *))
{
	eHalStatus status  = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		return status;
	}

	mac->sme.chip_power_save_fail_cb = cb;
	sme_ReleaseGlobalLock(&mac->sme);
	return status;
}

/**
 * sme_set_rssi_monitoring() - set rssi monitoring
 * @hal: global hal handle
 * @input: request message
 *
 * This function constructs the vos message and fill in message type,
 * bodyptr with @input and posts it to WDA queue.
 *
 * Return: eHalStatus enumeration
 */
eHalStatus sme_set_rssi_monitoring(tHalHandle hal,
					struct rssi_monitor_req *input)
{
	eHalStatus status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac    = PMAC_STRUCT(hal);
	vos_msg_t vos_message;
	struct rssi_monitor_req *req_msg;

	smsLog(mac, LOG1, FL("enter"));
	req_msg = vos_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		smsLog(mac, LOGE, FL("memory allocation failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*req_msg = *input;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
			FL("sme_AcquireGlobalLock failed!(status=%d)"),
			status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	vos_message.bodyptr = req_msg;
	vos_message.type    = WDA_SET_RSSI_MONITOR_REQ;
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		vos_mem_free(req_msg);
	}
	sme_ReleaseGlobalLock(&mac->sme);

	return status;
}

#ifdef WLAN_FEATURE_LINK_LAYER_STATS

/* ---------------------------------------------------------------------------
    \fn sme_LLStatsClearReq
    \brief  SME API to clear Link Layer Statistics
    \param  hHal
    \param  pclearStatsReq: Link Layer clear stats request params structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_LLStatsClearReq (tHalHandle hHal,
                        tSirLLStatsClearReq *pclearStatsReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;
    tSirLLStatsClearReq *clear_stats_req;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
              "staId = %u", pclearStatsReq->staId);
    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
              "statsClearReqMask = 0x%X",
              pclearStatsReq->statsClearReqMask);
    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
              "stopReq = %u", pclearStatsReq->stopReq);

    clear_stats_req = vos_mem_malloc(sizeof(*clear_stats_req));

    if (!clear_stats_req)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: Not able to allocate memory for WDA_LL_STATS_CLEAR_REQ",
                  __func__);
        return eHAL_STATUS_FAILURE;
    }

    *clear_stats_req = *pclearStatsReq;

    if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
    {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = clear_stats_req;
        vosMessage.type    = WDA_LINK_LAYER_STATS_CLEAR_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: not able to post WDA_LL_STATS_CLEAR_REQ",
                      __func__);
           vos_mem_free(clear_stats_req);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
                "sme_AcquireGlobalLock error", __func__);
        vos_mem_free(clear_stats_req);
        status = eHAL_STATUS_FAILURE;
    }

    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_LLStatsSetReq
    \brief  SME API to set the Link Layer Statistics
    \param  hHal
    \param  psetStatsReq: Link Layer set stats request params structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_LLStatsSetReq (tHalHandle hHal,
                        tSirLLStatsSetReq *psetStatsReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;
    tSirLLStatsSetReq *set_stats_req;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
      "%s:  MPDU Size = %u", __func__,
        psetStatsReq->mpduSizeThreshold);
    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
      " Aggressive Stats Collections = %u",
      psetStatsReq->aggressiveStatisticsGathering);

    set_stats_req = vos_mem_malloc(sizeof(*set_stats_req));

    if (!set_stats_req)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: Not able to allocate memory for WDA_LL_STATS_SET_REQ",
                  __func__);
        return eHAL_STATUS_FAILURE;
    }

    *set_stats_req = *psetStatsReq;

    if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
    {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = set_stats_req;
        vosMessage.type    = WDA_LINK_LAYER_STATS_SET_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: not able to post WDA_LL_STATS_SET_REQ",
                      __func__);
           vos_mem_free(set_stats_req);
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
                "sme_AcquireGlobalLock error", __func__);
        vos_mem_free(set_stats_req);
        status = eHAL_STATUS_FAILURE;
    }

    return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_LLStatsGetReq
    \brief  SME API to get the Link Layer Statistics
    \param  hHal
    \param  pgetStatsReq: Link Layer get stats request params structure
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_LLStatsGetReq (tHalHandle hHal,
                        tSirLLStatsGetReq *pgetStatsReq)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;
    tSirLLStatsGetReq *get_stats_req;

    get_stats_req = vos_mem_malloc(sizeof(*get_stats_req));

    if (!get_stats_req)
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: Not able to allocate memory for WDA_LL_STATS_GET_REQ",
                  __func__);
        return eHAL_STATUS_FAILURE;
    }

    *get_stats_req = *pgetStatsReq;

    if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
    {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = get_stats_req;
        vosMessage.type    = WDA_LINK_LAYER_STATS_GET_REQ;
        MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
                                 NO_SESSION, vosMessage.type));
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
           VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: not able to post WDA_LL_STATS_GET_REQ",
                      __func__);

           vos_mem_free(get_stats_req);
           status = eHAL_STATUS_FAILURE;

        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
                "sme_AcquireGlobalLock error", __func__);
        vos_mem_free(get_stats_req);
        status = eHAL_STATUS_FAILURE;
    }

    return status;
}

#ifdef WLAN_POWER_DEBUGFS
/**
 * sme_power_debug_stats_req() - SME API to collect Power debug stats
 * @callback_fn: Pointer to the callback function for Power stats event
 * @power_stats_context: Pointer to context
 *
 * Return: eHalStatus
 */
eHalStatus sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
			(struct power_stats_response *response,
			void *context), void *power_stats_context)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	vos_msg_t vos_message;

	if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&mac->sme)) {
		if (NULL == callback_fn) {
			smsLog(mac, LOGE,
				FL("Indication callback did not registered"));
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_FAILURE;
		}

		mac->sme.power_debug_stats_context = power_stats_context;
		mac->sme.power_stats_resp_callback = callback_fn;
		vos_message.bodyptr = NULL;
		vos_message.type    = SIR_HAL_POWER_DEBUG_STATS_REQ;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			smsLog(mac, LOGE,
				FL("not able to post WDA_POWER_DEBUG_STATS_REQ"));
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		smsLog(mac, LOGE, FL("sme_AcquireGlobalLock error"));
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}
#endif

/**
 * eHalStatus sme_ll_stats_set_thresh - set threshold for mac counters
 * @hal, hal layer handle
 * @threshold, threshold for mac counters
 */
eHalStatus sme_ll_stats_set_thresh(tHalHandle hal,
				   struct sir_ll_ext_stats_threshold *threshold)
{
	eHalStatus status    = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
	vos_msg_t message;
	struct sir_ll_ext_stats_threshold *thresh;

	thresh = vos_mem_malloc(sizeof(*thresh));
	if (!thresh) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "%s: Fail to alloc mem", __func__);
		return eHAL_STATUS_FAILURE;
	}
	*thresh = *threshold;

	if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&mac->sme)) {
		/* Serialize the req through MC thread */
		message.bodyptr = thresh;
		message.type    = WDA_LINK_LAYER_STATS_SET_THRESHOLD;
		MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_TX_WDA_MSG,
				 NO_SESSION, message.type));
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &message);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				  "%s: not able to post WDA_LL_STATS_GET_REQ",
				  __func__);
			vos_mem_free(thresh);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock error"));
		vos_mem_free(thresh);
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_SetLinkLayerStatsIndCB
    \brief  SME API to trigger the stats are available  after get request
    \param  hHal
    \param callbackRoutine - HDD callback which needs to be invoked after
           getting status notification from FW
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SetLinkLayerStatsIndCB
(
    tHalHandle hHal,
    void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp)
)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
    {
        pMac->sme.pLinkLayerStatsIndCallback = callbackRoutine;
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
                "sme_AcquireGlobalLock error", __func__);
    }

    return(status);
}

/**
 * sme_set_link_layer_ext_cb() - Register callback for link layer statistics
 * @hal: Mac global handle
 * @ll_stats_ext_cb: HDD callback which needs to be invoked after getting
 *                    status notification from FW
 *
 * Return: eHalStatus
 */
eHalStatus sme_set_ll_ext_cb(tHalHandle hal,
			     void (*ll_stats_ext_cb)(tSirLLStatsResults *rsp))
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		mac->sme.link_layer_stats_ext_cb = ll_stats_ext_cb;
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock error"));
	}
	return status;
}

#endif /* WLAN_FEATURE_LINK_LAYER_STATS */


#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/*--------------------------------------------------------------------------
  \brief sme_UpdateRoamOffloadEnabled() - enable/disable roam offload feature
  It is used at in the REG_DYNAMIC_VARIABLE macro definition of
  \param hHal - The handle returned by macOpen.
  \param nRoamOffloadEnabled - The boolean to update with
  \return eHAL_STATUS_SUCCESS - SME update config successfully.
          Other status means SME is failed to update.
  \sa
  --------------------------------------------------------------------------*/

eHalStatus sme_UpdateRoamOffloadEnabled(tHalHandle hHal,
        v_BOOL_t nRoamOffloadEnabled)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (HAL_STATUS_SUCCESS(status))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
        "%s: LFR3:gRoamOffloadEnabled is changed from %d to %d", __func__,
                              pMac->roam.configParam.isRoamOffloadEnabled,
                                                     nRoamOffloadEnabled);
        pMac->roam.configParam.isRoamOffloadEnabled = nRoamOffloadEnabled;
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return status ;
}

/*--------------------------------------------------------------------------
  \brief sme_UpdateRoamKeyMgmtOffloadEnabled() - enable/disable key mgmt offload
  This is a synchronous call
  \param hHal - The handle returned by macOpen.
  \param  sessionId - Session Identifier
  \param nRoamKeyMgmtOffloadEnabled - The boolean to update with
  \return eHAL_STATUS_SUCCESS - SME update config successfully.
          Other status means SME is failed to update.
  \sa
  --------------------------------------------------------------------------*/

eHalStatus sme_UpdateRoamKeyMgmtOffloadEnabled(tHalHandle hHal,
                                     tANI_U8 sessionId,
                                     v_BOOL_t nRoamKeyMgmtOffloadEnabled)

{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status    = eHAL_STATUS_SUCCESS;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (HAL_STATUS_SUCCESS(status))
    {
        if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                      "%s: LFR3: KeyMgmtOffloadEnabled changed to %d",
                      __func__,
                      nRoamKeyMgmtOffloadEnabled);
            status = csrRoamSetKeyMgmtOffload(pMac,
                                              sessionId,
                                              nRoamKeyMgmtOffloadEnabled);
        } else {
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return status ;
}
#endif

/* ---------------------------------------------------------------------------
   \fn sme_GetTemperature
   \brief SME API to get the pdev temperature
   \param hHal
   \param temperature context
   \param pCallbackfn: callback fn with response (temperature)
   \- return eHalStatus
   -------------------------------------------------------------------------*/
eHalStatus sme_GetTemperature(tHalHandle hHal,
        void *tempContext,
        void (*pCallbackfn)(int temperature, void *pContext))
{
    eHalStatus          status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
    vos_msg_t           vosMessage;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        if ( (NULL == pCallbackfn) &&
                (NULL == pMac->sme.pGetTemperatureCb))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                FL("Indication Call back did not registered"));
            sme_ReleaseGlobalLock(&pMac->sme);
            return eHAL_STATUS_FAILURE;
        }
        else if (NULL != pCallbackfn)
        {
            pMac->sme.pTemperatureCbContext = tempContext;
            pMac->sme.pGetTemperatureCb = pCallbackfn;
        }
        /* serialize the req through MC thread */
        vosMessage.bodyptr = NULL;
        vosMessage.type    = WDA_GET_TEMPERATURE_REQ;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
        {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                FL("Post Get Temperature msg fail"));
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return(status);
}

/* ---------------------------------------------------------------------------
    \fn sme_SetScanningMacOui
    \brief  SME API to set scanning mac oui
    \param  hHal
    \param  pScanMacOui: Scanning Mac Oui (input 3 bytes)
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_SetScanningMacOui(tHalHandle hHal, tSirScanMacOui *pScanMacOui)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = pScanMacOui;
        vosMessage.type    = WDA_SET_SCAN_MAC_OUI_REQ;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                FL("Msg post Set Scan Mac OUI failed"));
           status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

#ifdef DHCP_SERVER_OFFLOAD
/* ---------------------------------------------------------------------------
    \fn sme_setDhcpSrvOffload
    \brief  SME API to set DHCP server offload info
    \param  hHal
    \param  pDhcpSrvInfo : DHCP server offload info struct
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_setDhcpSrvOffload(tHalHandle hHal,
                                tSirDhcpSrvOffloadInfo *pDhcpSrvInfo)
{
    vos_msg_t vosMessage;
    tSirDhcpSrvOffloadInfo *pSmeDhcpSrvInfo;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeDhcpSrvInfo = vos_mem_malloc(sizeof(*pSmeDhcpSrvInfo));

    if (!pSmeDhcpSrvInfo) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_DHCP_SERVER_OFFLOAD_CMD",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeDhcpSrvInfo = *pDhcpSrvInfo;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_DHCP_SERVER_OFFLOAD_CMD;
        vosMessage.bodyptr  = pSmeDhcpSrvInfo;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_DHCP_SERVER_OFFLOAD_CMD to WDA!",
                __func__);
            vos_mem_free(pSmeDhcpSrvInfo);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeDhcpSrvInfo);
    }

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

#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
/* ---------------------------------------------------------------------------
    \fn sme_SetLedFlashing
    \brief  API to set the Led flashing parameters.
    \param  hHal - The handle returned by macOpen.
    \param  x0, x1 -  led flashing parameters
    \param  gpio_num -  GPIO number
    \return eHalStatus
  ---------------------------------------------------------------------------*/
eHalStatus sme_SetLedFlashing (tHalHandle hHal, tANI_U8 type,
                               tANI_U32 x0, tANI_U32 x1, tANI_U32 gpio_num)
{
    eHalStatus status    = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
    vos_msg_t vosMessage;
    tSirLedFlashingReq *ledflashing;

    ledflashing = vos_mem_malloc(sizeof(*ledflashing));
    if (!ledflashing) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Not able to allocate memory for WDA_LED_TIMING_REQ"));
        return eHAL_STATUS_FAILURE;
    }

    ledflashing->pattern_id = type;
    ledflashing->led_x0 = x0;
    ledflashing->led_x1 = x1;
    ledflashing->gpio_num = gpio_num;

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* Serialize the req through MC thread */
        vosMessage.bodyptr = ledflashing;
        vosMessage.type    = WDA_LED_FLASHING_REQ;
        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
            status = eHAL_STATUS_FAILURE;
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}
#endif

/* ---------------------------------------------------------------------------
    \fn sme_handle_dfS_chan_scan
    \brief  SME API to enable/disable DFS channel scan
    \param  hHal
    \param dfs_flag: whether dfs needs to be enabled or disabled
    \return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_handle_dfs_chan_scan(tHalHandle hHal, tANI_U8 dfs_flag)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);

    status = sme_AcquireGlobalLock(&pMac->sme);

    if (eHAL_STATUS_SUCCESS == status) {

        pMac->scan.fEnableDFSChnlScan = dfs_flag;

        /* update the channel list to the firmware */
        status = csrUpdateChannelList(pMac);

        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return status;
}

#ifdef MDNS_OFFLOAD
/* ---------------------------------------------------------------------------
    \fn sme_setMDNSOffload
    \brief  SME API to set mDNS offload info
    \param  hHal
    \param  pMDNSInfo : mDNS offload info struct
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_setMDNSOffload(tHalHandle hHal,
                                tSirMDNSOffloadInfo *pMDNSInfo)
{
    vos_msg_t vosMessage;
    tSirMDNSOffloadInfo *pSmeMDNSOffloadInfo;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMDNSOffloadInfo = vos_mem_malloc(sizeof(*pSmeMDNSOffloadInfo));

    if (!pSmeMDNSOffloadInfo) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MDNS_OFFLOAD_CMD",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMDNSOffloadInfo = *pMDNSInfo;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MDNS_OFFLOAD_CMD;
        vosMessage.bodyptr  = pSmeMDNSOffloadInfo;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MDNS_OFFLOAD_CMD to WDA!",
                __func__);
            vos_mem_free(pSmeMDNSOffloadInfo);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMDNSOffloadInfo);
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_setMDNSFqdn
    \brief  SME API to set mDNS Fqdn info
    \param  hHal
    \param  pMDNSFqdnInfo : mDNS Fqdn info struct
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_setMDNSFqdn(tHalHandle hHal,
                                tSirMDNSFqdnInfo *pMDNSFqdnInfo)
{
    vos_msg_t vosMessage;
    tSirMDNSFqdnInfo *pSmeMDNSFqdnInfo;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMDNSFqdnInfo = vos_mem_malloc(sizeof(*pSmeMDNSFqdnInfo));

    if (!pSmeMDNSFqdnInfo) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MDNS_FQDN_CMD",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMDNSFqdnInfo = *pMDNSFqdnInfo;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MDNS_FQDN_CMD;
        vosMessage.bodyptr  = pSmeMDNSFqdnInfo;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MDNS_FQDN_CMD to WDA!",
                __func__);
            vos_mem_free(pSmeMDNSFqdnInfo);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMDNSFqdnInfo);
    }

    return (status);
}

/* ---------------------------------------------------------------------------
    \fn sme_setMDNSResponse
    \brief  SME API to set mDNS response info
    \param  hHal
    \param  pMDNSRespInfo : mDNS response info struct
    \- return eHalStatus
    -------------------------------------------------------------------------*/
eHalStatus sme_setMDNSResponse(tHalHandle hHal,
                                tSirMDNSResponseInfo *pMDNSRespInfo)
{
    vos_msg_t vosMessage;
    tSirMDNSResponseInfo *pSmeMDNSRespInfo;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMDNSRespInfo = vos_mem_malloc(sizeof(*pSmeMDNSRespInfo));

    if (!pSmeMDNSRespInfo) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MDNS_RESPONSE_CMD",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMDNSRespInfo = *pMDNSRespInfo;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MDNS_RESPONSE_CMD;
        vosMessage.bodyptr  = pSmeMDNSRespInfo;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MDNS_RESPONSE_CMD to WDA!",
                __func__);
            vos_mem_free(pSmeMDNSRespInfo);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMDNSRespInfo);
    }

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

#ifdef SAP_AUTH_OFFLOAD
/**
 * sme_set_sap_auth_offload() enable/disable Software AP Auth Offload
 * @hHal: hal layer handler
 * @sap_auth_offload_info: the information of Software AP Auth offload
 *
 * This function provide enable/disable Software AP authenticaiton offload
 * feature on target firmware
 *
 * Return: Return eHalStatus.
 */
eHalStatus sme_set_sap_auth_offload(tHalHandle hHal,
                      struct tSirSapOffloadInfo *sap_auth_offload_info)
{
    vos_msg_t vosMessage;
    struct tSirSapOffloadInfo *sme_sap_auth_offload_info;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pMac->sap_auth_offload_sec_type =
        sap_auth_offload_info->sap_auth_offload_sec_type;
    pMac->sap_auth_offload = sap_auth_offload_info->sap_auth_offload_enable;

    sme_sap_auth_offload_info =
        vos_mem_malloc(sizeof(*sme_sap_auth_offload_info));

    if (!sme_sap_auth_offload_info) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: Not able to allocate memory for WDA_SET_SAP_AUTH_OFL",
                  __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    vos_mem_copy(sme_sap_auth_offload_info, sap_auth_offload_info,
            sizeof(*sap_auth_offload_info));

    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_SAP_AUTH_OFL;
        vosMessage.bodyptr  = sme_sap_auth_offload_info;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                      "%s: Not able to post WDA_SET_SAP_AUTH_OFL to WDA!",
                      __func__);
            vos_mem_free(sme_sap_auth_offload_info);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  "%s: sme_AcquireGlobalLock error!",
                  __func__);
        vos_mem_free(sme_sap_auth_offload_info);
        status = eHAL_STATUS_FAILURE;
    }

    return (status);

}

/**
 * sme_set_client_block_info set client block configuration.
 *
 * @hHal: hal layer handler
 * @client_block_info: client block info struct pointer
 *
 * This function set client block info including reconnect_cnt,
 * con_fail_duration, block_duration.
 *
 * Return: Return eHalStatus.
 */
eHalStatus sme_set_client_block_info(tHalHandle hHal,
		struct sblock_info *pclient_block_info)
{
	vos_msg_t vosMessage;
	eHalStatus status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	VOS_STATUS vos_status;
	struct sblock_info *client_block_info;

	if (!pclient_block_info) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: invalid sblock_info pointer", __func__);
		return eHAL_STATUS_INVALID_PARAMETER;
	}

	client_block_info = vos_mem_malloc(sizeof(*client_block_info));
	if (NULL == client_block_info) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: fail to alloc sblock_info",
			__func__);
		return eHAL_STATUS_FAILURE;
	}

	*client_block_info = *pclient_block_info;

	status = sme_AcquireGlobalLock(&pMac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		vosMessage.type     = WDA_SET_CLIENT_BLOCK_INFO;
		vosMessage.bodyptr  = client_block_info;

		vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Not able to post msg to WDA!",
				__func__);
			vos_mem_free(client_block_info);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: sme_AcquireGlobalLock error!",
				__func__);
		vos_mem_free(client_block_info);
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}
#endif /* SAP_AUTH_OFFLOAD */

#ifdef WLAN_FEATURE_APFIND
/**
 * sme_apfind_set_cmd() - set apfind configuration to firmware
 * @input: pointer to apfind request data.
 *
 * SME API to set APFIND configuations to firmware.
 *
 * Return: VOS_STATUS.
 */
VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input)
{
     vos_msg_t msg;
     struct hal_apfind_request *data;
     size_t data_len;

     data_len = sizeof(struct hal_apfind_request) + input->request_data_len;
     data = vos_mem_malloc(data_len);

     if (data == NULL) {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                FL("Memory allocation failure"));
         return VOS_STATUS_E_FAULT;
     }

     vos_mem_zero(data, data_len);
     data->request_data_len = input->request_data_len;
     if (input->request_data_len) {
         vos_mem_copy(data->request_data,
                input->request_data, input->request_data_len);
     }

     msg.type = WDA_APFIND_SET_CMD;
     msg.reserved = 0;
     msg.bodyptr = data;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            FL("Not able to post WDA_APFIND_SET_CMD message to WDA"));
        vos_mem_free(data);
        return VOS_STATUS_SUCCESS;
    }

     return VOS_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_APFIND */

#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
eHalStatus sme_AddCSAIndCallback
(
   tHalHandle hHal,
   void (*pCallbackfn)(void *pAdapter, void *CSAindParam)
)
{
   eHalStatus          status    = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              "%s: Plug in CSA Notify CB", __func__);

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status)
    {
        if (NULL != pCallbackfn)
        {
           pMac->sme.pCSASAPIndCb = pCallbackfn;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    }

    return(status);

}
#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/*
 * sme_validate_sap_channel_switch() - validate target channel switch w.r.t
 *      concurreny rules set to avoid channel interference.
 * @hal - Hal context
 * @sap_phy_mode - phy mode of SAP
 * @cc_switch_mode - concurreny switch mode
 * @session_id - sme session id.
 *
 * Return: true if there is no channel interference else return false
 */
bool sme_validate_sap_channel_switch(tHalHandle hal,
                   uint16_t sap_ch,
                   eCsrPhyMode sap_phy_mode,
                   uint8_t cc_switch_mode,
                   uint32_t session_id)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
	uint16_t intf_channel = 0;

	if (!session)
		return false;
	session->ch_switch_in_progress = true;
	status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(status))	{
		intf_channel = csrCheckConcurrentChannelOverlap(mac, sap_ch,
						sap_phy_mode,
						cc_switch_mode);
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		smsLog(mac, LOGE, FL(" sme_AcquireGlobalLock error!"));
		session->ch_switch_in_progress = false;
		return false;
	}

	session->ch_switch_in_progress = false;
	return (intf_channel == 0)? true : false;
}
#endif

/**
 * sme_configure_stats_avg_factor() - function to config avg. stats factor
 * @hHal: hHal
 * @session_id: session ID
 * @stats_avg_factor: average stats factor
 *
 * This function configures the avg stats factor in firmware
 *
 * Return: eHalStatus
 */
eHalStatus sme_configure_stats_avg_factor(tHalHandle hHal, tANI_U8 session_id,
                                          tANI_U16 stats_avg_factor)
{
	vos_msg_t msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
	struct sir_stats_avg_factor *stats_factor;

	stats_factor = vos_mem_malloc(sizeof(*stats_factor));

	if (!stats_factor) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for WDA_SET_MDNS_RESPONSE_CMD",
			  __func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}

	status = sme_AcquireGlobalLock(&pMac->sme);

	if (eHAL_STATUS_SUCCESS == status) {

		stats_factor->vdev_id = session_id;
		stats_factor->stats_avg_factor = stats_avg_factor;

		/* serialize the req through MC thread */
		msg.type     = SIR_HAL_CONFIG_STATS_FACTOR;
		msg.bodyptr  = stats_factor;

		if (!VOS_IS_STATUS_SUCCESS(
			    vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) {
			VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				   "%s: Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!",
				   __func__);
			vos_mem_free(stats_factor);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
	} else {
		VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			   "%s: sme_AcquireGlobalLock error!",
			   __func__);
		vos_mem_free(stats_factor);
	}

	return status;
}

/**
 * sme_configure_guard_time() - function to configure guard time
 * @hHal:   SME API to enable/disable DFS channel scan
 * @session_id: session ID
 * @guard_time: Guard time
 *
 * This function configures the guard time in firmware
 *
 * Return: eHalStatus
 */
eHalStatus sme_configure_guard_time(tHalHandle hHal, tANI_U8 session_id,
                                    tANI_U32 guard_time)
{
	vos_msg_t msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal pMac  = PMAC_STRUCT(hHal);
	struct sir_guard_time_request *g_time;

	g_time = vos_mem_malloc(sizeof(*g_time));

	if (!g_time) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for SIR_HAL_CONFIG_GUARD_TIME",
			  __func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}

	status = sme_AcquireGlobalLock(&pMac->sme);

	if (eHAL_STATUS_SUCCESS == status) {

		g_time->vdev_id = session_id;
		g_time->guard_time = guard_time;

		/* serialize the req through MC thread */
		msg.type     = SIR_HAL_CONFIG_GUARD_TIME;
		msg.bodyptr  = g_time;

		if (!VOS_IS_STATUS_SUCCESS(
			    vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) {
			VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				   "%s: Not able to post SIR_HAL_CONFIG_GUARD_TIME to WDA!",
				   __func__);
			vos_mem_free(g_time);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
	} else {
		VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			   "%s: sme_AcquireGlobalLock error!",
			   __func__);
		vos_mem_free(g_time);
	}

	return status;
}

/**
 * sme_update_roam_scan_hi_rssi_scan_params() - update high rssi scan
 *         params
 * @hal_handle - The handle returned by macOpen.
 * @session_id - Session Identifier
 * @notify_id - Identifies 1 of the 4 parameters to be modified
 * @val New value of the parameter
 *
 * Return: eHAL_STATUS_SUCCESS - SME update config successful.
 *         Other status means SME failed to update
 */

eHalStatus sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle,
	uint8_t session_id,
	uint32_t notify_id,
	int32_t val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status  = eHAL_STATUS_SUCCESS;
	tCsrNeighborRoamConfig *nr_config = NULL;
	tpCsrNeighborRoamControlInfo nr_info = NULL;
	uint32_t reason = 0;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		nr_config = &mac_ctx->roam.configParam.neighborRoamConfig;
		nr_info   = &mac_ctx->roam.neighborRoamInfo[session_id];
		switch (notify_id) {
		case eCSR_HI_RSSI_SCAN_MAXCOUNT_ID:
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
				"%s: gRoamScanHirssiMaxCount is changed from %d to %d",
				__func__, nr_config->nhi_rssi_scan_max_count,
				val);
			nr_config->nhi_rssi_scan_max_count = val;
			nr_info->cfgParams.hi_rssi_scan_max_count = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED;
		break;

		case eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID:
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
				"%s: gRoamScanHiRssiDelta is changed from %d to %d",
				__func__, nr_config->nhi_rssi_scan_rssi_delta,
				val);
			nr_config->nhi_rssi_scan_rssi_delta = val;
			nr_info->cfgParams.hi_rssi_scan_rssi_delta = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED;
			break;

		case eCSR_HI_RSSI_SCAN_DELAY_ID:
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
				"%s: gRoamScanHiRssiDelay is changed from %d to %d",
				__func__, nr_config->nhi_rssi_scan_delay,
				val);
			nr_config->nhi_rssi_scan_delay = val;
			nr_info->cfgParams.hi_rssi_scan_delay = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED;
			break;

		case eCSR_HI_RSSI_SCAN_RSSI_UB_ID:
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
				"%s: gRoamScanHiRssiUpperBound is changed from %d to %d",
				__func__,
				nr_config->nhi_rssi_scan_rssi_ub,
				val);
			nr_config->nhi_rssi_scan_rssi_ub = val;
			nr_info->cfgParams.hi_rssi_scan_rssi_ub = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED;
			break;

		default:
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: invalid parameter notify_id %d", __func__,
				notify_id);
			status = eHAL_STATUS_INVALID_PARAMETER;
			break;
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
	if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled &&
		status == eHAL_STATUS_SUCCESS) {
		csrRoamOffloadScan(mac_ctx, session_id,
			ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
	}
#endif

	return status;
}

/**
 * sme_configure_modulated_dtim() - function to configure modulated dtim
 * @h_hal: SME API to enable/disable modulated DTIM instantaneously
 * @session_id: session ID
 * @modulated_dtim: modulated dtim value
 *
 * This function configures the guard time in firmware
 *
 * Return: eHalStatus
 */
eHalStatus sme_configure_modulated_dtim(tHalHandle h_hal, tANI_U8 session_id,
				      tANI_U32 modulated_dtim)
{
	vos_msg_t msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal pMac  = PMAC_STRUCT(h_hal);
	wda_cli_set_cmd_t *iwcmd;

	iwcmd = vos_mem_malloc(sizeof(*iwcmd));
	if (NULL == iwcmd) {
		VOS_TRACE(VOS_MODULE_ID_SME,
			  VOS_TRACE_LEVEL_FATAL,
			  "%s: vos_mem_malloc failed", __func__);
		return eHAL_STATUS_FAILED_ALLOC;
	}

	status = sme_AcquireGlobalLock(&pMac->sme);

	if (eHAL_STATUS_SUCCESS == status) {

		vos_mem_zero((void *)iwcmd, sizeof(*iwcmd));
		iwcmd->param_value = modulated_dtim;
		iwcmd->param_vdev_id = session_id;
		iwcmd->param_id = GEN_PARAM_MODULATED_DTIM;
		iwcmd->param_vp_dev = GEN_CMD;
		msg.type = WDA_CLI_SET_CMD;
		msg.reserved = 0;
		msg.bodyptr = (void *)iwcmd;

		if (!VOS_IS_STATUS_SUCCESS(
			    vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) {
			VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				   "%s: Not able to post SIR_HAL_CONFIG_GUARD_TIME to WDA!",
				   __func__);
			vos_mem_free(iwcmd);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
	} else {
		VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			   "%s: sme_AcquireGlobalLock error!",
			   __func__);
		vos_mem_free(iwcmd);
	}

	return status;
}

/**
 * sme_mnt_filter_type_cmd() - set filter packet type to firmware
 * @input: pointer to filter type request data.
 *
 * Return: VOS_STATUS.
 */
VOS_STATUS sme_mnt_filter_type_cmd(struct sme_mnt_filter_type_req *input)
{
    vos_msg_t msg;
    struct hal_mnt_filter_type_request *data;
    size_t data_len;

    data_len = sizeof(struct hal_mnt_filter_type_request) + input->request_data_len;
    data = vos_mem_malloc(data_len);

    if (data == NULL) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Memory allocation failure"));
        return VOS_STATUS_E_FAULT;
    }

    vos_mem_zero(data, data_len);
    data->request_data_len = input->request_data_len;
    data->vdev_id = input->vdev_id;
    if (input->request_data_len) {
        vos_mem_copy(data->request_data,
                input->request_data, input->request_data_len);
    }

    msg.type = WDA_MNT_FILTER_TYPE_CMD;
    msg.reserved = 0;
    msg.bodyptr = data;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
        FL("Not able to post WDA_MNT_FILTER_TYPE_CMD message to WDA"));
        vos_mem_free(data);
        return VOS_STATUS_SUCCESS;
    }

    return VOS_STATUS_SUCCESS;
}

#define THROTTLE_PERIOD_MIN        (10)
#define THROTTLE_PERIOD_MAX        (10000)
#define THROTTLE_TX_THRESHOLD_MIN  (1)
#define THROTTLE_TX_THRESHOLD_MAX  (400)
#define MAX_DUTY_CYCLE_VAL         (100)

eHalStatus sme_hpcs_pulse_params_conf_cmd(tHalHandle hHal,
                                          tSirHpcsPulseParmasConfig *pHpcsPulseParams)
{
    vos_msg_t msg;
    struct hal_hpcs_pulse_params *hpcs_pulse_params;

    hpcs_pulse_params = vos_mem_malloc(sizeof(*hpcs_pulse_params));
    if (!hpcs_pulse_params) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to allocate memory"));
        return eHAL_STATUS_FAILED_ALLOC;
    }

    vos_mem_zero(hpcs_pulse_params, sizeof(*hpcs_pulse_params));

    hpcs_pulse_params->vdev_id            = pHpcsPulseParams->vdev_id;
    hpcs_pulse_params->start              = pHpcsPulseParams->start;
    hpcs_pulse_params->sync_time          = pHpcsPulseParams->sync_time;
    hpcs_pulse_params->pulse_interval     = pHpcsPulseParams->pulse_interval;
    hpcs_pulse_params->active_sync_period = pHpcsPulseParams->active_sync_period;
    hpcs_pulse_params->gpio_pin           = pHpcsPulseParams->gpio_pin;
    hpcs_pulse_params->pulse_width        = pHpcsPulseParams->pulse_width;

    msg.type = WDA_SET_HPCS_PULSE_PARAMS;
    msg.reserved = 0;
    msg.bodyptr = hpcs_pulse_params;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to post WMI_HPCS_PULSE_START_CMDID message"));
        vos_mem_free(hpcs_pulse_params);
        return eHAL_STATUS_FAILURE;
    }
    return eHAL_STATUS_SUCCESS;
}

eHalStatus sme_thermal_throttle_mgmt_cmd(tHalHandle hHal, tANI_U16 lower_thresh_deg,
                                         tANI_U16 higher_thresh_deg)
{
    vos_msg_t msg;
    struct hal_thermal_mgmt_cmd_params *therm_mgmt_cmd;

    therm_mgmt_cmd = vos_mem_malloc(sizeof(*therm_mgmt_cmd));
    if (!therm_mgmt_cmd) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to allocate memory"));
        return eHAL_STATUS_FAILED_ALLOC;
    }

    vos_mem_zero(therm_mgmt_cmd, sizeof(*therm_mgmt_cmd));

    therm_mgmt_cmd->min_temp = lower_thresh_deg;
    therm_mgmt_cmd->max_temp = higher_thresh_deg;
    therm_mgmt_cmd->enable = 1;

    msg.type = WDA_THERMAL_MGMT_CMD;
    msg.reserved = 0;
    msg.bodyptr = therm_mgmt_cmd;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to post WDA_THERMAL_MGMT_CMD message"));
        vos_mem_free(therm_mgmt_cmd);
        return eHAL_STATUS_FAILURE;
    }
    return eHAL_STATUS_SUCCESS;
}

eHalStatus sme_thermal_throttle_set_conf_cmd(tHalHandle hHal, bool enable,
                                             tANI_U32 dc, tANI_U32 dc_off_percent,
                                             tANI_U32 prio)
{
    vos_msg_t msg;
    struct hal_thermal_mitigation_params *therm_data;

    therm_data = vos_mem_malloc(sizeof(*therm_data));
    if (!therm_data) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to allocate memory"));
        return eHAL_STATUS_FAILED_ALLOC;
    }

    vos_mem_zero(therm_data, sizeof(*therm_data));


    therm_data->enable = enable;
    therm_data->dc = dc;
    therm_data->level_conf[0].dcoffpercent = dc_off_percent;
    therm_data->level_conf[0].priority = prio;

    msg.type = WDA_THERM_THROT_SET_CONF_CMD;
    msg.reserved = 0;
    msg.bodyptr = therm_data;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to post WMI_THERM_THROT_SET_CONF_CMDID message"));
        vos_mem_free(therm_data);
        return eHAL_STATUS_FAILURE;
    }
    return eHAL_STATUS_SUCCESS;
}

eHalStatus sme_cfr_capture_configure(struct sme_peer_cfr_capture_conf arg)
{
    vos_msg_t msg;
    struct sme_peer_cfr_capture_conf *cfr_cfg_data;
    cfr_cfg_data = vos_mem_malloc(sizeof(*cfr_cfg_data));
    if (!cfr_cfg_data) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to allocate memory"));
        return eHAL_STATUS_FAILED_ALLOC;
    }

    vos_mem_zero(cfr_cfg_data, sizeof(*cfr_cfg_data));

    memcpy(cfr_cfg_data, &arg, sizeof(*cfr_cfg_data));

    msg.type = WDA_PEER_CFR_CAPTURE_CONF_CMD;
    msg.reserved = 0;
    msg.bodyptr = cfr_cfg_data;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to post WDA_PEER_CFR_CAPTURE_CONF_CMD message"));
        vos_mem_free(cfr_cfg_data);
        return eHAL_STATUS_FAILURE;
    }
    return eHAL_STATUS_SUCCESS;
}

eHalStatus sme_periodic_cfr_enable(u8 cfr_enable)
{
    vos_msg_t msg;
    u8 *cfr_data;

    cfr_data = vos_mem_malloc(sizeof(*cfr_data));
    if (!cfr_data) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to allocate memory"));
        return eHAL_STATUS_FAILED_ALLOC;
    }

    *cfr_data = cfr_enable;

    msg.type = WDA_PERIODIC_CFR_ENABLE_CMD;
    msg.reserved = 0;
    msg.bodyptr = cfr_data;

    if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                  FL("Unable to post WDA_PEER_CFR_CAPTURE_CONF_CMD message"));
        vos_mem_free(cfr_data);
        return eHAL_STATUS_FAILURE;
    }
    return eHAL_STATUS_SUCCESS;
}

/**
 * sme_set_tsfcb() - set callback which to handle WMI_VDEV_TSF_REPORT_EVENTID
 *
 * @hHal: Handler return by macOpen.
 * @pcallbackfn: callback to handle the tsf event
 * @pcallbackcontext: callback context
 *
 * Return: eHalStatus.
 */
eHalStatus sme_set_tsfcb
(
	tHalHandle hHal,
	int (*pcallbackfn)(void *pcallbackcontext, struct stsf *pTsf),
	void *pcallbackcontext
)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	eHalStatus status;

	status = sme_AcquireGlobalLock(&pMac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		pMac->sme.get_tsf_cb = pcallbackfn;
		pMac->sme.get_tsf_cxt = pcallbackcontext;
		sme_ReleaseGlobalLock(&pMac->sme);
	}
	return status;
}

#ifdef WLAN_FEATURE_TSF
/*
 * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tef
 *
 * @hHal: Handler return by macOpen
 * @pinvalue: gpio pin id
 *
 * Return: eHalStatus
 */
eHalStatus sme_set_tsf_gpio(tHalHandle hHal, uint32_t pinvalue)
{
	eHalStatus status;
	VOS_STATUS vos_status;
	vos_msg_t vos_msg = {0};
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_AcquireGlobalLock(&pMac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		vos_msg.type = WDA_TSF_GPIO_PIN;
		vos_msg.reserved = 0;
		vos_msg.bodyval = pinvalue;

		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: not able to post WDA_TSF_GPIO_PIN",
				__func__);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&pMac->sme);
	}
	return status;
}
#endif

/*
 * sme_wifi_start_logger() - This function send the command to WMA
 * to either start/stop logging
 * @hal: HAL context
 * @start_log: Structure containing the wifi start logger params
 *
 * This function send the command to WMA to either start/stop logging
 *
 * Return: eHAL_STATUS_SUCCESS on successful posting
 */
eHalStatus sme_wifi_start_logger(tHalHandle hal,
		struct sir_wifi_start_log start_log)
{
	eHalStatus status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	vos_msg_t vos_message;
	struct sir_wifi_start_log *req_msg;
	uint32_t len;

	len = sizeof(*req_msg);
	req_msg = vos_mem_malloc(len);
	if (!req_msg) {
		smsLog(mac, LOGE, FL("vos_mem_malloc failed"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	vos_mem_zero(req_msg, len);

	req_msg->verbose_level = start_log.verbose_level;
	req_msg->flag = start_log.flag;
	req_msg->ring_id = start_log.ring_id;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status != eHAL_STATUS_SUCCESS) {
		smsLog(mac, LOGE,
				FL("sme_AcquireGlobalLock failed!(status=%d)"),
				status);
		vos_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	vos_message.bodyptr = req_msg;
	vos_message.type    = SIR_HAL_START_STOP_LOGGING;
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
				FL("vos_mq_post_message failed!(err=%d)"),
				vos_status);
		vos_mem_free(req_msg);
		status = eHAL_STATUS_FAILURE;
	}
	sme_ReleaseGlobalLock(&mac->sme);
	return status;
}

/**
 * smeNeighborMiddleOfRoaming() - Function to know if
 * STA is in the middle of roaming states
 * @hal:                Handle returned by macOpen
 * @sessionId: sessionId of the STA session
 *
 * This function is a wrapper to call
 * csrNeighborMiddleOfRoaming to know if
 * STA is in the middle of roaming states
 *
 * Return: True or False
 *
 */
bool smeNeighborMiddleOfRoaming(tHalHandle hHal, tANI_U8 sessionId)
{
	return csrNeighborMiddleOfRoaming(PMAC_STRUCT(hHal), sessionId);
}

/**
 * sme_update_nss() - SME API to change the number for spatial streams (1 or 2)
 * @hal:            - Handle returned by macOpen
 * @nss:            - Number of spatial streams
 *
 * This function is used to update the number of spatial streams supported.
 *
 * Return: Success upon successfully changing nss else failure
 *
 */
eHalStatus sme_update_nss(tHalHandle h_hal, uint8_t nss)
{
	eHalStatus status;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
	uint32_t  i, value = 0;
	union {
		uint16_t                        cfg_value16;
		tSirMacHTCapabilityInfo         ht_cap_info;
	} uHTCapabilityInfo;
	tCsrRoamSession *csr_session;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);

	if (eHAL_STATUS_SUCCESS == status) {
		mac_ctx->roam.configParam.enable2x2 = (nss == 1) ? 0 : 1;

		/* get the HT capability info*/
		ccmCfgGetInt(mac_ctx, WNI_CFG_HT_CAP_INFO, &value);
		uHTCapabilityInfo.cfg_value16 = (0xFFFF & value);

		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
			if (CSR_IS_SESSION_VALID(mac_ctx, i)) {
				csr_session = &mac_ctx->roam.roamSession[i];
				csr_session->htConfig.ht_tx_stbc =
					uHTCapabilityInfo.ht_cap_info.txSTBC;
			}
		}

		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}

	return status;
}

uint8_t sme_is_any_session_in_connected_state(tHalHandle h_hal)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
	eHalStatus     status;
	uint8_t        ret     = FALSE;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		ret = csrIsAnySessionInConnectState(mac_ctx);
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}
	return ret;
}

/**
 * vos_send_flush_logs_cmd_to_fw() - Flush FW logs
 * @mac: MAC handle
 *
 * This function is used to send the command that will
 * be used to flush the logs in the firmware
 *
 * Return: eHalStatus
 */
eHalStatus vos_send_flush_logs_cmd_to_fw(tpAniSirGlobal mac)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status;
	vos_msg_t vos_message;

	/* Serialize the req through MC thread */
	vos_message.bodyptr = NULL;
	vos_message.type    = SIR_HAL_FLUSH_LOG_TO_FW;
	vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		smsLog(mac, LOGE,
			FL("vos_mq_post_message failed!(err=%d)"),
			vos_status);
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}

/**
 * sme_handle_set_fcc_channel() - set specific txPower for non-fcc channel
 * @hal: HAL pointer
 * @fcc_constraint: true: disable, false; enable
 *
 * Return: eHalStatus.
 */
eHalStatus sme_handle_set_fcc_channel(tHalHandle hal, bool fcc_constraint,
		uint32_t scan_pending)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac_ptr  = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac_ptr->sme);

	if (eHAL_STATUS_SUCCESS == status) {
		if (fcc_constraint != mac_ptr->scan.fcc_constraint) {
			mac_ptr->scan.fcc_constraint = fcc_constraint;
			if (scan_pending == TRUE) {
				mac_ptr->scan.defer_update_channel_list = true;
			} else {
				/* update the channel list to the firmware */
				status = csrUpdateChannelList(mac_ptr);
			}
		}
	}
	sme_ReleaseGlobalLock(&mac_ptr->sme);

	return status;
}

/**
 * sme_set_sta_chanlist_with_sub20()- update channel list with 5/10M
 * info
 * @hal_ptr: Hal context pointor
 * @chan_width: 5/10M channel width info
 *
 * Return: eHalStatus
 */
eHalStatus
sme_set_sta_chanlist_with_sub20(tHalHandle hal_ptr, uint8_t chan_width)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac_ptr  = PMAC_STRUCT(hal_ptr);

	status = sme_AcquireGlobalLock(&mac_ptr->sme);

	if (eHAL_STATUS_SUCCESS == status) {
		mac_ptr->sub20_channelwidth = chan_width;
		mac_ptr->sta_sub20_current_channelwidth = chan_width;
		status = csrUpdateChannelList(mac_ptr);
	}
	sme_ReleaseGlobalLock(&mac_ptr->sme);

	return status;
}

/**
 * sme_enable_phy_error_logs() - Enable DFS phy error logs
 * @hal:        global hal handle
 * @enable_log: value to set
 *
 * Since the frequency of DFS phy error is very high, enabling logs for them
 * all the times can cause crash and will also create lot of useless logs
 * causing difficulties in debugging other issue. This function will be called
 * from iwpriv cmd to eanble such logs temporarily.
 *
 * Return: void
 */
void sme_enable_phy_error_logs(tHalHandle hal, bool enable_log)
{
    tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
    mac_ctx->sap.enable_dfs_phy_error_logs = enable_log;
}

/**
 * sme_SetDefDot11Mode() - Updates pMac with default dot11mode
 * @hal: Global MAC pointer
 *
 * Return: NULL.
 */
void sme_SetDefDot11Mode(tHalHandle hal)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT( hal );
	csrSetDefaultDot11Mode(mac_ctx);
}

/**
 * sme_update_user_configured_nss() - sets the nss based on user request
 * @hal: Pointer to HAL
 * @nss: number of streams
 *
 * Return: None
 */
void sme_update_user_configured_nss(tHalHandle hal, uint8_t nss)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	mac_ctx->user_configured_nss = nss;
}

/**
 * sme_set_vdev_nss() - sets the vdev nss based on INI
 * @hal: Pointer to HAL
 * @enable2x2: 1x1 or 2x2 mode.
 *
 * Sets the per band Nss for each vdev type based on INI.
 *
 * Return: None
 */
void sme_set_vdev_nss(tHalHandle hal, bool enable2x2)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct vdev_type_nss *vdev_nss;
	uint8_t i;
	uint8_t nss_val;
	uint8_t coex;

	if (enable2x2) {
		if (mac_ctx->lteCoexAntShare)
			coex = 1;
		else
			coex = 0;
		nss_val = 2;
	} else {
		nss_val = 1;
		coex = 0;
	}
	mac_ctx->user_configured_nss = nss_val;

	vdev_nss = &mac_ctx->vdev_type_nss_2g;

	for (i = 0; i < NUM_OF_BANDS; i++) {
		vdev_nss->sta = nss_val;
		vdev_nss->sap = nss_val - coex;
		vdev_nss->p2p_go = nss_val - coex;
		vdev_nss->p2p_cli = nss_val - coex;
		vdev_nss->p2p_dev = nss_val - coex;
		vdev_nss->ibss = nss_val - coex;
		vdev_nss->tdls = nss_val - coex;
		vdev_nss->ocb = nss_val - coex;

		vdev_nss = &mac_ctx->vdev_type_nss_5g;
		coex = 0;
	}
}

/**
 * sme_update_vdev_type_nss() - sets the nss per vdev type
 * @hal: Pointer to HAL
 * @max_supp_nss: max_supported Nss
 * @band: 5G or 2.4G band
 *
 * Sets the per band Nss for each vdev type based on INI and configured
 * chain mask value.
 *
 * Return: None
 */
void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss,
		uint32_t vdev_type_nss, eCsrBand band)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct vdev_type_nss *vdev_nss;

	if (eCSR_BAND_5G == band) {
		vdev_nss = &mac_ctx->vdev_type_nss_5g;
	} else {
		vdev_nss = &mac_ctx->vdev_type_nss_2g;
	}

	vdev_nss->sta = VOS_MIN(max_supp_nss, CFG_STA_NSS(vdev_type_nss));
	vdev_nss->sap = VOS_MIN(max_supp_nss, CFG_SAP_NSS(vdev_type_nss));
	vdev_nss->p2p_go = VOS_MIN(max_supp_nss,
				CFG_P2P_GO_NSS(vdev_type_nss));
	vdev_nss->p2p_cli = VOS_MIN(max_supp_nss,
				CFG_P2P_CLI_NSS(vdev_type_nss));
	vdev_nss->p2p_dev = VOS_MIN(max_supp_nss,
				CFG_P2P_DEV_NSS(vdev_type_nss));
	vdev_nss->ibss = VOS_MIN(max_supp_nss, CFG_IBSS_NSS(vdev_type_nss));
	vdev_nss->tdls = VOS_MIN(max_supp_nss, CFG_TDLS_NSS(vdev_type_nss));
	vdev_nss->ocb = VOS_MIN(max_supp_nss, CFG_OCB_NSS(vdev_type_nss));
	mac_ctx->user_configured_nss = max_supp_nss;

	smsLog(mac_ctx, LOG1,
           "band %d NSS: sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d",
           band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli,
           vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss,
           vdev_nss->tdls, vdev_nss->ocb);
}

/**
 * sme_set_per_band_chainmask_supp() - sets the per band chainmask support
 * @hal: Pointer to HAL
 * @val: Value to be set.
 *
 * Sets the per band chain mask support to mac context.
 * Return: None
 */
void sme_set_per_band_chainmask_supp(tHalHandle hal, bool val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	mac_ctx->per_band_chainmask_supp = val;
}

/**
 * sme_set_lte_coex_supp() - sets the lte coex antenna share support
 * @hal: Pointer to HAL
 * @val: Value to be set.
 *
 * Sets the lte coex antenna share support to mac context.
 * Return: None
 */
void sme_set_lte_coex_supp(tHalHandle hal, bool val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	mac_ctx->lteCoexAntShare = val;
}

/**
 * sme_set_bcon_offload_supp() - sets the beacon offload support
 * @hal: Pointer to HAL
 * @val: Value to be set.
 *
 * Sets the beacon offload support to mac context.
 * Return: None
 */
void sme_set_bcon_offload_supp(tHalHandle hal, bool val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	mac_ctx->beacon_offload = val;
}

#ifdef FEATURE_WLAN_TDLS

/**
 * sme_get_opclass() - determine operating class
 * @hal: Pointer to HAL
 * @channel: channel id
 * @bw_offset: bandwidth offset
 * @opclass: pointer to operating class
 *
 * Function will determine operating class from regdm_get_opclass_from_channel
 *
 * Return: none
 */
void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset,
			uint8_t *opclass)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	/* redgm opclass table contains opclass for 40MHz low primary,
	 * 40MHz high primary and 20MHz. No support for 80MHz yet. So
	 * first we will check if bit for 40MHz is set and if so find
	 * matching opclass either with low primary or high primary
	 * (a channel would never be in both) and then search for opclass
	 * matching 20MHz, else for any BW.
	 */
	if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
		*opclass = regdm_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				channel,
				BW40_LOW_PRIMARY);
		if (!(*opclass)) {
			*opclass = regdm_get_opclass_from_channel(
					mac_ctx->scan.countryCodeCurrent,
					channel,
					BW40_HIGH_PRIMARY);
		}
	} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
		*opclass = regdm_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				channel,
				BW20);
	} else {
		*opclass = regdm_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				channel,
				BWALL);
	}
}

#endif



#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
/**
 * sme_set_udp_resp_offload() - set udp response payload.
 * @pudp_resp_cmd: specific udp and response udp payload struct pointer
 *
 * This function set specific udp and response udp payload info
 * including enable dest_port,udp_payload, resp_payload.
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_udp_resp_offload(struct udp_resp_offload *pudp_resp_cmd)
{
	vos_msg_t vos_message;
	VOS_STATUS vos_status;
	struct udp_resp_offload *udp_resp_cmd;

	if (!pudp_resp_cmd) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: invalid pudp_resp_cmd pointer", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	udp_resp_cmd = vos_mem_malloc(sizeof(*udp_resp_cmd));
	if (NULL == udp_resp_cmd) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc sudp_cmd", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	*udp_resp_cmd = *pudp_resp_cmd;

	vos_message.type = WDA_SET_UDP_RESP_OFFLOAD;
	vos_message.bodyptr = udp_resp_cmd;
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Not able to post msg to WDA!",
				__func__);
		vos_mem_free(udp_resp_cmd);
		vos_status = VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}
#endif

/**
 * sme_set_lost_link_info_cb() - plug in callback function for receiving
 * lost link info
 * @hal: HAL handle
 * @cb: callback function
 *
 * Return: HAL status
 */
eHalStatus sme_set_lost_link_info_cb(tHalHandle hal,
				     void (*cb)(void *,
				     struct sir_lost_link_info *))
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		mac->sme.lost_link_info_cb = cb;
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
			  "%s: set lost link info callback", __func__);
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "%s: sme_AcquireGlobalLock error status %d",
			  __func__, status);
	}
	return status;
}

/**
 * sme_set_smps_force_mode_cb() - callback set by HDD for smps
 * force mode event
 * @hal: The handle returned by macOpen
 * @cb: callback function
 *
 * Return: eHAL_STATUS_SUCCESS if callback was set successfully
 * else failure status
 */
eHalStatus sme_set_smps_force_mode_cb(tHalHandle hal,
				void (*cb)(void *,
				struct sir_smps_force_mode_event *))
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		mac->sme.smps_force_mode_cb = cb;
		sme_ReleaseGlobalLock(&mac->sme);
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
			"%s: set smps force mode callback", __func__);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "%s: sme_AcquireGlobalLock error status %d",
			  __func__, status);
	}
	return status;
}

#ifdef WLAN_FEATURE_WOW_PULSE
/**
 * sme_set_wow_pulse() - set wow pulse info
 * @wow_pulse_set_info: wow_pulse_mode structure pointer
 *
 * Return: HAL status
 */
VOS_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
{
	vos_msg_t vos_message;
	VOS_STATUS vos_status;
	struct wow_pulse_mode *wow_pulse_set_cmd;

	if (!wow_pulse_set_info) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: invalid wow_pulse_set_info pointer", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	wow_pulse_set_cmd = vos_mem_malloc(sizeof(*wow_pulse_set_cmd));
	if (NULL == wow_pulse_set_cmd) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: fail to alloc wow_pulse_set_cmd", __func__);
		return VOS_STATUS_E_NOMEM;
	}

	*wow_pulse_set_cmd = *wow_pulse_set_info;

	vos_message.type = WDA_SET_WOW_PULSE_CMD;
	vos_message.bodyptr = wow_pulse_set_cmd;
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);
		vos_mem_free(wow_pulse_set_cmd);
		vos_status = VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}
#endif

/**
 * sme_set_wakeup_gpio() - set wakeup gpio info
 * @wakeup_gpio_info: wakeup_gpio_mode structure pointer
 *
 * Return: HAL status
 */
VOS_STATUS sme_set_wakeup_gpio(struct wakeup_gpio_mode *wakeup_gpio_info)
{
	vos_msg_t vos_message;
	VOS_STATUS vos_status;
	struct wakeup_gpio_mode *wakeup_gpio_cmd;

	if (!wakeup_gpio_info) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: invalid wakeup_gpio_info pointer", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	wakeup_gpio_cmd = vos_mem_malloc(sizeof(*wakeup_gpio_cmd));
	if (NULL == wakeup_gpio_cmd) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: fail to alloc wakeup_gpio_cmd", __func__);
		return VOS_STATUS_E_NOMEM;
	}

	*wakeup_gpio_cmd = *wakeup_gpio_info;

	vos_message.type = WDA_SET_WAKEUP_GPIO_CMD;
	vos_message.bodyptr = wakeup_gpio_cmd;
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);
		vos_mem_free(wakeup_gpio_cmd);
		vos_status = VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

#ifdef FEATURE_GREEN_AP
/**
 * sme_send_egap_conf_params() - set the enhanced green ap configuration params
 *
 * @enable: enable/disable the enhanced green ap feature
 * @inactivity_time: inactivity timeout value
 * @wait_time: wait timeout value
 * @flag: feature flag in bitmasp
 *
 * Return: Return VOS_STATUS, otherwise appropriate failure code
 */
VOS_STATUS sme_send_egap_conf_params(uint32_t enable, uint32_t inactivity_time,
				     uint32_t wait_time, uint32_t flags)
{
	vos_msg_t vos_message;
	VOS_STATUS vos_status;
	struct egap_conf_params *egap_params;

	egap_params = vos_mem_malloc(sizeof(*egap_params));
	if (NULL == egap_params) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc egap_params", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	egap_params->enable = enable;
	egap_params->inactivity_time = inactivity_time;
	egap_params->wait_time = wait_time;
	egap_params->flags = flags;

	vos_message.type = WDA_SET_EGAP_CONF_PARAMS;
	vos_message.bodyptr = egap_params;
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);

		vos_mem_free(egap_params);
	}
	return vos_status;
}
#endif

/**
 * sme_update_mimo_power_save() - Update MIMO power save
 * configuration
 * @hal: The handle returned by macOpen
 * @is_ht_smps_enabled: enable/disable ht smps
 * @ht_smps_mode: smps mode disabled/static/dynamic
 *
 * Return: eHAL_STATUS_SUCCESS if SME update mimo power save
 * configuration sucsess else failue status
 */
eHalStatus sme_update_mimo_power_save(tHalHandle hal,
				      uint8_t is_ht_smps_enabled,
				      uint8_t ht_smps_mode)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	eHalStatus status;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		smsLog(mac_ctx, LOG1,
		       "update mimo power save config enable smps: %d smps mode: %d",
		       is_ht_smps_enabled, ht_smps_mode);
		mac_ctx->roam.configParam.enableHtSmps =
			is_ht_smps_enabled;
		mac_ctx->roam.configParam.htSmps = ht_smps_mode;
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}
	return status;
}

/**
 * sme_is_sta_smps_allowed() - check if the supported nss for
 * the session is greater than 1x1 to enable sta SMPS
 * @hal: The handle returned by macOpen
 * @session_id: session id
 *
 * Return: bool returns true if supported nss is greater than
 * 1x1 else false
 */
bool sme_is_sta_smps_allowed(tHalHandle hal, uint8_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	tCsrRoamSession *csr_session;

	if (!mac_ctx) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to get mac_ctx"));
		return false;
	}

	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
	if (NULL == csr_session) {
		smsLog(mac_ctx, LOGE, "SME session not valid: %d", session_id);
		return false;
	}

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		smsLog(mac_ctx, LOGE, "CSR session not valid: %d", session_id);
		return false;
	}

	return (csr_session->supported_nss_1x1 == true) ? false : true;
}

/**
 * sme_get_bpf_offload_capabilities() - Get length for BPF offload
 * @hal: Global HAL handle
 * This function constructs the vos message and fill in message type,
 * post the same to WDA.
 * Return: eHalstatus enumeration
 */
eHalStatus sme_get_bpf_offload_capabilities(tHalHandle hal)
{
	eHalStatus          status    = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx      = PMAC_STRUCT(hal);
	vos_msg_t           vos_msg;

	smsLog(mac_ctx, LOG1, FL("enter"));

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = NULL;
		vos_msg.type = WDA_BPF_GET_CAPABILITIES_REQ;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
					FL("Post bpf get offload msg fail"));
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("sme_AcquireGlobalLock error"));
	}
	smsLog(mac_ctx, LOG1, FL("exit"));
	return status;
}


/**
 * sme_set_bpf_instructions() - Set BPF bpf filter instructions.
 * @hal: HAL handle
 * @bpf_set_offload: struct to set bpf filter instructions.
 *
 * Return: eHalStatus enumeration.
 */
eHalStatus sme_set_bpf_instructions(tHalHandle hal,
				    struct sir_bpf_set_offload *req)
{
	eHalStatus          status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
	vos_msg_t           vos_msg;
	struct sir_bpf_set_offload *set_offload;

	set_offload = vos_mem_malloc(sizeof(*set_offload) +
					req->current_length);

	if (NULL == set_offload) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Failed to alloc set_offload"));
		return eHAL_STATUS_FAILED_ALLOC;
	}
	vos_mem_zero(set_offload, sizeof(*set_offload) + req->current_length);

	set_offload->session_id = req->session_id;
	set_offload->filter_id = req->filter_id;
	set_offload->current_offset = req->current_offset;
	set_offload->total_length = req->total_length;
	set_offload->current_length = req->current_length;
	if (set_offload->total_length) {
		set_offload->program = ((uint8_t *)set_offload) +
					sizeof(*set_offload);
		vos_mem_copy(set_offload->program, req->program,
				set_offload->current_length);
	}
	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = set_offload;
		vos_msg.type = WDA_BPF_SET_INSTRUCTIONS_REQ;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("Post BPF set offload msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(set_offload);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(set_offload);
	}
	return status;
}

/**
 * sme_bpf_offload_register_callback() - Register get bpf offload callbacK
 *
 * @hal - MAC global handle
 * @callback_routine - callback routine from HDD
 *
 * This API is invoked by HDD to register its callback in SME
 *
 * Return: eHalStatus
 */
eHalStatus sme_bpf_offload_register_callback(tHalHandle hal,
				void (*pbpf_get_offload_cb)(void *context,
					struct sir_bpf_get_offload *))
{
	eHalStatus status   = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		mac->sme.pbpf_get_offload_cb = pbpf_get_offload_cb;
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("sme_AcquireGlobalLock failed"));
	}
	return status;
}

/**
 * sme_set_mib_stats_enable() - sme function to set ini parms to FW.
 * @hal_handle: reference to the HAL
 * @value: enable/disable
 *
 * This function sends mib stats enable/disable command to vos
 *
 * Return: hal_status
 */
eHalStatus sme_set_mib_stats_enable(tHalHandle hal_handle, uint8_t value)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	vos_msg_t vos_msg;

	vos_msg.bodyptr = NULL;

	if (value)
		vos_msg.type = WDA_SET_MIB_STATS_ENABLE;
	else
		vos_msg.type = WDA_SET_MIB_STATS_DISABLE;
	if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_msg))) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Failed to post msg to WDA"));
		status = eHAL_STATUS_FAILURE;
	}
	return status;
}

/**
 * sme_get_mib_stats() - sme function to get mib stats
 * @hal_handle: reference to the HAL
 * @callback: callback handler
 * @context: mib stats context
 * @vos_context: vos context
 * @session_id: session id
 *
 * Return: hal_status
 */
eHalStatus sme_get_mib_stats(tHalHandle hal,
		csr_mib_stats_callback callback,
		void *context, void *vos_context,
		uint8_t session_id)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	struct get_mib_stats_req *msg = NULL;
	vos_msg_t vos_message;

	msg = vos_mem_malloc(sizeof(struct get_mib_stats_req));
	status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		if (!msg) {
			smsLog(mac, LOGE, "%s: failed to allocate mem for req",
				__func__);
			return status;
		}

		msg->msg_type = WDA_MIB_STATS_REQ;
		msg->msg_len = (tANI_U16)sizeof(struct get_mib_stats_req);
		msg->session_id = session_id;
		mac->sme.mib_stats_context = context;
		mac->sme.csr_mib_stats_callback = callback;

		vos_message.type = WDA_MIB_STATS_REQ;
		vos_message.bodyptr = msg;
		vos_message.reserved = 0;

		if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(
					VOS_MODULE_ID_WDA, &vos_message))) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
					"%s: Get Mib Stats Request fail",
					__func__);
			vos_mem_free(msg);
			mac->sme.mib_stats_context = NULL;
			mac->sme.csr_mib_stats_callback = NULL;
			status = eHAL_STATUS_FAILURE;
		}

		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(msg);
	}
	return status;
}

/**
 * sme_update_fine_time_measurement_capab() - Update the FTM capab from incoming
 * val
 * @hal:    Handle for Hal layer
 * @val:    New FTM capability value
 *
 * Return: None
 */
void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	mac_ctx->fine_time_meas_cap = val;
	if (val == 0) {
		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0;
		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
			rrmConfig.rm_capability)->fine_time_meas_rpt = 0;
	} else {
		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1;
		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
			rrmConfig.rm_capability)->fine_time_meas_rpt = 1;
	}
}

eHalStatus sme_update_txrate(tHalHandle hal,
			struct sir_txrate_update *req)
{
	eHalStatus          status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
	vos_msg_t           vos_msg;
	struct sir_txrate_update *txrate_update;

	smsLog(mac_ctx, LOG1, FL("enter"));

	txrate_update = vos_mem_malloc(sizeof(*txrate_update));
	if (NULL == txrate_update) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Failed to alloc txrate_update"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	txrate_update->session_id = req->session_id;
	txrate_update->txrate = req->txrate;
	vos_mem_copy(txrate_update->bssid, req->bssid, VOS_MAC_ADDR_SIZE);

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = txrate_update;
		vos_msg.type = WDA_UPDATE_TX_RATE;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("Post Update tx_rate msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(txrate_update);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {

		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
		FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(txrate_update);
	}
	smsLog(mac_ctx, LOG1, FL("exit"));
	return status;
}

/**
 * sme_peer_flush_pending() - sme function to flush peer pending packets
 * val
 * @hal:    Handle for Hal layer
 * @req:    specified flush pending
 *
 * Return: Hal status
 */
eHalStatus sme_peer_flush_pending(tHalHandle hal,
				  struct sme_flush_pending *req)
{
	eHalStatus          status;
	VOS_STATUS          vos_status;
	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
	vos_msg_t           vos_msg;
	struct sme_flush_pending *flush_pend;

	smsLog(mac_ctx, LOG1, FL("enter"));

	flush_pend = vos_mem_malloc(sizeof(*flush_pend));
	if (NULL == flush_pend) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to alloc flush_pend"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	flush_pend->session_id = req->session_id;
	flush_pend->flush_ac = req->flush_ac;
	vos_mem_copy(flush_pend->peer_addr.bytes, req->peer_addr.bytes,
		     VOS_MAC_ADDR_SIZE);

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = flush_pend;
		vos_msg.type = WDA_PEER_FLUSH_PENDING;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				  FL("Post peer flush pending msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(flush_pend);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(flush_pend);
	}
	smsLog(mac_ctx, LOG1, FL("exit"));
	return status;
}

/**
 * sme_delete_all_tdls_peers: send request to delete tdls peers
 * @hal: handler for HAL
 * @sessionId: session id
 *
 * Functtion send's request to lim to delete tdls peers
 *
 * Return: Success: eHAL_STATUS_SUCCESS Failure: Error value
 */
eHalStatus sme_delete_all_tdls_peers(tHalHandle hal, uint8_t session_id)
{
	struct sir_del_all_tdls_peers *msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal p_mac = PMAC_STRUCT(hal);
	tCsrRoamSession *session = CSR_GET_SESSION(p_mac, session_id);

	msg = vos_mem_malloc(sizeof(*msg));
	if (NULL == msg) {
		smsLog(p_mac, LOGE, FL("memory alloc failed"));
		return eHAL_STATUS_FAILURE;
	}

	vos_mem_set(msg, sizeof(*msg), 0);

	msg->msg_type = pal_cpu_to_be16((uint16_t)eWNI_SME_DEL_ALL_TDLS_PEERS);
	msg->msg_len =  pal_cpu_to_be16((uint16_t)sizeof(*msg));

	vos_mem_copy(msg->bssid, session->connectedProfile.bssid,
			sizeof(tSirMacAddr));

	status = palSendMBMessage(p_mac->hHdd, msg);

	if(status != eHAL_STATUS_SUCCESS) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("palSendMBMessage Failed"));
		status = eHAL_STATUS_FAILURE;
	}

	return status;
}

#ifdef FEATURE_COEX_PTA_CONFIG_ENABLE
/**
 * sme_configure_pta_coex() - Set coex PTA params
 * @pta_enable: PTA enable or not
 * @pta_param: PTA params
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_configure_pta_coex(uint8_t coex_pta_config_enable, uint32_t coex_pta_config_param)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_pta_config;

	sme_pta_config = vos_mem_malloc(sizeof(*sme_pta_config));
	if (!sme_pta_config) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_pta_config->config_type = WMI_COEX_CONFIG_PTA_CONFIG;
	sme_pta_config->config_arg1 = coex_pta_config_enable;
	sme_pta_config->config_arg2 = coex_pta_config_param;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_pta_config;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_pta_config);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}
#endif

/**
 * sme_set_beacon_filter() - set the beacon filter configuration
 * @vdev_id: vdev index id
 * @ie_map: bitwise array of IEs
 *
 * Return: Return VOS_STATUS, otherwise appropriate failure code
 */
VOS_STATUS sme_set_beacon_filter(uint32_t vdev_id, uint32_t *ie_map)
{
	vos_msg_t vos_message;
	VOS_STATUS vos_status;
	struct beacon_filter_param *filter_param;

	filter_param = vos_mem_malloc(sizeof(*filter_param));
	if (NULL == filter_param) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc filter_param", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	filter_param->vdev_id = vdev_id;

	vos_mem_copy(filter_param->ie_map, ie_map,
			BCN_FLT_MAX_ELEMS_IE_LIST*sizeof(uint32_t));

	vos_message.type = WDA_ADD_BCN_FILTER_CMDID;
	vos_message.bodyptr = filter_param;
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);
		vos_mem_free(filter_param);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

/**
 * sme_set_btc_bt_wlan_interval_page_p2p() - Set the btc bt/p2p interval
 * @bt_interval: BT Page Interval
 * @bt_interval: P2P Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_page_p2p(uint32_t bt_interval,
			uint32_t p2p_interval)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_PAGE_P2P_TDM;
	sme_interval->config_arg1 = bt_interval;
	sme_interval->config_arg2 = p2p_interval;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

/**

 * sme_unset_beacon_filter() - set the beacon filter configuration
 * @vdev_id: vdev index id
 *
 * Return: Return VOS_STATUS, otherwise appropriate failure code
 */
VOS_STATUS sme_unset_beacon_filter(uint32_t vdev_id)
{
	vos_msg_t vos_message;
	VOS_STATUS vos_status;
	struct beacon_filter_param *filter_param;

	filter_param = vos_mem_malloc(sizeof(*filter_param));
	if (NULL == filter_param) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc filter_param", __func__);
		return VOS_STATUS_E_FAILURE;
	}

	filter_param->vdev_id = vdev_id;

	vos_message.type = WDA_REMOVE_BCN_FILTER_CMDID;
	vos_message.bodyptr = filter_param;
	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
					&vos_message);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);
		vos_mem_free(filter_param);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

/**
 * sme_set_btc_bt_wlan_interval_page_sta() - Set the btc bt/sta interval
 * @bt_interval: BT Page Interval
 * @sta_interval: STA Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_page_sta(uint32_t bt_interval,
			uint32_t sta_interval)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_PAGE_STA_TDM;
	sme_interval->config_arg1 = bt_interval;
	sme_interval->config_arg2 = sta_interval;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

/**
 * sme_set_btc_bt_wlan_interval_page_sap() - Set the btc bt/sap interval
 * @bt_interval: BT Page Interval
 * @bt_interval: SAP Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_page_sap(uint32_t bt_interval,
			uint32_t sap_interval)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_PAGE_SAP_TDM;
	sme_interval->config_arg1 = bt_interval;
	sme_interval->config_arg2 = sap_interval;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

/**
 * sme_set_btc_wlan_conn_params() - Set the btc wlan conn params
 * @coex_config_during_wlan_conn_val0: wlan conn val0
 * @coex_config_during_wlan_conn_val1: wlan conn val1
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_wlan_conn_params(uint32_t conn_val0,
			uint32_t conn_val1)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_DURING_WLAN_CONN;
	sme_interval->config_arg1 = conn_val0;
	sme_interval->config_arg2 = conn_val1;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

/**
 * sme_set_btc_bt_wlan_coex() - Set the btc bt wlan coex
 * @dynamic_wlan_bt_coex: enable bt wlan co-exist
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_dynamic_bt_wlan_coex(uint32_t dynamic_wlan_bt_coex,
						uint32_t antenna_isolation)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_BTC_ENABLE;
	sme_interval->config_arg1 = dynamic_wlan_bt_coex;
	sme_interval->config_arg2 = antenna_isolation;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}


/**
 * sme_set_btc_bt_wlan_interval_page_p2p_sta() - Set the
 * btc bt/p2psta interval
 * @bt_interval: BT Page Interval
 * @sta_interval: P2P STA Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_page_p2p_sta(uint32_t bt_interval,
                        uint32_t p2p_sta_interval)
{
        vos_msg_t msg = {0};
        VOS_STATUS vos_status;
        WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

        sme_interval = vos_mem_malloc(sizeof(*sme_interval));
        if (!sme_interval) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Malloc failed"));
                return VOS_STATUS_E_NOMEM;
        }

        sme_interval->config_type = WMI_COEX_CONFIG_PAGE_P2P_STA_TDM;
        sme_interval->config_arg1 = bt_interval;
        sme_interval->config_arg2 = p2p_sta_interval;

        msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
        msg.reserved = 0;
        msg.bodyptr = sme_interval;

        vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Not able to post message to WDA"));
                vos_mem_free(sme_interval);
                return VOS_STATUS_E_FAILURE;
        }

        return vos_status;
}

/**
 * sme_set_btc_bt_wlan_interval_inquiry_sta() - Inquiry the btc bt/sta interval
 * @bt_interval: BT Page Interval
 * @sta_interval: STA Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_inquiry_sta(uint32_t bt_interval,
                        uint32_t sta_interval)
{
        vos_msg_t msg = {0};
        VOS_STATUS vos_status;
        WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

        sme_interval = vos_mem_malloc(sizeof(*sme_interval));
        if (!sme_interval) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Malloc failed"));
                return VOS_STATUS_E_NOMEM;
        }

        sme_interval->config_type = WMI_COEX_CONFIG_INQUIRY_STA_TDM;
        sme_interval->config_arg1 = bt_interval;
        sme_interval->config_arg2 = sta_interval;

        msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
        msg.reserved = 0;
        msg.bodyptr = sme_interval;

        vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Not able to post message to WDA"));
                vos_mem_free(sme_interval);
                return VOS_STATUS_E_FAILURE;
        }

        return vos_status;
}

/**
 * sme_set_btc_bt_wlan_interval_inquiry_sap() - Inquiry the btc bt/sap interval
 * @bt_interval: BT Page Interval
 * @sta_interval: SAP Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_inquiry_sap(uint32_t bt_interval,
                        uint32_t sap_interval)
{
        vos_msg_t msg = {0};
        VOS_STATUS vos_status;
        WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

        sme_interval = vos_mem_malloc(sizeof(*sme_interval));
        if (!sme_interval) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Malloc failed"));
                return VOS_STATUS_E_NOMEM;
        }

        sme_interval->config_type = WMI_COEX_CONFIG_INQUIRY_SAP_TDM;
        sme_interval->config_arg1 = bt_interval;
        sme_interval->config_arg2 = sap_interval;

        msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
        msg.reserved = 0;
        msg.bodyptr = sme_interval;

        vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Not able to post message to WDA"));
                vos_mem_free(sme_interval);
                return VOS_STATUS_E_FAILURE;
        }

        return vos_status;
}

 /**
 * sme_set_btc_bt_wlan_interval_inquiry_p2p() - Inquiry the btc bt/p2p interval
 * @bt_interval: BT Page Interval
 * @sta_interval: P2P Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_inquiry_p2p(uint32_t bt_interval,
                        uint32_t p2p_interval)
{
        vos_msg_t msg = {0};
        VOS_STATUS vos_status;
        WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

        sme_interval = vos_mem_malloc(sizeof(*sme_interval));
        if (!sme_interval) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Malloc failed"));
                return VOS_STATUS_E_NOMEM;
        }

        sme_interval->config_type = WMI_COEX_CONFIG_INQUIRY_P2P_TDM;
        sme_interval->config_arg1 = bt_interval;
        sme_interval->config_arg2 = p2p_interval;

        msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
        msg.reserved = 0;
        msg.bodyptr = sme_interval;

        vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Not able to post message to WDA"));
                vos_mem_free(sme_interval);
                return VOS_STATUS_E_FAILURE;
        }

        return vos_status;
}

/**
 * sme_set_btc_bt_wlan_interval_inquiry_p2p_sta() - Inquiry the
 * btc bt/p2psta interval
 * @bt_interval: BT Page Interval
 * @sta_interval: P2P STA Interval
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_bt_wlan_interval_inquiry_p2p_sta(uint32_t bt_interval,
                        uint32_t p2p_sta_interval)
{
        vos_msg_t msg = {0};
        VOS_STATUS vos_status;
        WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

        sme_interval = vos_mem_malloc(sizeof(*sme_interval));
        if (!sme_interval) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Malloc failed"));
                return VOS_STATUS_E_NOMEM;
        }

        sme_interval->config_type = WMI_COEX_CONFIG_INQUIRY_P2P_STA_TDM;
        sme_interval->config_arg1 = bt_interval;
        sme_interval->config_arg2 = p2p_sta_interval;

        msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
        msg.reserved = 0;
        msg.bodyptr = sme_interval;

        vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          FL("Not able to post message to WDA"));
                vos_mem_free(sme_interval);
                return VOS_STATUS_E_FAILURE;
        }

        return vos_status;
}

/**
 * sme_set_btc_coex_tx_power() - Set the btc bt/wlan coex tx power
 * @coex_tx_power: bt/wlan coex tx power
 *
 * Return: Return VOS_STATUS.
 */
VOS_STATUS sme_set_btc_wlan_coex_tx_power(uint32_t coex_tx_power)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_TX_POWER;
	sme_interval->config_arg1 = coex_tx_power;

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}

#ifdef WMI_COEX_BTC_DUTYCYCLE
VOS_STATUS sme_set_btc_coex_dutycycle(uint32_t coex_btc_PauseDuration,uint32_t coex_btc_UnPauseDuration)
{
	vos_msg_t msg = {0};
	VOS_STATUS vos_status;
	WMI_COEX_CONFIG_CMD_fixed_param *sme_interval;

	sme_interval = vos_mem_malloc(sizeof(*sme_interval));
	if (!sme_interval) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		return VOS_STATUS_E_NOMEM;
	}

	sme_interval->config_type = WMI_COEX_CONFIG_BTC_DUTYCYCLE;
	sme_interval->config_arg1 = coex_btc_PauseDuration;
	sme_interval->config_arg2 = coex_btc_UnPauseDuration;
	printk(KERN_ERR "ENTER sme_set_btc_coex_dutycycle = %d",coex_btc_PauseDuration);
	printk(KERN_ERR "ENTER sme_set_btc_coex_dutycycle =%d",coex_btc_UnPauseDuration);

	msg.type = WDA_BTC_BT_WLAN_INTERVAL_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_interval;

	vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,&msg);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		vos_mem_free(sme_interval);
		return VOS_STATUS_E_FAILURE;
	}

	return vos_status;
}
#endif

/**
 * sme_send_disassoc_req_frame - send disassoc req
 * @hal: handler to hal
 * @session_id: session id
 * @peer_mac: peer mac address
 * @reason: reason for disassociation
 * wait_for_ack: wait for acknowledgment
 *
 * function to send disassoc request to lim
 *
 * return: none
 */
void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id,
	uint8_t *peer_mac, uint16_t reason, uint8_t wait_for_ack)
{
	struct sme_send_disassoc_frm_req *msg;
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal p_mac = PMAC_STRUCT(hal);
	tANI_U8 *buf;
	tANI_U16 tmp;

	msg = vos_mem_malloc(sizeof(struct sme_send_disassoc_frm_req));

	if (NULL == msg)
		status = eHAL_STATUS_FAILURE;
	else
		status = eHAL_STATUS_SUCCESS;
	if (!HAL_STATUS_SUCCESS(status))
		return;

	vos_mem_set(msg, sizeof(struct sme_send_disassoc_frm_req), 0);
	msg->msg_type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SEND_DISASSOC_FRAME);

	msg->length =
	    pal_cpu_to_be16((tANI_U16)sizeof(struct sme_send_disassoc_frm_req));

	buf = &msg->session_id;

	/* session id */
	*buf = (tANI_U8) session_id;
	buf += sizeof(tANI_U8);

	/* transaction id */
	*buf = 0;
	*(buf + 1) = 0;
	buf += sizeof(tANI_U16);

	/* Set the peer MAC address before sending the message to LIM */
	vos_mem_copy(buf, peer_mac, VOS_MAC_ADDR_SIZE);

	buf += VOS_MAC_ADDR_SIZE;

	/* reasoncode */
	tmp = pal_cpu_to_be16(reason);
	vos_mem_copy(buf, &tmp, sizeof(tANI_U16));
	buf += sizeof(tANI_U16);

	*buf =  wait_for_ack;
	buf += sizeof(tANI_U8);

	status = palSendMBMessage(p_mac->hHdd, msg );

	if(status != eHAL_STATUS_SUCCESS)
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("palSendMBMessage Failed"));
}

/*
 *  sme_is_session_valid(): verify a sme session
 *  @param hal_handle: hal handle for getting global mac struct.
 *  @param session_id: sme_session_id
 *  Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
VOS_STATUS sme_is_session_valid(tHalHandle hal_handle, uint8_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);

	if (NULL == mac_ctx) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("mac_ctx is null!!"));
	        VOS_ASSERT(0);
	        return VOS_STATUS_E_FAILURE;
	}
	if (CSR_IS_SESSION_VALID(mac_ctx, session_id))
	        return VOS_STATUS_SUCCESS;

	return VOS_STATUS_E_FAILURE;
}

/**
 * sme_enable_disable_chanavoidind_event - configure ca event ind
 * @hal: handler to hal
 * set_val: enable/disable
 *
 * function to enable/disable chan avoidance indication
 *
 * return: eHalStatus
 */
eHalStatus sme_enable_disable_chanavoidind_event(tHalHandle hal,
                                              tANI_U8 set_value)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	vos_msg_t msg;

	smsLog(mac, LOG1, FL("set_value: %d"), set_value);
	if (eHAL_STATUS_SUCCESS ==  sme_AcquireGlobalLock(&mac->sme)) {
		vos_mem_zero(&msg, sizeof(vos_msg_t));
		msg.type = WDA_SEND_FREQ_RANGE_CONTROL_IND;
		msg.reserved = 0;
		msg.bodyval = set_value;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);
		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
		return status;
	}

	return eHAL_STATUS_FAILURE;
}
/**
 * sme_oem_update_capability() - update UMAC's oem related capability.
 * @hal: Handle returned by mac_open
 * @oem_cap: pointer to oem_capability
 *
 * This function updates OEM capability to UMAC. Currently RTT
 * related capabilities are updated. More capabilities can be
 * added in future.
 *
 * Return: VOS_STATUS
 */
VOS_STATUS sme_oem_update_capability(tHalHandle hal,
				     struct sme_oem_capability *cap)
{
	VOS_STATUS status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	uint8_t *bytes;

	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;

	if (cap->ftm_rr)
		bytes[4] |= RM_CAP_FTM_RANGE_REPORT;
	if (cap->lci_capability)
		bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT;

	return status;
}

/**
 * sme_oem_get_capability() - get oem capability
 * @hal: Handle returned by mac_open
 * @oem_cap: pointer to oem_capability
 *
 * This function is used to get the OEM capability from UMAC.
 * Currently RTT related capabilities are received. More
 * capabilities can be added in future.
 *
 * Return: VOS_STATUS
 */
VOS_STATUS sme_oem_get_capability(tHalHandle hal,
				  struct sme_oem_capability *cap)
{
	VOS_STATUS status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	uint8_t *bytes;

	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;

	cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT;
	cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT;

	return status;
}

/**
 * sme_remove_bssid_from_scan_list() - wrapper to remove the bssid from
 * scan list
 * @hal: hal context.
 * @bssid: bssid to be removed
 *
 * This function remove the given bssid from scan list.
 *
 * Return: hal status.
 */
eHalStatus sme_remove_bssid_from_scan_list(tHalHandle hal,
	tSirMacAddr bssid)
{
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		csr_remove_bssid_from_scan_list(mac_ctx, bssid);
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}

	return status;
}

/**
 * sme_sta_roam_offload_scan() - update sta roam policy for
 * unsafe and DFS channels for roaming.
 * @hal_handle: hal handle for getting global mac struct
 * @param session_id: sme_session_id
 * @reason: reason to roam
 *
 * Return: none
 */
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
static void sme_sta_roam_offload_scan(tHalHandle hal_handle,
		uint8_t session_id, uint8_t reason)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	if (csrRoamIsRoamOffloadScanEnabled(mac_ctx)) {
		csrRoamOffloadScan(mac_ctx, session_id,
				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				reason);
	}
}
#else
static inline void sme_sta_roam_offload_scan(tHalHandle hal_handle,
		uint8_t session_id, uint8_t reason)
{
}
#endif

/**
 * sme_update_sta_roam_policy() - update sta roam policy for
 * unsafe and DFS channels.
 * @hal_handle: hal handle for getting global mac struct
 * @dfs_mode: dfs mode which tell if dfs channel needs to be
 * skipped or not
 * @skip_unsafe_channels: Param to tell if driver needs to
 * skip unsafe channels or not.
 * @param session_id: sme_session_id
 * @sap_operating_band: Band on which SAP is operating
 *
 * sme_update_sta_roam_policy update sta rome policies to csr
 * this function will call csrUpdateChannelList as well
 * to include/exclude DFS channels and unsafe channels.
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_update_sta_roam_policy(tHalHandle hal_handle,
		enum sta_roam_policy_dfs_mode dfs_mode,
		bool skip_unsafe_channels,
		uint8_t session_id,
                uint8_t sap_operating_band)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tSmeConfigParams sme_config;
	uint8_t reason = 0;

	if (!mac_ctx) {
	    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
	                                "%s: mac_ctx is null", __func__);
		VOS_ASSERT(0);
		return eHAL_STATUS_FAILURE;
	}
	vos_mem_zero(&sme_config, sizeof(sme_config));
	sme_GetConfigParam(hal_handle, &sme_config);

	sme_config.csrConfig.sta_roam_policy_params.dfs_mode =
		dfs_mode;
	sme_config.csrConfig.sta_roam_policy_params.skip_unsafe_channels =
		skip_unsafe_channels;
        sme_config.csrConfig.sta_roam_policy_params.sap_operating_band =
            sap_operating_band;

	sme_UpdateConfig(hal_handle, &sme_config);

	status = csrUpdateChannelList(mac_ctx);
	if (eHAL_STATUS_SUCCESS != status) {
		smsLog(mac_ctx, LOGE,
			FL("failed to update the supported channel list"));
	}
	reason = REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED;
	sme_sta_roam_offload_scan(mac_ctx, session_id, reason);
	return status;
}

/**
 * sme_update_access_policy_vendor_ie() - update vendor ie and access policy.
 * @hal: Pointer to the mac context
 * @session_id: sme session id
 * @vendor_ie: vendor ie
 * @access_policy: vendor ie access policy
 *
 * This function updates the vendor ie and access policy to lim.
 *
 * Return: success or failure.
 */
eHalStatus sme_update_access_policy_vendor_ie(tHalHandle hal,
		uint8_t session_id, uint8_t *vendor_ie, int access_policy)
{
	struct sme_update_access_policy_vendor_ie *msg;
	uint16_t msg_len;
	eHalStatus status = eHAL_STATUS_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	msg_len  = sizeof(*msg);

	msg = vos_mem_malloc(msg_len);
	if (!msg) {
		smsLog(mac, LOGE,
			"failed to allocate memory for sme_update_access_policy_vendor_ie");
		return eHAL_STATUS_FAILURE;
	}

	vos_mem_set(msg, msg_len, 0);
	msg->msg_type = pal_cpu_to_be16(
			(tANI_U16)eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE);
	msg->length = pal_cpu_to_be16(msg_len);

	vos_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie));

	msg->sme_session_id = session_id;
	msg->access_policy = access_policy;

	smsLog(mac, LOG1, "sme_session_id %hu, access_policy %d", session_id,
			access_policy);

	status = palSendMBMessage(mac->hHdd, msg);

	return status;
}

/**
 * sme_update_tx_fail_cnt_threshold() - update tx fail count Threshold
 * @hal: Handle returned by mac_open
 * @session_id: Session ID on which tx fail count needs to be updated to FW
 * @tx_fail_count: Count for tx fail threshold after which FW will disconnect
 *
 * This function is used to set tx fail count threshold to firmware.
 * firmware will issue disocnnect with peer device once this threshold is
 * reached.
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_update_tx_fail_cnt_threshold(tHalHandle hal_handle,
		uint8_t session_id, uint32_t tx_fail_count)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status = eHAL_STATUS_SUCCESS;
	struct sme_tx_fail_cnt_threshold *tx_fail_cnt;
	vos_msg_t msg;

	tx_fail_cnt = vos_mem_malloc(sizeof(*tx_fail_cnt));
	if (NULL == tx_fail_cnt) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc filter_param", __func__);
		return eHAL_STATUS_FAILURE;
	}
	smsLog(mac_ctx, LOG1, FL("session_id %d tx_fail_count: %d"),
			session_id, tx_fail_count);
	tx_fail_cnt->session_id = session_id;
	tx_fail_cnt->tx_fail_cnt_threshold = tx_fail_count;

	vos_mem_zero(&msg, sizeof(vos_msg_t));
	msg.type = WDA_UPDATE_TX_FAIL_CNT_TH;
	msg.reserved = 0;
	msg.bodyptr = tx_fail_cnt;
	status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);

	if(status != eHAL_STATUS_SUCCESS) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
		  FL("Not able to post Tx fail count message to WDA"));
		vos_mem_free(tx_fail_cnt);
		return eHAL_STATUS_FAILURE;
	}

	return status;
}

/**
 * sme_update_short_retry_limit_threshold() - update short frame retry limit TH
 * @hal: Handle returned by mac_open
 * @session_id: Session ID on which short frame retry limit needs to be
 * updated to FW
 * @short_limit_count_th: Retry count TH to retry short frame.
 *
 * This function is used to configure count to retry short frame.
 *
 * Return: VOS_STATUS
 */
eHalStatus sme_update_short_retry_limit_threshold(tHalHandle hal_handle,
		uint8_t session_id, uint8_t short_limit_count_th)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status = eHAL_STATUS_SUCCESS;
	struct sme_short_retry_limit *srl;
	vos_msg_t msg;

	srl = vos_mem_malloc(sizeof(*srl));
	if (NULL == srl) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc short retry limit", __func__);
		return eHAL_STATUS_FAILURE;
	}
	smsLog(mac_ctx, LOG1, FL("session_id %d short retry limit count: %d"),
			session_id, short_limit_count_th);
	srl->session_id = session_id;
	srl->short_retry_limit = short_limit_count_th;

	vos_mem_zero(&msg, sizeof(vos_msg_t));
	msg.type = WDA_UPDATE_SHORT_RETRY_LIMIT_CNT;
	msg.reserved = 0;
	msg.bodyptr = srl;
	status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);
	if(status != eHAL_STATUS_SUCCESS) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Not able to post short retry limit count to WDA"));
		vos_mem_free(srl);
		return eHAL_STATUS_FAILURE;
	}

	return status;
}

/**
 * sme_update_long_retry_limit_threshold() - update long retry limit TH
 * @hal: Handle returned by mac_open
 * @session_id: Session ID on which long frames retry TH needs to be updated
 * to FW
 * @long_limit_count_th: Retry count to retry long frame.
 *
 * This function is used to configure TH to retry long frame.
 *
 * Return: VOS_STATUS
 */
eHalStatus sme_update_long_retry_limit_threshold(tHalHandle hal_handle,
		uint8_t session_id, uint8_t long_limit_count_th)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status = eHAL_STATUS_SUCCESS;
	struct sme_long_retry_limit *lrl;
	vos_msg_t msg;

	lrl = vos_mem_malloc(sizeof(*lrl));
	if (NULL == lrl) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc long retry limit", __func__);
		return eHAL_STATUS_FAILURE;
	}
	smsLog(mac_ctx, LOG1, FL("session_id %d long retry limit count: %d"),
			session_id, long_limit_count_th);
	lrl->session_id = session_id;
	lrl->long_retry_limit = long_limit_count_th;

	vos_mem_zero(&msg, sizeof(vos_msg_t));
	msg.type = WDA_UPDATE_LONG_RETRY_LIMIT_CNT;
	msg.reserved = 0;
	msg.bodyptr = lrl;
	status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);

	if(status != eHAL_STATUS_SUCCESS) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Not able to post long retry limit count to WDA"));
		vos_mem_free(lrl);
		return eHAL_STATUS_FAILURE;
	}
	return status;
}

/**
 * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW
 * @hal: Handle returned by mac_open
 * @session_id: Session ID on which sta_inactivity_timeout needs
 * to be updated to FW
 * @sta_inactivity_timeout: sta inactivity timeout.
 *
 * If a station does not send anything in sta_inactivity_timeout seconds, an
 * empty data frame is sent to it in order to verify whether it is
 * still in range. If this frame is not ACKed, the station will be
 * disassociated and then deauthenticated.
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
		uint8_t session_id, uint32_t sta_inactivity_timeout)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status = eHAL_STATUS_SUCCESS;
	struct sme_sta_inactivity_timeout *inactivity_time;
	vos_msg_t msg;

	inactivity_time = vos_mem_malloc(sizeof(*inactivity_time));
	if (NULL == inactivity_time) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: fail to alloc inactivity_time", __func__);
		return eHAL_STATUS_FAILURE;
	}
	smsLog(mac_ctx, LOG1, FL("sta_inactivity_timeout: %d"),
			sta_inactivity_timeout);
	inactivity_time->session_id = session_id;
	inactivity_time->sta_inactivity_timeout = sta_inactivity_timeout;

	if (eHAL_STATUS_SUCCESS ==  sme_AcquireGlobalLock(&mac_ctx->sme)) {
		vos_mem_zero(&msg, sizeof(vos_msg_t));
		msg.type = WDA_UPDATE_STA_INACTIVITY_TIMEOUT;
		msg.reserved = 0;
		msg.bodyptr = inactivity_time;
		status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg);

		if(status != eHAL_STATUS_SUCCESS) {
			status = eHAL_STATUS_FAILURE;
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: sta_inactivity_timeout ",
				__func__);
			vos_mem_free(inactivity_time);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
		return status;
	}

	return eHAL_STATUS_FAILURE;
}

/**
 * sme_set_chan_info_callback() - set scan chan info call back
 * @hal: Handle returned by mac_open
 * @callback: scan chan info call back
 *
 * This function is used to set scan chan info call back.
 *
 * Return: None
 */
void sme_set_chan_info_callback(tHalHandle hal_handle,
                           void (*callback)(struct scan_chan_info *chan_info))
{
	tpAniSirGlobal mac = PMAC_STRUCT(hal_handle);

	mac->chan_info_cb = callback;
}

/*
 * sme_set_band_specific_pref(): If 5G preference is enabled,set boost/drop
 * params from ini.
 * @hal_handle: Handle returned by mac_open
 * @5g_pref_params: pref params from ini.
 */
void sme_set_5g_band_pref(tHalHandle hal_handle,
                                struct sme_5g_band_pref_params *pref_params) {

	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	struct roam_ext_params *roam_params;
	eHalStatus status    = eHAL_STATUS_SUCCESS;

	if (!pref_params) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "Invalid 5G pref params!");
		return;
	}
	status = sme_AcquireGlobalLock( &mac_ctx->sme );
	if (HAL_STATUS_SUCCESS(status)) {
		roam_params = &mac_ctx->roam.configParam.roam_params;
		roam_params->raise_rssi_thresh_5g =
				pref_params->rssi_boost_threshold_5g;
		roam_params->raise_factor_5g =
				pref_params->rssi_boost_factor_5g;
		roam_params->max_raise_rssi_5g =
				pref_params->max_rssi_boost_5g;
		roam_params->drop_rssi_thresh_5g =
				pref_params->rssi_penalize_threshold_5g;
		roam_params->drop_factor_5g =
				pref_params->rssi_penalize_factor_5g;
		roam_params->max_drop_rssi_5g =
				pref_params->max_rssi_penalize_5g;

		sme_ReleaseGlobalLock(&mac_ctx->sme);
	}
	else
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "Unable to acquire global sme lock");
}

/**
 * sme_set_reorder_timeout() - set reorder timeout value
 * including Voice,Video,Besteffort,Background parameters
 * @hal: hal handle for getting global mac struct
 * @reg: struct sir_set_rx_reorder_timeout_val
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_set_reorder_timeout(tHalHandle hal,
			struct sir_set_rx_reorder_timeout_val *req)
{
	eHalStatus          status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
	vos_msg_t           vos_msg;
	struct sir_set_rx_reorder_timeout_val *reorder_timeout;

	smsLog(mac_ctx, LOG1, FL("enter"));

	reorder_timeout = vos_mem_malloc(sizeof(*reorder_timeout));
	if (NULL == reorder_timeout) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Failed to alloc txrate_update"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*reorder_timeout = *req;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = reorder_timeout;
		vos_msg.type = SIR_HAL_SET_REORDER_TIMEOUT_CMDID;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("Post Update tx_rate msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(reorder_timeout);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(reorder_timeout);
	}
	smsLog(mac_ctx, LOG1, FL("exit"));
	return status;
}

/**
 * sme_set_rx_set_blocksize() - set blocksize value
 * including mac_addr and win_limit parameters
 * @hal: hal handle for getting global mac struct
 * @reg: struct sir_peer_set_rx_blocksize
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_set_rx_set_blocksize(tHalHandle hal,
			struct sir_peer_set_rx_blocksize *req)
{
	eHalStatus          status     = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
	vos_msg_t           vos_msg;
	struct sir_peer_set_rx_blocksize *rx_blocksize;

	smsLog(mac_ctx, LOG1, FL("enter"));

	rx_blocksize = vos_mem_malloc(sizeof(*rx_blocksize));
	if (NULL == rx_blocksize) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("Failed to alloc rx_blocksize"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*rx_blocksize = *req;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = rx_blocksize;
		vos_msg.type = SIR_HAL_SET_RX_BLOCKSIZE_CMDID;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("Post Update tx_rate msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(rx_blocksize);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(rx_blocksize);
	}
	smsLog(mac_ctx, LOG1, FL("exit"));
	return status;
}
/**
 * sme_register_stats_ext2_callback() - Register drone callback to SME
 * @hal_handle: hal handle for getting global mac struct
 * @stats_ext2_cb: callback to be registered
 *
 * This function will register a callback for frame aggregation failure
 * indications processing.
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_register_stats_ext2_callback(tHalHandle hal_handle,
			void (*stats_ext2_cb)(void *, struct stats_ext2_event *))
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal_handle);

	status = sme_AcquireGlobalLock(&pmac->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		pmac->sme.stats_ext2_cb = stats_ext2_cb;
		sme_ReleaseGlobalLock(&pmac->sme);
	}
	return status;
}

#ifdef FEATURE_WLAN_SUB_20_MHZ
/**
 * sme_update_sub20_channel_width() - update sub 20 channel width
 * @hal_handle: hal handle for getting global mac struct
 * @session_id: Session ID on which sub20 channel width needs to be updated
 * to FW
 * @chan_width: channel width
 *
 * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
 */
eHalStatus sme_update_sub20_channel_width(tHalHandle hal_handle,
                                          uint8_t session_id,
                                          uint8_t chan_width)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	eHalStatus status;
	struct sme_sub20_chan_width *msg;
	uint16_t msg_len;

	if (mac_ctx == NULL) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
			  "%s: mac_ctx is null", __func__);
		VOS_ASSERT(0);
		return eHAL_STATUS_FAILURE;
	}

	if (mac_ctx->sub20_dynamic_channelwidth == 0)
		return eHAL_STATUS_SUCCESS;

	msg = vos_mem_malloc(sizeof(*msg));
	if (NULL == msg) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  "%s: mem alloc failed for pSub20ChannelWidth",
			  __func__);
		return eHAL_STATUS_FAILURE;
	}

	msg_len = sizeof(*msg);
	msg->message_type = pal_cpu_to_be16(eWNI_SME_SET_SUB20_CH_WIDTH);
	msg->length = pal_cpu_to_be16(msg_len);
	msg->session_id = session_id;
	msg->channelwidth = chan_width;

	status = palSendMBMessage(mac_ctx->hHdd, msg);
	if (eHAL_STATUS_SUCCESS != status)
		smsLog(mac_ctx, LOGE, FL(
		       "eWNI_SME_SET_SUB20_CH_WIDTH: msg to PE failed"));
	return status;
}
#endif

eHalStatus sme_set_random_mac(tHalHandle hal,
			      action_frame_random_filter_callback callback,
			      uint32_t session_id, uint8_t *random_mac,
			      void *context)
{

	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	vos_msg_t vos_msg;
	struct action_frame_random_filter *filter;

	filter = vos_mem_malloc(sizeof(*filter));

	if (!filter) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to alloc random mac filter"));
		return eHAL_STATUS_FAILED_ALLOC;
	}
	vos_mem_zero(filter, sizeof(*filter));

	filter->session_id = session_id;
	filter->filter_type = SME_ACTION_FRAME_RANDOM_MAC_SET;
	filter->callback = callback;
	filter->context = context;
	vos_mem_copy(filter->mac_addr, random_mac, VOS_MAC_ADDR_SIZE);

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = filter;
		vos_msg.type = WDA_ACTION_FRAME_RANDOM_MAC;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("action frame set random mac msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(filter);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(filter);
	}
	return status;
}

eHalStatus sme_clear_random_mac(tHalHandle hal, uint32_t session_id,
				uint8_t *random_mac)
{

	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	vos_msg_t vos_msg;
	struct action_frame_random_filter *filter;

	filter = vos_mem_malloc(sizeof(*filter));

	if (!filter) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to alloc random mac filter"));
		return eHAL_STATUS_FAILED_ALLOC;
	}
	vos_mem_zero(filter, sizeof(*filter));

	filter->session_id = session_id;
	filter->filter_type = SME_ACTION_FRAME_RANDOM_MAC_CLEAR;
	vos_mem_copy(filter->mac_addr, random_mac, VOS_MAC_ADDR_SIZE);

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = filter;
		vos_msg.type = WDA_ACTION_FRAME_RANDOM_MAC;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("action frame clear random mac msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(filter);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(filter);
	}
	return status;
}

bool sme_is_sta_key_exchange_in_progress(tHalHandle hal, uint8_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Invalid session %d"), session_id);
		return false;
	}

	return CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id);
}

#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
 * sme_set_mt_host_ev_cb() - set callback which to handle
 *                            eWNI_SME_MOTION_DET_HOST_EVENT
 *
 * @hHal: Handler return by macOpen.
 * @pcallbackfn: callback to handle the motion det host event
 * @pcallbackcontext: callback context
 *
 * Return: eHalStatus.
 */
eHalStatus sme_set_mt_host_ev_cb
(
    tHalHandle hHal,
    VOS_STATUS (*pcallbackfn)(void *pcallbackcontext, tSirMtEvent *pEvent),
    void *pcallbackcontext
)
{
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    eHalStatus status;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        pMac->sme.mt_host_ev_cb = pcallbackfn;
        pMac->sme.mt_cxt = pcallbackcontext;
        sme_ReleaseGlobalLock(&pMac->sme);
    }
    return status;
}

eHalStatus sme_MotionDetConfig(tHalHandle hHal, tSirMotionDetConfig *pMotionDetConfig)
{
    vos_msg_t vosMessage;
    tSirMotionDetConfig *pSmeMotionDetConfig;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMotionDetConfig = vos_mem_malloc(sizeof(*pMotionDetConfig));

    if (!pSmeMotionDetConfig) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MOTION_DET_CONFIG",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMotionDetConfig = *pMotionDetConfig;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MOTION_DET_CONFIG;
        vosMessage.bodyptr  = pSmeMotionDetConfig;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MOTION_DET_CONFIG to WDA!",
                __func__);
            vos_mem_free(pSmeMotionDetConfig);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMotionDetConfig);
    }

    return (status);
}

eHalStatus sme_MotionDetEnable(tHalHandle hHal, tSirMotionDetEnable *pMotionDetEnable)
{
    vos_msg_t vosMessage;
    tSirMotionDetEnable *pSmeMotionDetEnable;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMotionDetEnable = vos_mem_malloc(sizeof(*pMotionDetEnable));

    if (!pSmeMotionDetEnable) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MOTION_DET_ENABLE",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMotionDetEnable = *pMotionDetEnable;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MOTION_DET_ENABLE;
        vosMessage.bodyptr  = pSmeMotionDetEnable;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MOTION_DET_ENABLE to WDA!",
                __func__);
            vos_mem_free(pSmeMotionDetEnable);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMotionDetEnable);
    }

    return (status);
}

eHalStatus sme_MotionDetBaseLineConfig(tHalHandle hHal, tSirMotionDetBaseLineConfig *pMotionDetBaseLineConfig)
{
    vos_msg_t vosMessage;
    tSirMotionDetBaseLineConfig *pSmeMotionDetBaseLineConfig;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMotionDetBaseLineConfig = vos_mem_malloc(sizeof(*pMotionDetBaseLineConfig));

    if (!pSmeMotionDetBaseLineConfig ) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MOTION_DET_BASE_LINE_CONFIG",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMotionDetBaseLineConfig = *pMotionDetBaseLineConfig;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MOTION_DET_BASE_LINE_CONFIG;
        vosMessage.bodyptr  = pSmeMotionDetBaseLineConfig;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MOTION_DET_BASE_LINE_CONFIG to WDA!",
                __func__);
            vos_mem_free(pSmeMotionDetBaseLineConfig);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMotionDetBaseLineConfig);
    }

    return (status);
}

eHalStatus sme_MotionDetBaseLineEnable(tHalHandle hHal, tSirMotionDetBaseLineEnable *pMotionDetBaseLineEnable)
{
    vos_msg_t vosMessage;
    tSirMotionDetBaseLineEnable *pSmeMotionDetBaseLineEnable;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

    pSmeMotionDetBaseLineEnable = vos_mem_malloc(sizeof(*pMotionDetBaseLineEnable));

    if (!pSmeMotionDetBaseLineEnable ) {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         "%s: Not able to allocate memory for WDA_SET_MOTION_DET_BASE_LINE_ENABLE",
         __func__);
        return eHAL_STATUS_E_MALLOC_FAILED;
    }

    *pSmeMotionDetBaseLineEnable = *pMotionDetBaseLineEnable;

    status = sme_AcquireGlobalLock(&pMac->sme);
    if (eHAL_STATUS_SUCCESS == status) {
        /* serialize the req through MC thread */
        vosMessage.type     = WDA_SET_MOTION_DET_BASE_LINE_ENABLE;
        vosMessage.bodyptr  = pSmeMotionDetBaseLineEnable;

        if (!VOS_IS_STATUS_SUCCESS(
            vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) {
            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to post WDA_SET_MOTION_DET_BASE_LINE_ENABLE to WDA!",
                __func__);
            vos_mem_free(pSmeMotionDetBaseLineEnable);
            status = eHAL_STATUS_FAILURE;
        }
        sme_ReleaseGlobalLock(&pMac->sme);
    } else {
        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_AcquireGlobalLock error!",
                       __func__);
        vos_mem_free(pSmeMotionDetBaseLineEnable);
    }

    return (status);
}
#endif

eHalStatus sme_update_owe_info(tHalHandle hal,
			       struct sSirSmeAssocInd *assoc_ind)
{
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	eHalStatus status;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(status)) {
		status = csr_update_owe_info(mac, assoc_ind);
		sme_ReleaseGlobalLock(&mac->sme);
	}

	return status;
}

uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf,
                           uint8_t buf_len,
                           tDot11fIERSN *rsn_ie)
{
         tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

         return dot11fUnpackIeRSN(mac_ctx, buf, buf_len, rsn_ie);
}

#ifdef WLAN_FEATURE_SAE
eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
			      uint8_t sae_status,
			      tSirMacAddr peer_mac_addr)
{
	eHalStatus hal_status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	struct sir_sae_msg *sae_msg;
	vos_msg_t vos_message;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;

	hal_status = sme_AcquireGlobalLock(&mac->sme);
	if (HAL_STATUS_SUCCESS(hal_status)) {
		sae_msg = vos_mem_malloc(sizeof(*sae_msg));
		if (!sae_msg) {
			hal_status = eHAL_STATUS_FAILED_ALLOC;
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"SAE: memory allocation failed");
		} else {
			sae_msg->message_type = eWNI_SME_SEND_SAE_MSG;
			sae_msg->length = sizeof(*sae_msg);
			sae_msg->session_id = session_id;
			sae_msg->sae_status = sae_status;
			vos_mem_copy(sae_msg->peer_mac_addr,
				     peer_mac_addr,
				     VOS_MAC_ADDR_SIZE);
			vos_message.bodyptr = sae_msg;
			vos_message.type =  eWNI_SME_SEND_SAE_MSG;
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
				  "SAE: sae_status %d session_id %d Peer: "
				  MAC_ADDRESS_STR,
				  sae_msg->sae_status,
				  sae_msg->session_id,
				  MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));

			vos_status = vos_mq_post_message(VOS_MQ_ID_PE,
							 &vos_message);
			if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
				vos_mem_free(sae_msg);
				hal_status = eHAL_STATUS_FAILURE;
			}
		}
		sme_ReleaseGlobalLock(&mac->sme);
	}

	return hal_status;
}
#endif

#ifdef WLAN_SPECTRAL_SCAN
eHalStatus sme_spectral_scan_enable(tHalHandle hal,
				    sir_spectral_enable_params_t *params)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	vos_msg_t vos_msg;
	sir_spectral_enable_params_t *spectral_enable_params;

	spectral_enable_params = vos_mem_malloc(sizeof(*spectral_enable_params));
	if (!spectral_enable_params) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to alloc spectral enable params"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*spectral_enable_params = *params;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = spectral_enable_params;
		vos_msg.type = SIR_HAL_SPECTRAL_SCAN_ENABLE_CMDID;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				  FL("post spectal scan enable msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(spectral_enable_params);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(spectral_enable_params);
	}

	return status;
}

eHalStatus sme_spectral_scan_config(tHalHandle hal,
				    sir_spectral_config_params_t *params)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	vos_msg_t vos_msg;
	sir_spectral_config_params_t *spectral_config_params;

	spectral_config_params = vos_mem_malloc(sizeof(*spectral_config_params));
	if (!spectral_config_params) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("Failed to alloc spectral config params"));
		return eHAL_STATUS_FAILED_ALLOC;
	}

	*spectral_config_params = *params;

	status = sme_AcquireGlobalLock(&mac_ctx->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		/* Serialize the req through MC thread */
		vos_msg.bodyptr = spectral_config_params;
		vos_msg.type = SIR_HAL_SPECTRAL_SCAN_CONFIG_CMDID;
		vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg);

		if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				  FL("post spectal scan config msg fail"));
			status = eHAL_STATUS_FAILURE;
			vos_mem_free(spectral_config_params);
		}
		sme_ReleaseGlobalLock(&mac_ctx->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(spectral_config_params);
	}

	return status;
}
#endif

#ifdef AUDIO_MULTICAST_AGGR_SUPPORT
/**
 * sme_au_get_txrx_stat() - get audio multicast txrx stats
 * @sessionid: Session ID
 * @context: event handle context
 * @pcallbackfn: callback function pointer
 *
 * This function will send GEN_PARAM_MULTICAST_GET_TXRX_STAT to WMA
 *
 * Return: 0 on success, otherwise error value
 */
eHalStatus sme_au_get_txrx_stat(tHalHandle hal,
			uint8_t sessionid,
			void *context,
			void (*callbackfn)(struct sir_au_get_txrx_stat_resp *param,
						void *pcontext))
{

	eHalStatus          status    = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vosstatus = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac       = PMAC_STRUCT(hal);
	vos_msg_t           vosmessage;
	wda_cli_set_cmd_t   *iwcmd;

	/* serialize the req through MC thread */
	iwcmd = (wda_cli_set_cmd_t *)vos_mem_malloc(sizeof(wda_cli_set_cmd_t));
	if (NULL == iwcmd) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Memory allocation failed.", __func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}
	iwcmd->param_value = sessionid;
	iwcmd->param_vdev_id = sessionid;
	iwcmd->param_id = GEN_PARAM_MULTICAST_GET_TXRX_STAT;
	iwcmd->param_vp_dev = GEN_CMD;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		if (NULL == callbackfn) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Indication Call back is NULL",
				__func__);
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_FAILURE;
		}

		mac->sme.pau_txrx_stat_ind_cb = callbackfn;
		mac->sme.pau_get_txrx_stat_cb_context = context;

		vosmessage.bodyptr = (void*)iwcmd;
		vosmessage.type    = WDA_CLI_SET_CMD;
		vosstatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosmessage);
		if (!VOS_IS_STATUS_SUCCESS(vosstatus)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Post get peer info msg fail", __func__);
			vos_mem_free(vosmessage.bodyptr);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(iwcmd);
	}
	return status;
}

/**
 * sme_au_get_tx_sched() - get audio multicast tx sched method
 * @sessionid: Session ID
 * @context: event handle context
 * @pcallbackfn: callback function pointer
 *
 * This function will send GEN_PARAM_MULTICAST_GET_TX_SCHED to WMA
 *
 * Return: 0 on success, otherwise error value
 */
eHalStatus sme_au_get_tx_sched(tHalHandle hal,
			uint8_t sessionid,
			void *context,
			void (*callbackfn)(struct sir_au_get_tx_sched_resp *param,
						void *pcontext))
{

	eHalStatus          status    = eHAL_STATUS_SUCCESS;
	VOS_STATUS          vosstatus = VOS_STATUS_SUCCESS;
	tpAniSirGlobal      mac       = PMAC_STRUCT(hal);
	vos_msg_t           vosmessage;
	wda_cli_set_cmd_t   *iwcmd;

	/* serialize the req through MC thread */
	iwcmd = (wda_cli_set_cmd_t *)vos_mem_malloc(sizeof(wda_cli_set_cmd_t));
	if (NULL == iwcmd) {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			"%s: Memory allocation failed.", __func__);
		return eHAL_STATUS_E_MALLOC_FAILED;
	}
	iwcmd->param_value = sessionid;
	iwcmd->param_vdev_id = sessionid;
	iwcmd->param_id = GEN_PARAM_MULTICAST_GET_TX_SCHED;
	iwcmd->param_vp_dev = GEN_CMD;

	status = sme_AcquireGlobalLock(&mac->sme);
	if (eHAL_STATUS_SUCCESS == status) {
		if (NULL == callbackfn) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Indication Call back is NULL",
				__func__);
			sme_ReleaseGlobalLock(&mac->sme);
			return eHAL_STATUS_FAILURE;
		}

		mac->sme.pau_tx_sched_ind_cb = callbackfn;
		mac->sme.pau_get_tx_sched_cb_context = context;

		vosmessage.bodyptr = (void*)iwcmd;
		vosmessage.type    = WDA_CLI_SET_CMD;
		vosstatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosmessage);
		if (!VOS_IS_STATUS_SUCCESS(vosstatus)) {
			VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
				"%s: Post get tx sched msg fail", __func__);
			vos_mem_free(vosmessage.bodyptr);
			status = eHAL_STATUS_FAILURE;
		}
		sme_ReleaseGlobalLock(&mac->sme);
	} else {
		VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
			  FL("sme_AcquireGlobalLock failed"));
		vos_mem_free(iwcmd);
	}
	return status;
}
#endif

void sme_enable_aid_by_user(tHalHandle hal, bool aid_by_user)
{
    tpAniSirGlobal mac = PMAC_STRUCT(hal);
    mac->aid_by_user = aid_by_user;
}

eHalStatus sme_register_aid_req_callback(tHalHandle hal,
			void (*aid_req_cb)(void *, sir_aid_req_t *))
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_AcquireGlobalLock(&mac->sme);
	if (status == eHAL_STATUS_SUCCESS) {
		mac->sme.aid_req_cb = aid_req_cb;
		sme_ReleaseGlobalLock(&mac->sme);
	}

	return status;
}

eHalStatus sme_aid_set(tHalHandle hal, sir_aid_set_t *aid_set)
{
	eHalStatus status = eHAL_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	lim_process_sme_aid_set(mac, aid_set);

	return status;
}
