blob: 7bc6f3cd9d3ed13edc1581fe161ee783c6c1ae70 [file] [log] [blame]
/*
* 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 "sapApi.h"
#include "macTrace.h"
#include "vos_utils.h"
#include "limSession.h"
extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#include <wlan_qct_pal_api.h>
#define LOG_SIZE 256
#define READ_MEMORY_DUMP_CMD 9
#define TL_INIT_STATE 0
#define CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE 1000*30 //30s
// TxMB Functions
extern eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, 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 csrReleaseRocReqCommand( tpAniSirGlobal pMac);
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 sme_sendActionCnf( 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);
eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal);
#ifdef FEATURE_WLAN_LFR
tANI_BOOLEAN csrIsScanAllowed(tpAniSirGlobal pMac);
#endif
#ifdef WLAN_FEATURE_11W
eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm );
#endif
//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);
}
static eHalStatus initSmeCmdList(tpAniSirGlobal pMac)
{
eHalStatus status;
tSmeCmd *pCmd;
tANI_U32 cmd_idx;
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;
pCmd = (tSmeCmd *) vos_mem_vmalloc(sizeof(tSmeCmd) * pMac->sme.totalSmeCmd);
if ( NULL == pCmd )
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("fail to allocate memory %lu"),
(unsigned long)(sizeof(tSmeCmd) * pMac->sme.totalSmeCmd));
status = eHAL_STATUS_FAILURE;
}
else
{
status = eHAL_STATUS_SUCCESS;
vos_mem_set(pCmd, sizeof(tSmeCmd) * pMac->sme.totalSmeCmd, 0);
pMac->sme.pSmeCmdBufAddr = pCmd;
for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++)
{
csrLLInsertTail(&pMac->sme.smeCmdFreeList,
&pCmd[cmd_idx].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, bool flush_all)
{
//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 (!flush_all &&
csr_is_disconnect_full_power_cmd(pCommand)) {
smsLog(pMac, LOGW, FL(" Ignore disconnect"));
pEntry = pNext;
continue;
}
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;
}
if(NULL != pMac->sme.pSmeCmdBufAddr)
{
vos_mem_vfree(pMac->sme.pSmeCmdBufAddr);
pMac->sme.pSmeCmdBufAddr = NULL;
}
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 tfhe 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 pending 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);
vos_state_info_dump_all();
if (pMac->roam.configParam.enableFatalEvent)
{
vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
WLAN_LOG_INDICATOR_HOST_DRIVER,
WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
FALSE, FALSE);
}
else
{
/* Trigger SSR */
vos_wlanRestart(VOS_GET_MSG_BUFF_FAILURE);
}
}
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 );
}
//For commands that need to do extra cleanup.
static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping )
{
if( eSmePmcCommandMask & pCommand->command )
{
pmcAbortCommand( 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;
tSmeCmd *pSmeCommand;
tANI_BOOLEAN status = eANI_BOOLEAN_TRUE;
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 );
//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 ((!csrLLIsListEmpty(&pMac->sme.smeCmdActiveList,
LL_ACCESS_LOCK )))
{
pSmeEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList,
LL_ACCESS_LOCK);
if (pEntry)
{
pSmeCommand = GET_BASE_ADDR(pEntry, tSmeCmd,
Link) ;
/* if scan is running on one interface and SME recei
ves the next command on the same interface then
dont the allow the command to be queued to
smeCmdPendingList. If next scan is allowed on
the same interface the CSR state machine will
get screwed up. */
if (pSmeCommand->sessionId == pCommand->sessionId)
{
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;
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;
}
eHalStatus smeProcessPnoCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd)
{
tpSirPNOScanReq pnoReqBuf;
tSirMsgQ msgQ;
pnoReqBuf = vos_mem_malloc(sizeof(tSirPNOScanReq));
if ( NULL == pnoReqBuf )
{
smsLog(pMac, LOGE, FL("failed to allocate memory"));
return eHAL_STATUS_FAILURE;
}
vos_mem_copy(pnoReqBuf, &(pCmd->u.pnoInfo), sizeof(tSirPNOScanReq));
smsLog(pMac, LOG1, FL("post WDA_SET_PNO_REQ comamnd"));
msgQ.type = WDA_SET_PNO_REQ;
msgQ.reserved = 0;
msgQ.bodyptr = pnoReqBuf;
msgQ.bodyval = 0;
wdaPostCtrlMsg( pMac, &msgQ);
return eHAL_STATUS_SUCCESS;
}
/**
* 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;
}
/**
* sme_process_update_channel_list() - Update channel list
* @mac_ctx: mac context
* @command: cmd param containing band, and power in db
*
* Return: eHalStatus
*/
eHalStatus sme_process_update_channel_list(tpAniSirGlobal mac_ctx,
tSmeCmd *command)
{
vos_msg_t msg;
msg.type = WDA_UPDATE_CHAN_LIST_REQ;
msg.reserved = 0;
msg.bodyptr = command->u.chan_list;
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)) {
smsLog(mac_ctx, LOGE,
FL("Unable to post message to WDA"));
vos_mem_free(command->u.chan_list);
return eHAL_STATUS_FAILURE;
}
return eHAL_STATUS_SUCCESS;
}
static void smeProcessNanReq(tpAniSirGlobal pMac, tSmeCmd *pCommand )
{
tSirMsgQ msgQ;
tSirRetStatus retCode = eSIR_SUCCESS;
msgQ.type = WDA_NAN_REQUEST;
msgQ.reserved = 0;
msgQ.bodyptr = pCommand->u.pNanReq;
msgQ.bodyval = 0;
retCode = wdaPostCtrlMsg( pMac, &msgQ );
if( eSIR_SUCCESS != retCode)
{
vos_mem_free(pCommand->u.pNanReq);
smsLog( pMac, LOGE,
FL("Posting WDA_NAN_REQUEST to WDA failed, reason=%X"),
retCode );
}
else
{
smsLog(pMac, LOG1, FL("posted WDA_NAN_REQUEST command"));
}
}
/**
* sme_set_qpower() - Set Qpower
* @pMac - context handler
* @enable - uint8 value that needs to be sent to FW
*
* The function sends the qpower to firmware received
* via driver command
*/
void sme_set_qpower(tpAniSirGlobal pMac, uint8_t enable)
{
tSirMsgQ msgQ;
tSirRetStatus retCode = eSIR_SUCCESS;
vos_mem_zero(&msgQ, sizeof(tSirMsgQ));
msgQ.type = WDA_QPOWER;
msgQ.reserved = 0;
msgQ.bodyval = enable;
retCode = wdaPostCtrlMsg(pMac, &msgQ);
if(eSIR_SUCCESS != retCode)
{
smsLog(pMac, LOGE,
FL("Posting WDA_QPOWER to WDA failed, reason=%X"),
retCode);
}
else
{
smsLog(pMac, LOG1, FL("posted WDA_QPOWER command"));
}
}
/**
* sme_set_vowifi_mode() - Set VOWIFI mode
* @pMac - context handler
* @enable - boolean value that determines the state
*
* The function sends the VOWIFI to firmware received
* via driver command
*/
void sme_set_vowifi_mode(tpAniSirGlobal pMac, bool enable)
{
tSirMsgQ msgQ;
tSirRetStatus retCode = eSIR_SUCCESS;
vos_mem_zero(&msgQ, sizeof(tSirMsgQ));
msgQ.type = WDA_VOWIFI_MODE;
msgQ.reserved = 0;
msgQ.bodyval = enable;
retCode = wdaPostCtrlMsg(pMac, &msgQ);
if(eSIR_SUCCESS != retCode)
{
smsLog(pMac, LOGE,
FL("Posting WDA_VOWIFI_MODE to WDA failed, reason=%X"),
retCode);
}
else
{
smsLog(pMac, LOG1, FL("posted WDA_VOWIFI_MODE command"));
}
}
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...
//alwasy 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_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;
}
}
pmcCommand = smeIsFullPowerNeeded( pMac, pCommand );
if( eSmeDropCommand == pmcCommand )
{
//This command is not ok for current PMC state
if( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) )
{
smeAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE );
}
csrLLUnlock( &pMac->sme.smeCmdActiveList );
//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, pmcCommand, pv, size, &pPmcCmd );
if( HAL_STATUS_SUCCESS( status ) && pPmcCmd )
{
/* Set the time out to 30 sec */
pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
//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 );
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
/* For ROC set timeot to 30 *3 as Supplicant can retry
* P2P Invitation Request 120 times with 500ms interval.
* For roam command set timeout to 30 * 2 sec.
* There are cases where we try to connect to different
* APs with same SSID one by one until sucessfully conneted
* and thus roam command might take more time if connection
* is rejected by too many APs.
*/
if (eSmeCommandRemainOnChannel == pCommand->command)
pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE * 3;
else if ((eSmeCommandRoam == pCommand->command) &&
(eCsrHddIssued == pCommand->u.roamCmd.roamReason))
pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE * 2;
else
pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
// Insert the command onto the ActiveList...
csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_NOLOCK );
if( pMac->deferImps )
{
/* IMPS timer is already running so stop it and
* it will get restarted when no command is pending
*/
csrScanStopIdleScanTimer( pMac );
pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
pMac->deferImps = eANI_BOOLEAN_FALSE;
}
// .... 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);
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 eSmeCommandDelStaSession:
csrLLUnlock( &pMac->sme.smeCmdActiveList );
csrProcessDelStaSessionCommand( pMac, pCommand );
break;
case eSmeCommandMacSpoofRequest:
csrLLUnlock( &pMac->sme.smeCmdActiveList );
csrProcessMacAddrSpoofCommand( 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 );
}
break;
case eSmeCommandGetFrameLogRequest:
csrLLUnlock( &pMac->sme.smeCmdActiveList );
csrProcessGetFrameLogCommand( 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 );
}
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;
case eSmeCommandUpdateChannelList:
csrLLUnlock(&pMac->sme.smeCmdActiveList);
sme_process_update_channel_list(pMac, pCommand);
if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
&pCommand->Link, LL_ACCESS_LOCK)) {
csrReleaseCommand(pMac, pCommand);
}
smsLog(pMac, LOG1,
FL("eSmeCommandUpdateChannelList processed"));
fContinue = eANI_BOOLEAN_TRUE;
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);
case eSmeCommandEnterImps:
case eSmeCommandExitImps:
case eSmeCommandEnterBmps:
case eSmeCommandExitBmps:
case eSmeCommandEnterUapsd:
case eSmeCommandExitUapsd:
case eSmeCommandEnterWowl:
case eSmeCommandExitWowl:
csrLLUnlock( &pMac->sme.smeCmdActiveList );
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 );
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
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 eSmeCommandPnoReq:
csrLLUnlock( &pMac->sme.smeCmdActiveList );
status = smeProcessPnoCommand(pMac, pCommand);
if (!HAL_STATUS_SUCCESS(status)){
smsLog(pMac, LOGE,
FL("failed to post SME PNO SCAN %d"), status);
}
//We need to re-run the command
fContinue = eANI_BOOLEAN_TRUE;
if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
&pCommand->Link, LL_ACCESS_LOCK))
{
csrReleaseCommand(pMac, pCommand);
}
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:
case eSmeCommandTdlsChannelSwitch: // tdlsoffchan
smsLog(pMac, LOG1,
FL("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))
csrReleaseCommand(pMac, pCommand);
}
break ;
#endif
case eSmeCommandNanReq:
csrLLUnlock( &pMac->sme.smeCmdActiveList );
smeProcessNanReq( pMac, pCommand );
if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList,
&pCommand->Link, LL_ACCESS_LOCK))
{
csrReleaseCommand(pMac, pCommand);
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"eSmeCommandNanReq processed");
fContinue = eANI_BOOLEAN_TRUE;
break;
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 );
}
}
else
{
csrLLUnlock( &pMac->sme.smeCmdActiveList );
}
}
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.
if(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) );
}
//Global APIs
/*--------------------------------------------------------------------------
\brief sme_Open() - Initialze 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;
}
status = pmcOpen(hHal);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE,
"pmcOpen 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;
}
status = btcOpen(pMac);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE,
"btcOpen 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;
{
v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL);
if ( NULL == pvosGCtx ){
smsLog( pMac, LOGE, "WLANSAP_Open open failed during initialization");
status = eHAL_STATUS_FAILURE;
break;
}
status = WLANSAP_Open( pvosGCtx );
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE,
"WLANSAP_Open open failed during initialization with status=%d", status );
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
#if defined WLAN_FEATURE_VOWIFI_11R
sme_FTOpen(pMac);
#endif
sme_p2pOpen(pMac);
smeTraceInit(pMac);
sme_register_debug_callback();
}while (0);
return status;
}
/*--------------------------------------------------------------------------
\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;
}
#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
eHalStatus sme_UpdateChannelList(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
status = csrUpdateChannelList(pMac);
if (eHAL_STATUS_SUCCESS != status)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"failed to update the supported channel list");
}
return status;
}
/**
* sme_update_channel_list() - Update configured channel list to fwr
* This is a synchronous API.
*
* @mac_ctx - The handle returned by mac_open.
*
* Return QDF_STATUS SUCCESS.
* FAILURE or RESOURCES The API finished and failed.
*/
VOS_STATUS
sme_update_channel_list(tpAniSirGlobal pMac)
{
VOS_STATUS status = VOS_STATUS_SUCCESS;
status = sme_AcquireGlobalLock(&pMac->sme);
if (VOS_IS_STATUS_SUCCESS(status)) {
csrInitGetChannels(pMac);
csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
csrScanFilterResults(pMac);
sme_ReleaseGlobalLock(&pMac->sme);
}
return status;
}
/*--------------------------------------------------------------------------
\brief sme_UpdateConfig() - Change configurations for all SME moduels
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_P2P_INTERNAL
status = p2pChangeDefaultConfigParam(pMac, &pSmeConfigParams->p2pConfig);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "p2pChangeDefaultConfigParam failed with status=%d",
status );
}
#endif
#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 powersave 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;
pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog;
pMac->fDeferIMPSTime = pSmeConfigParams->fDeferIMPSTime;
pMac->fBtcEnableIndTimerVal = pSmeConfigParams->fBtcEnableIndTimerVal;
pMac->sta_auth_retries_for_code17 =
pSmeConfigParams->csrConfig.sta_auth_retries_for_code17;
return status;
}
#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_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. Currrently 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 tio 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 );
Msg.sme_msg_cb = sme_process_msg_callback;
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;
}
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;
}
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
if(VOS_STATUS_SUCCESS != btcReady(hHal))
{
status = eHAL_STATUS_FAILURE;
smsLog( pMac, LOGE, "btcReady failed");
break;
}
#endif
#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 FW
*
* @hal: Handler to HAL
*
* 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_BITMAP
*
* Return: None
*/
static void sme_set_allowed_action_frames(tHalHandle hal)
{
eHalStatus status;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
vos_msg_t vos_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->bitmask = ALLOWED_ACTION_FRAMES_BITMAP;
sir_allowed_action_frames->reserved = 0;
status = sme_AcquireGlobalLock(&mac->sme);
if (status == eHAL_STATUS_SUCCESS) {
/* serialize the req through MC thread */
vos_message.bodyptr = sir_allowed_action_frames;
vos_message.type = WDA_SET_ALLOWED_ACTION_FRAMES_IND;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_TX_WDA_MSG,
NO_SESSION, vos_message.type));
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,
"Not able to post WDA_SET_ALLOWED_ACTION_FRAMES_IND 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;
}
/*--------------------------------------------------------------------------
\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;
}
status = pmcStart(hHal);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "pmcStart failed during smeStart with status=%d",
status );
break;
}
status = WLANSAP_Start(vos_get_global_context(VOS_MODULE_ID_SAP, NULL));
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "WLANSAP_Start failed during smeStart with status=%d",
status );
break;
}
pMac->sme.state = SME_STATE_START;
}while (0);
sme_set_allowed_action_frames(hHal);
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 pRoamInfo = {0};
tANI_U32 SessionId = pSmeMgmtFrm->sessionId;
pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen;
pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
pRoamInfo.frameType = pSmeMgmtFrm->frameType;
/* forward the mgmt frame to HDD */
csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
return status;
}
#endif
#ifdef WLAN_FEATURE_AP_HT40_24G
/* ---------------------------------------------------------------------------
\fn sme_HT2040CoexInfoInd
\brief a Send 20/40 Coex info to SAP layer
\param tpSirHT2040CoexInfoInd - 20/40 Coex info param
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_HT2040CoexInfoInd( tHalHandle hHal,
tpSirHT2040CoexInfoInd pSmeHT2040CoexInfoInd)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
tANI_U32 SessionId = pSmeHT2040CoexInfoInd->sessionId;
tCsrRoamInfo roamInfo = {0};
roamInfo.pSmeHT2040CoexInfoInd = pSmeHT2040CoexInfoInd;
smsLog(pMac, LOGW, FL("HT40MHzIntolerant: %d HT20MHzBssWidthReq: %d"),
roamInfo.pSmeHT2040CoexInfoInd->HT40MHzIntolerant,
roamInfo.pSmeHT2040CoexInfoInd->HT20MHzBssWidthReq);
smsLog(pMac, LOGW, FL("Total Intolerant Channel: %d"),
roamInfo.pSmeHT2040CoexInfoInd->channel_num);
/* forward the 20/40 BSS Coex information to HDD */
smsLog(pMac, LOGW, FL("Sending eCSR_ROAM_2040_COEX_INFO_IND"
" to WLANSAP_RoamCallback "));
csrRoamCallCallback(pMac, SessionId, &roamInfo,
0, eCSR_ROAM_2040_COEX_INFO_IND, 0);
return status;
}
#endif
#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 pRoamInfo = {0};
tANI_U32 SessionId = pSmeTsmIeInd->sessionId;
pRoamInfo.tsmIe.tsid= pSmeTsmIeInd->tsmIe.tsid;
pRoamInfo.tsmIe.state= pSmeTsmIeInd->tsmIe.state;
pRoamInfo.tsmIe.msmt_interval= pSmeTsmIeInd->tsmIe.msmt_interval;
/* forward the tsm ie information to HDD */
csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_TSM_IE_IND, 0);
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 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;
/* 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;
}
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;
}
sme_RrmProcessBeaconReportReqInd(pMac, pSmeBcnReportReq);
vos_mem_free(pSmeBcnReportReq);
return status;
}
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
#ifdef WLAN_FEATURE_RMC
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;
}
#endif /* WLAN_FEATURE_RMC */
/* ---------------------------------------------------------------------------
\fn sme_getBcnMissRate
\brief function sends 'WDA_GET_BCN_MISS_RATE_REQ' to WDA layer,
\param hHal - HAL handle for device.
\param sessionId - session ID.
\- return Success or Failure.
-------------------------------------------------------------------------*/
eHalStatus sme_getBcnMissRate(tHalHandle hHal, tANI_U8 sessionId, void *callback, void *data)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
vos_msg_t vosMessage;
tSirBcnMissRateReq *pMsg;
tCsrRoamSession *pSession;
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
{
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;
}
pMsg = (tSirBcnMissRateReq *) vos_mem_malloc(sizeof(tSirBcnMissRateReq));
if (NULL == pMsg)
{
smsLog(pMac, LOGE, FL("failed to allocated memory"));
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
vos_mem_copy(pMsg->bssid, pSession->connectedProfile.bssid,
sizeof(tSirMacAddr));
pMsg->msgLen = sizeof(tSirBcnMissRateReq);
pMsg->callback = callback;
pMsg->data = data;
vosMessage.type = WDA_GET_BCN_MISS_RATE_REQ;
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 Set TM Level MSG fail", __func__);
vos_mem_free(pMsg);
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme);
return eHAL_STATUS_SUCCESS;
}
return eHAL_STATUS_FAILURE;
}
eHalStatus sme_EncryptMsgResponseHandler(tHalHandle hHal,
tpSirEncryptedDataRspParams pEncRspParams)
{
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.pEncMsgInfoParams.pEncMsgCbk == NULL)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: HDD callback is null", __func__);
return eHAL_STATUS_FAILURE;
}
pMac->sme.pEncMsgInfoParams.pEncMsgCbk(pMac->sme.pEncMsgInfoParams.pUserData,
&pEncRspParams->encryptedDataRsp);
return eHAL_STATUS_SUCCESS;
}
eHalStatus sme_UpdateMaxRateInd(tHalHandle hHal,
tSirSmeUpdateMaxRateParams *pSmeUpdateMaxRateParams)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
tANI_U8 sessionId = pSmeUpdateMaxRateParams->smeSessionId;
/* forward the information to HDD */
status = csrRoamCallCallback(pMac, sessionId, NULL, 0,
eCSR_ROAM_UPDATE_MAX_RATE_IND,
pSmeUpdateMaxRateParams->maxRateFlag);
return status;
}
/**
* sme_ecsa_msg_processor() - Handle ECSA indication and resp from LIM
* @mac_ctx: A pointer to Global MAC structure
* @msg_type: Indication/resp type
* @msg_buf: Indication/resp buffer
*
* Return VOS_STATUS
*/
static VOS_STATUS sme_ecsa_msg_processor(tpAniSirGlobal mac_ctx,
uint16_t msg_type, void *msg_buf)
{
tCsrRoamInfo roam_info = { 0 };
struct sir_ecsa_ie_complete_ind *ecsa_ie_cmp_ind;
struct sir_channel_chanege_rsp *chan_params;
uint32_t session_id = 0;
eRoamCmdStatus roamStatus;
eCsrRoamResult roamResult;
switch (msg_type) {
case eWNI_SME_ECSA_IE_BEACON_COMP_IND:
ecsa_ie_cmp_ind =
(struct sir_ecsa_ie_complete_ind *) msg_buf;
if (!ecsa_ie_cmp_ind) {
smsLog(mac_ctx, LOGE, FL("pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND"));
return VOS_STATUS_E_FAILURE;
}
session_id = ecsa_ie_cmp_ind->session_id;
roamStatus = eCSR_ROAM_ECSA_BCN_TX_IND;
roamResult = eCSR_ROAM_RESULT_NONE;
smsLog(mac_ctx, LOG1, FL("sapdfs: Received eWNI_SME_ECSA_IE_BEACON_COMP_IND for session id [%d]"),
session_id);
break;
case eWNI_SME_ECSA_CHAN_CHANGE_RSP:
chan_params = (struct sir_channel_chanege_rsp *)msg_buf;
roam_info.ap_chan_change_rsp =
vos_mem_malloc(sizeof(struct sir_channel_chanege_rsp));
if (!roam_info.ap_chan_change_rsp) {
smsLog(mac_ctx, LOGE, FL("failed to allocate ap_chan_change_rsp"));
return VOS_STATUS_E_FAILURE;
}
session_id = chan_params->sme_session_id;
roam_info.ap_chan_change_rsp->sme_session_id = session_id;
roam_info.ap_chan_change_rsp->new_channel = chan_params->new_channel;
if (chan_params->status == VOS_STATUS_SUCCESS) {
roam_info.ap_chan_change_rsp->status = VOS_STATUS_SUCCESS;
roamResult = eCSR_ROAM_RESULT_NONE;
} else {
roam_info.ap_chan_change_rsp->status = VOS_STATUS_E_FAILURE;
roamResult = eCSR_ROAM_RESULT_FAILURE;
}
roamStatus = eCSR_ROAM_ECSA_CHAN_CHANGE_RSP;
break;
default:
smsLog(mac_ctx, LOGE, FL("Invalid ECSA message: 0x%x"), msg_type);
return VOS_STATUS_E_FAILURE;
}
/* Indicate Radar Event to SAP */
csrRoamCallCallback(mac_ctx, session_id, &roam_info, 0,
roamStatus, roamResult);
if (roam_info.ap_chan_change_rsp)
vos_mem_free(roam_info.ap_chan_change_rsp);
return VOS_STATUS_SUCCESS;
}
static bool sme_get_sessionid_from_scan_cmd(tpAniSirGlobal mac,
tANI_U32 *session_id)
{
tListElem *entry = NULL;
tSmeCmd *command = NULL;
bool active_scan = false;
if (!mac->fScanOffload) {
entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
} else {
entry = csrLLPeekHead(&mac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK);
}
if (entry) {
command = GET_BASE_ADDR(entry, tSmeCmd, Link);
if (command->command == eSmeCommandScan) {
*session_id = command->sessionId;
active_scan = true;
}
}
return active_scan;
}
/*--------------------------------------------------------------------------
\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
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)
{
pmcMessageProcessor(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 WLAN_FEATURE_AP_HT40_24G
case eWNI_SME_2040_COEX_IND:
if(pMsg->bodyptr)
{
sme_HT2040CoexInfoInd(pMac, pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
}
else
{
smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_2040_COEX_IND), nothing to process");
}
break;
#endif
case eWNI_SME_ACTION_FRAME_SEND_CNF:
if(pMsg->bodyptr)
{
status = sme_sendActionCnf(pMac, pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
}
else
{
smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ACTION_FRAME_SEND_CNF), nothing to process");
}
break;
case eWNI_SME_COEX_IND:
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type));
if(pMsg->bodyptr)
{
tSirSmeCoexInd *pSmeCoexInd = (tSirSmeCoexInd *)pMsg->bodyptr;
vos_msg_t vosMessage = {0};
tANI_U32 session_id = 0;
bool active_scan;
if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4)
{
pMac->btc.agg_disabled = true;
smsLog( pMac, LOG1, FL("SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4"));
active_scan = sme_get_sessionid_from_scan_cmd(pMac,
&session_id);
if (active_scan)
sme_AbortMacScan(hHal, session_id,
eCSR_SCAN_ABORT_DEFAULT);
sme_RequestFullPower(hHal, NULL, NULL, eSME_REASON_OTHER);
pMac->isCoexScoIndSet = 1;
pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE;
pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE;
vosMessage.type = eWNI_SME_STA_DEL_BA_REQ;
vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
}
else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4)
{
pMac->btc.agg_disabled = false;
smsLog( pMac, LOG1, FL("SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4"));
pMac->isCoexScoIndSet = 0;
sme_RequestBmps(hHal, NULL, NULL);
pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE;
/*
* If aggregation during SCO is enabled, there is a
* possibility for an active BA session. This session
* should be deleted on receiving enable aggregation
* indication and block ack buffer size should be reset
* to default.
*/
if (pMac->roam.configParam.agg_btc_sco_enabled) {
vosMessage.type = eWNI_SME_STA_DEL_BA_REQ;
vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
}
}
status = btcHandleCoexInd((void *)pMac, pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
}
else
{
smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_COEX_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)